From 4bf8b0839465742918fe8de2f4607379fda56d89 Mon Sep 17 00:00:00 2001 From: David Rose Date: Mon, 21 Jul 2003 18:34:46 +0000 Subject: [PATCH] split out EggBase and EggSingleBase --- pandatool/src/egg-mkfont/eggMakeFont.cxx | 16 +- pandatool/src/egg-mkfont/eggMakeFont.h | 8 +- pandatool/src/egg-optchar/eggOptchar.cxx | 2 + pandatool/src/eggbase/Sources.pp | 8 +- pandatool/src/eggbase/eggBase.cxx | 323 ++++++++++++++++--- pandatool/src/eggbase/eggBase.h | 41 ++- pandatool/src/eggbase/eggMultiBase.cxx | 94 ++++-- pandatool/src/eggbase/eggMultiBase.h | 22 +- pandatool/src/eggbase/eggMultiFilter.cxx | 1 + pandatool/src/eggbase/eggReader.cxx | 4 +- pandatool/src/eggbase/eggReader.h | 4 +- pandatool/src/eggbase/eggSingleBase.cxx | 84 +++++ pandatool/src/eggbase/eggSingleBase.h | 59 ++++ pandatool/src/eggbase/eggWriter.cxx | 296 +---------------- pandatool/src/eggbase/eggWriter.h | 30 +- pandatool/src/eggbase/eggbase_composite1.cxx | 1 + 16 files changed, 549 insertions(+), 444 deletions(-) create mode 100644 pandatool/src/eggbase/eggSingleBase.cxx create mode 100644 pandatool/src/eggbase/eggSingleBase.h diff --git a/pandatool/src/egg-mkfont/eggMakeFont.cxx b/pandatool/src/egg-mkfont/eggMakeFont.cxx index b6aa841057..dcc6201a51 100644 --- a/pandatool/src/egg-mkfont/eggMakeFont.cxx +++ b/pandatool/src/egg-mkfont/eggMakeFont.cxx @@ -21,13 +21,13 @@ #include "charPlacement.h" #include "pkFontFile.h" -#include -#include -#include -#include -#include -#include -#include +#include "string_utils.h" +#include "eggGroup.h" +#include "eggTexture.h" +#include "eggVertexPool.h" +#include "eggPolygon.h" +#include "eggPoint.h" +#include "pointerTo.h" #include @@ -220,7 +220,7 @@ handle_args(ProgramBase::Args &args) { //////////////////////////////////////////////////////////////////// bool EggMakeFont:: dispatch_dimensions(ProgramBase *self, const string &opt, const string &arg, void *) { - EggBase *base = (EggBase *)self; + EggSingleBase *base = (EggSingleBase *)self; EggMakeFont *me = (EggMakeFont *)base->as_writer(); return me->ns_dispatch_dimensions(opt, arg); } diff --git a/pandatool/src/egg-mkfont/eggMakeFont.h b/pandatool/src/egg-mkfont/eggMakeFont.h index b78042c6ad..8cd147802c 100644 --- a/pandatool/src/egg-mkfont/eggMakeFont.h +++ b/pandatool/src/egg-mkfont/eggMakeFont.h @@ -19,13 +19,13 @@ #ifndef EGGMAKEFONT_H #define EGGMAKEFONT_H -#include +#include "pandatoolbase.h" #include "charLayout.h" -#include -#include -#include +#include "eggWriter.h" +#include "luse.h" +#include "pnmImage.h" class CharPlacement; class CharBitmap; diff --git a/pandatool/src/egg-optchar/eggOptchar.cxx b/pandatool/src/egg-optchar/eggOptchar.cxx index 751abbe5a3..898ae5c388 100644 --- a/pandatool/src/egg-optchar/eggOptchar.cxx +++ b/pandatool/src/egg-optchar/eggOptchar.cxx @@ -37,6 +37,8 @@ EggOptchar:: EggOptchar() { add_path_replace_options(); add_path_store_options(); + add_normals_options(); + add_transform_options(); set_program_description ("egg-optchar performs basic optimizations of a character model " diff --git a/pandatool/src/eggbase/Sources.pp b/pandatool/src/eggbase/Sources.pp index fcfec2b5d6..f6c782b2e1 100644 --- a/pandatool/src/eggbase/Sources.pp +++ b/pandatool/src/eggbase/Sources.pp @@ -9,18 +9,20 @@ #define SOURCES \ eggBase.h eggConverter.h eggFilter.h eggMultiBase.h \ - eggMultiFilter.h eggReader.h eggToSomething.h eggWriter.h \ + eggMultiFilter.h eggReader.h eggSingleBase.h \ + eggToSomething.h eggWriter.h \ somethingToEgg.h #define INCLUDED_SOURCES \ eggBase.cxx eggConverter.cxx eggFilter.cxx eggMultiBase.cxx \ - eggMultiFilter.cxx eggReader.cxx eggToSomething.cxx \ + eggMultiFilter.cxx eggReader.cxx eggSingleBase.cxx \ + eggToSomething.cxx \ eggWriter.cxx somethingToEgg.cxx #define INSTALL_HEADERS \ eggBase.h eggConverter.h eggFilter.h \ eggMultiBase.h eggMultiFilter.h \ - eggReader.h eggToSomething.h eggWriter.h somethingToEgg.h + eggReader.h eggSingleBase.h eggToSomething.h eggWriter.h somethingToEgg.h #end ss_lib_target diff --git a/pandatool/src/eggbase/eggBase.cxx b/pandatool/src/eggbase/eggBase.cxx index f5fe37b60f..5245af0bd0 100644 --- a/pandatool/src/eggbase/eggBase.cxx +++ b/pandatool/src/eggbase/eggBase.cxx @@ -23,6 +23,7 @@ #include "eggFilenameNode.h" #include "eggComment.h" #include "dcast.h" +#include "string_utils.h" //////////////////////////////////////////////////////////////////// // Function: EggBase::Constructor @@ -39,40 +40,86 @@ EggBase() { &_got_coordinate_system, &_coordinate_system); _coordinate_system = CS_yup_right; + + _normals_mode = NM_preserve; + _normals_threshold = 0.0; + + _got_transform = false; + _transform = LMatrix4d::ident_mat(); } //////////////////////////////////////////////////////////////////// -// Function: EggBase::as_reader -// Access: Public, Virtual -// Description: Returns this object as an EggReader pointer, if it is -// in fact an EggReader, or NULL if it is not. -// -// This is intended to work around the C++ limitation -// that prevents downcasts past virtual inheritance. -// Since both EggReader and EggWriter inherit virtually -// from EggBase, we need functions like this to downcast -// to the appropriate pointer. +// Function: EggBase::add_normals_options +// Access: Public +// Description: Adds -no, -np, etc. as valid options for this +// program. If the user specifies one of the options on +// the command line, the normals will be adjusted when +// the egg file is written out. //////////////////////////////////////////////////////////////////// -EggReader *EggBase:: -as_reader() { - return (EggReader *)NULL; +void EggBase:: +add_normals_options() { + static NormalsMode strip = NM_strip; + static NormalsMode polygon = NM_polygon; + static NormalsMode vertex = NM_vertex; + static NormalsMode preserve = NM_preserve; + + add_option + ("no", "", 48, + "Strip all normals.", + &EggBase::dispatch_normals, NULL, &strip); + + add_option + ("np", "", 48, + "Strip existing normals and redefine polygon normals.", + &EggBase::dispatch_normals, NULL, &polygon); + + add_option + ("nv", "threshold", 48, + "Strip existing normals and redefine vertex normals. Consider an edge " + "between adjacent polygons to be smooth if the angle between them " + "is less than threshold degrees.", + &EggBase::dispatch_normals, NULL, &vertex); + + add_option + ("nn", "", 48, + "Preserve normals exactly as they are. This is the default.", + &EggBase::dispatch_normals, NULL, &preserve); } //////////////////////////////////////////////////////////////////// -// Function: EggBase::as_writer -// Access: Public, Virtual -// Description: Returns this object as an EggWriter pointer, if it is -// in fact an EggWriter, or NULL if it is not. -// -// This is intended to work around the C++ limitation -// that prevents downcasts past virtual inheritance. -// Since both EggReader and EggWriter inherit virtually -// from EggBase, we need functions like this to downcast -// to the appropriate pointer. +// Function: EggBase::add_transform_options +// Access: Public +// Description: Adds -TS, -TT, etc. as valid options for this +// program. If the user specifies one of the options on +// the command line, the data will be transformed when +// the egg file is written out. //////////////////////////////////////////////////////////////////// -EggWriter *EggBase:: -as_writer() { - return (EggWriter *)NULL; +void EggBase:: +add_transform_options() { + add_option + ("TS", "sx[,sy,sz]", 49, + "Scale the model uniformly by the given factor (if only one number " + "is given) or in each axis by sx, sy, sz (if three numbers are given).", + &EggBase::dispatch_scale, &_got_transform, &_transform); + + add_option + ("TR", "x,y,z", 49, + "Rotate the model x degrees about the x axis, then y degrees about the " + "y axis, and then z degrees about the z axis.", + &EggBase::dispatch_rotate_xyz, &_got_transform, &_transform); + + add_option + ("TA", "angle,x,y,z", 49, + "Rotate the model angle degrees counterclockwise about the given " + "axis.", + &EggBase::dispatch_rotate_axis, &_got_transform, &_transform); + + add_option + ("TT", "x,y,z", 49, + "Translate the model by the indicated amount.\n\n" + "All transformation options (-TS, -TR, -TA, -TT) are cumulative and are " + "applied in the order they are encountered on the command line.", + &EggBase::dispatch_translate, &_got_transform, &_transform); } //////////////////////////////////////////////////////////////////// @@ -116,21 +163,6 @@ convert_paths(EggNode *node, PathReplace *path_replace, } } -//////////////////////////////////////////////////////////////////// -// Function: EggBase::post_command_line -// Access: Protected, Virtual -// Description: -//////////////////////////////////////////////////////////////////// -bool EggBase:: -post_command_line() { - if (_got_coordinate_system) { - _data.set_coordinate_system(_coordinate_system); - } - - return ProgramBase::post_command_line(); -} - - //////////////////////////////////////////////////////////////////// // Function: EggBase::append_command_comment // Access: Protected @@ -162,3 +194,212 @@ void EggBase:: append_command_comment(EggData &data, const string &comment) { data.insert(data.begin(), new EggComment("", comment)); } + +//////////////////////////////////////////////////////////////////// +// Function: EggBase::dispatch_normals +// Access: Protected, Static +// Description: Accepts one of -no, -np, etc. and sets _normals_mode +// as indicated. The void * argument is a pointer to a +// NormalsMode variable that indicates which switch was +// passed. +//////////////////////////////////////////////////////////////////// +bool EggBase:: +dispatch_normals(ProgramBase *self, const string &opt, const string &arg, void *mode) { + EggBase *base = (EggBase *)self; + return base->ns_dispatch_normals(opt, arg, mode); +} + +//////////////////////////////////////////////////////////////////// +// Function: EggBase::ns_dispatch_normals +// Access: Protected +// Description: Accepts one of -no, -np, etc. and sets _normals_mode +// as indicated. The void * argument is a pointer to a +// NormalsMode variable that indicates which switch was +// passed. +//////////////////////////////////////////////////////////////////// +bool EggBase:: +ns_dispatch_normals(const string &opt, const string &arg, void *mode) { + _normals_mode = *(NormalsMode *)mode; + + if (_normals_mode == NM_vertex) { + if (!string_to_double(arg, _normals_threshold)) { + nout << "Invalid numeric parameter for -" << opt << ": " + << arg << "\n"; + return false; + } + } + + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggBase::dispatch_scale +// Access: Protected, Static +// Description: Handles -TS, which specifies a scale transform. Var +// is an LMatrix4d. +//////////////////////////////////////////////////////////////////// +bool EggBase:: +dispatch_scale(const string &opt, const string &arg, void *var) { + LMatrix4d *transform = (LMatrix4d *)var; + + vector_string words; + tokenize(arg, words, ","); + + double sx, sy, sz; + + bool okflag = false; + if (words.size() == 3) { + okflag = + string_to_double(words[0], sx) && + string_to_double(words[1], sy) && + string_to_double(words[2], sz); + + } else if (words.size() == 1) { + okflag = + string_to_double(words[0], sx); + sy = sz = sx; + } + + if (!okflag) { + nout << "-" << opt + << " requires one or three numbers separated by commas.\n"; + return false; + } + + *transform = (*transform) * LMatrix4d::scale_mat(sx, sy, sz); + + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggBase::dispatch_rotate_xyz +// Access: Protected, Static +// Description: Handles -TR, which specifies a rotate transform about +// the three cardinal axes. Var is an LMatrix4d. +//////////////////////////////////////////////////////////////////// +bool EggBase:: +dispatch_rotate_xyz(ProgramBase *self, const string &opt, const string &arg, void *var) { + EggBase *base = (EggBase *)self; + return base->ns_dispatch_rotate_xyz(opt, arg, var); +} + +//////////////////////////////////////////////////////////////////// +// Function: EggBase::ns_dispatch_rotate_xyz +// Access: Protected +// Description: Handles -TR, which specifies a rotate transform about +// the three cardinal axes. Var is an LMatrix4d. +//////////////////////////////////////////////////////////////////// +bool EggBase:: +ns_dispatch_rotate_xyz(const string &opt, const string &arg, void *var) { + LMatrix4d *transform = (LMatrix4d *)var; + + vector_string words; + tokenize(arg, words, ","); + + LVecBase3d xyz; + + bool okflag = false; + if (words.size() == 3) { + okflag = + string_to_double(words[0], xyz[0]) && + string_to_double(words[1], xyz[1]) && + string_to_double(words[2], xyz[2]); + } + + if (!okflag) { + nout << "-" << opt + << " requires three numbers separated by commas.\n"; + return false; + } + + LMatrix4d mat = + LMatrix4d::rotate_mat(xyz[0], LVector3d(1.0, 0.0, 0.0), _coordinate_system) * + LMatrix4d::rotate_mat(xyz[1], LVector3d(0.0, 1.0, 0.0), _coordinate_system) * + LMatrix4d::rotate_mat(xyz[2], LVector3d(0.0, 0.0, 1.0), _coordinate_system); + + *transform = (*transform) * mat; + + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggBase::dispatch_rotate_axis +// Access: Protected, Static +// Description: Handles -TA, which specifies a rotate transform about +// an arbitrary axis. Var is an LMatrix4d. +//////////////////////////////////////////////////////////////////// +bool EggBase:: +dispatch_rotate_axis(ProgramBase *self, const string &opt, const string &arg, void *var) { + EggBase *base = (EggBase *)self; + return base->ns_dispatch_rotate_axis(opt, arg, var); +} + +//////////////////////////////////////////////////////////////////// +// Function: EggBase::ns_dispatch_rotate_axis +// Access: Protected +// Description: Handles -TA, which specifies a rotate transform about +// an arbitrary axis. Var is an LMatrix4d. +//////////////////////////////////////////////////////////////////// +bool EggBase:: +ns_dispatch_rotate_axis(const string &opt, const string &arg, void *var) { + LMatrix4d *transform = (LMatrix4d *)var; + + vector_string words; + tokenize(arg, words, ","); + + double angle; + LVecBase3d axis; + + bool okflag = false; + if (words.size() == 4) { + okflag = + string_to_double(words[0], angle) && + string_to_double(words[1], axis[0]) && + string_to_double(words[2], axis[1]) && + string_to_double(words[3], axis[2]); + } + + if (!okflag) { + nout << "-" << opt + << " requires four numbers separated by commas.\n"; + return false; + } + + *transform = (*transform) * LMatrix4d::rotate_mat(angle, axis, _coordinate_system); + + return true; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggBase::dispatch_translate +// Access: Protected, Static +// Description: Handles -TT, which specifies a translate transform. +// Var is an LMatrix4d. +//////////////////////////////////////////////////////////////////// +bool EggBase:: +dispatch_translate(const string &opt, const string &arg, void *var) { + LMatrix4d *transform = (LMatrix4d *)var; + + vector_string words; + tokenize(arg, words, ","); + + LVector3d trans; + + bool okflag = false; + if (words.size() == 3) { + okflag = + string_to_double(words[0], trans[0]) && + string_to_double(words[1], trans[1]) && + string_to_double(words[2], trans[2]); + } + + if (!okflag) { + nout << "-" << opt + << " requires three numbers separated by commas.\n"; + return false; + } + + *transform = (*transform) * LMatrix4d::translate_mat(trans); + + return true; +} diff --git a/pandatool/src/eggbase/eggBase.h b/pandatool/src/eggbase/eggBase.h index a57c4adb6b..a582711ca0 100644 --- a/pandatool/src/eggbase/eggBase.h +++ b/pandatool/src/eggbase/eggBase.h @@ -22,20 +22,13 @@ #include "pandatoolbase.h" #include "programBase.h" -#include "coordinateSystem.h" #include "eggData.h" -class EggReader; -class EggWriter; -class EggNode; -class PathReplace; - //////////////////////////////////////////////////////////////////// // Class : EggBase -// Description : This specialization of ProgramBase is intended for -// programs that read and/or write a single egg file. -// (See EggMultiBase for programs that operate on -// multiple egg files at once.) +// Description : This is a base class for both EggSingleBase and +// EggMultiBase. Don't inherit directly from this; use +// one of those two classes instead. // // This is just a base class; see EggReader, EggWriter, // or EggFilter according to your particular I/O needs. @@ -44,21 +37,41 @@ class EggBase : public ProgramBase { public: EggBase(); - virtual EggReader *as_reader(); - virtual EggWriter *as_writer(); + void add_normals_options(); + void add_transform_options(); static void convert_paths(EggNode *node, PathReplace *path_replace, const DSearchPath &additional_path); protected: - virtual bool post_command_line(); void append_command_comment(EggData &_data); static void append_command_comment(EggData &_data, const string &comment); + static bool dispatch_normals(ProgramBase *self, const string &opt, const string &arg, void *mode); + bool ns_dispatch_normals(const string &opt, const string &arg, void *mode); + + static bool dispatch_scale(const string &opt, const string &arg, void *var); + static bool dispatch_rotate_xyz(ProgramBase *self, const string &opt, const string &arg, void *var); + bool ns_dispatch_rotate_xyz(const string &opt, const string &arg, void *var); + static bool dispatch_rotate_axis(ProgramBase *self, const string &opt, const string &arg, void *var); + bool ns_dispatch_rotate_axis(const string &opt, const string &arg, void *var); + static bool dispatch_translate(const string &opt, const string &arg, void *var); + protected: + enum NormalsMode { + NM_strip, + NM_polygon, + NM_vertex, + NM_preserve + }; + NormalsMode _normals_mode; + double _normals_threshold; + + bool _got_transform; + LMatrix4d _transform; + bool _got_coordinate_system; CoordinateSystem _coordinate_system; - EggData _data; }; #endif diff --git a/pandatool/src/eggbase/eggMultiBase.cxx b/pandatool/src/eggbase/eggMultiBase.cxx index 48d3d737e4..22a08aca6e 100644 --- a/pandatool/src/eggbase/eggMultiBase.cxx +++ b/pandatool/src/eggbase/eggMultiBase.cxx @@ -30,54 +30,78 @@ //////////////////////////////////////////////////////////////////// EggMultiBase:: EggMultiBase() { - add_option - ("cs", "coordinate-system", 80, - "Specify the coordinate system to operate in. This may be one of " - "'y-up', 'z-up', 'y-up-left', or 'z-up-left'.", - &EggMultiBase::dispatch_coordinate_system, - &_got_coordinate_system, &_coordinate_system); - add_option ("f", "", 80, "Force complete loading: load up the egg file along with all of its " "external references.", &EggMultiBase::dispatch_none, &_force_complete); - - _coordinate_system = CS_yup_right; } - //////////////////////////////////////////////////////////////////// -// Function: EggMultiBase::append_command_comment -// Access: Protected -// Description: Inserts a comment into the beginning of the indicated -// egg file corresponding to the command line that -// invoked this program. +// Function: EggMultiBase::post_process_egg_files +// Access: Public +// Description: Performs any processing of the egg file(s) that is +// appropriate before writing them out. This includes any +// normal adjustments the user requested via -np, etc. // -// Normally this function is called automatically when -// appropriate by EggWriter, and it's not necessary to -// call it explicitly. +// Normally, you should not need to call this function +// directly; write_egg_files() calls it for you. You +// should call this only if you do not use +// write_egg_files() to write out the resulting egg +// files. //////////////////////////////////////////////////////////////////// void EggMultiBase:: -append_command_comment(EggData &data) { - append_command_comment(data, get_exec_command()); +post_process_egg_files() { + if (_eggs.empty()) { + return; + } + + Eggs::iterator ei; + if (_got_transform) { + nout << "Applying transform matrix:\n"; + _transform.write(nout, 2); + LVecBase3d scale, hpr, translate; + if (decompose_matrix(_transform, scale, hpr, translate, + _eggs[0]->get_coordinate_system())) { + nout << "(scale " << scale << ", hpr " << hpr << ", translate " + << translate << ")\n"; + } + for (ei = _eggs.begin(); ei != _eggs.end(); ++ei) { + (*ei)->transform(_transform); + } + } + + switch (_normals_mode) { + case NM_strip: + nout << "Stripping normals.\n"; + for (ei = _eggs.begin(); ei != _eggs.end(); ++ei) { + (*ei)->strip_normals(); + (*ei)->remove_unused_vertices(); + } + break; + + case NM_polygon: + nout << "Recomputing polygon normals.\n"; + for (ei = _eggs.begin(); ei != _eggs.end(); ++ei) { + (*ei)->recompute_polygon_normals(); + (*ei)->remove_unused_vertices(); + } + break; + + case NM_vertex: + nout << "Recomputing vertex normals.\n"; + for (ei = _eggs.begin(); ei != _eggs.end(); ++ei) { + (*ei)->recompute_vertex_normals(_normals_threshold); + (*ei)->remove_unused_vertices(); + } + break; + + case NM_preserve: + // Do nothing. + break; + } } -//////////////////////////////////////////////////////////////////// -// Function: EggMultiBase::append_command_comment -// Access: Protected, Static -// Description: Inserts a comment into the beginning of the indicated -// egg file corresponding to the command line that -// invoked this program. -// -// Normally this function is called automatically when -// appropriate by EggWriter, and it's not necessary to -// call it explicitly. -//////////////////////////////////////////////////////////////////// -void EggMultiBase:: -append_command_comment(EggData &data, const string &comment) { - data.insert(data.begin(), new EggComment("", comment)); -} //////////////////////////////////////////////////////////////////// // Function: EggMultiBase::read_egg diff --git a/pandatool/src/eggbase/eggMultiBase.h b/pandatool/src/eggbase/eggMultiBase.h index 6290e15607..b7706ab4a9 100644 --- a/pandatool/src/eggbase/eggMultiBase.h +++ b/pandatool/src/eggbase/eggMultiBase.h @@ -19,12 +19,12 @@ #ifndef EGGMULTIBASE_H #define EGGMULTIBASE_H -#include +#include "pandatoolbase.h" -#include -#include -#include -#include +#include "eggBase.h" +#include "coordinateSystem.h" +#include "eggData.h" +#include "pointerTo.h" class Filename; @@ -37,21 +37,17 @@ class Filename; // how to read a bunch of egg files in and write them // out again. //////////////////////////////////////////////////////////////////// -class EggMultiBase : public ProgramBase { +class EggMultiBase : public EggBase { public: EggMultiBase(); -protected: - void append_command_comment(EggData &_data); - static void append_command_comment(EggData &_data, const string &comment); + void post_process_egg_files(); +protected: virtual PT(EggData) read_egg(const Filename &filename); protected: - bool _got_coordinate_system; - CoordinateSystem _coordinate_system; - - typedef pvector Eggs; + typedef pvector< PT(EggData) > Eggs; Eggs _eggs; bool _force_complete; diff --git a/pandatool/src/eggbase/eggMultiFilter.cxx b/pandatool/src/eggbase/eggMultiFilter.cxx index 7048117634..28698250c0 100644 --- a/pandatool/src/eggbase/eggMultiFilter.cxx +++ b/pandatool/src/eggbase/eggMultiFilter.cxx @@ -189,6 +189,7 @@ get_output_filename(const Filename &source_filename) const { void EggMultiFilter:: write_eggs() { nassertv(!_read_only); + post_process_egg_files(); Eggs::iterator ei; for (ei = _eggs.begin(); ei != _eggs.end(); ++ei) { EggData *data = (*ei); diff --git a/pandatool/src/eggbase/eggReader.cxx b/pandatool/src/eggbase/eggReader.cxx index e62b6f5b17..178bac035e 100644 --- a/pandatool/src/eggbase/eggReader.cxx +++ b/pandatool/src/eggbase/eggReader.cxx @@ -136,7 +136,7 @@ add_delod_options(double default_delod) { // This is intended to work around the C++ limitation // that prevents downcasts past virtual inheritance. // Since both EggReader and EggWriter inherit virtually -// from EggBase, we need functions like this to downcast +// from EggSingleBase, we need functions like this to downcast // to the appropriate pointer. //////////////////////////////////////////////////////////////////// EggReader *EggReader:: @@ -211,7 +211,7 @@ handle_args(ProgramBase::Args &args) { //////////////////////////////////////////////////////////////////// bool EggReader:: post_command_line() { - return EggBase::post_command_line(); + return EggSingleBase::post_command_line(); } //////////////////////////////////////////////////////////////////// diff --git a/pandatool/src/eggbase/eggReader.h b/pandatool/src/eggbase/eggReader.h index 5267334332..d31d81a472 100644 --- a/pandatool/src/eggbase/eggReader.h +++ b/pandatool/src/eggbase/eggReader.h @@ -21,7 +21,7 @@ #include "pandatoolbase.h" -#include "eggBase.h" +#include "eggSingleBase.h" #include "filename.h" class PNMFileType; @@ -31,7 +31,7 @@ class PNMFileType; // Description : This is the base class for a program that reads egg // files, but doesn't write an egg file. //////////////////////////////////////////////////////////////////// -class EggReader : virtual public EggBase { +class EggReader : virtual public EggSingleBase { public: EggReader(); diff --git a/pandatool/src/eggbase/eggSingleBase.cxx b/pandatool/src/eggbase/eggSingleBase.cxx new file mode 100644 index 0000000000..3e95908a81 --- /dev/null +++ b/pandatool/src/eggbase/eggSingleBase.cxx @@ -0,0 +1,84 @@ +// Filename: eggSingleBase.cxx +// Created by: drose (21Jul03) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://www.panda3d.org/license.txt . +// +// To contact the maintainers of this program write to +// panda3d@yahoogroups.com . +// +//////////////////////////////////////////////////////////////////// + +#include "eggSingleBase.h" + +#include "eggGroupNode.h" +#include "eggTexture.h" +#include "eggFilenameNode.h" +#include "eggComment.h" +#include "dcast.h" +#include "string_utils.h" + +//////////////////////////////////////////////////////////////////// +// Function: EggSingleBase::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +EggSingleBase:: +EggSingleBase() { +} + +//////////////////////////////////////////////////////////////////// +// Function: EggSingleBase::as_reader +// Access: Public, Virtual +// Description: Returns this object as an EggReader pointer, if it is +// in fact an EggReader, or NULL if it is not. +// +// This is intended to work around the C++ limitation +// that prevents downcasts past virtual inheritance. +// Since both EggReader and EggWriter inherit virtually +// from EggSingleBase, we need functions like this to downcast +// to the appropriate pointer. +//////////////////////////////////////////////////////////////////// +EggReader *EggSingleBase:: +as_reader() { + return (EggReader *)NULL; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggSingleBase::as_writer +// Access: Public, Virtual +// Description: Returns this object as an EggWriter pointer, if it is +// in fact an EggWriter, or NULL if it is not. +// +// This is intended to work around the C++ limitation +// that prevents downcasts past virtual inheritance. +// Since both EggReader and EggWriter inherit virtually +// from EggSingleBase, we need functions like this to downcast +// to the appropriate pointer. +//////////////////////////////////////////////////////////////////// +EggWriter *EggSingleBase:: +as_writer() { + return (EggWriter *)NULL; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggSingleBase::post_command_line +// Access: Protected, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +bool EggSingleBase:: +post_command_line() { + if (_got_coordinate_system) { + _data.set_coordinate_system(_coordinate_system); + } + + return EggBase::post_command_line(); +} + diff --git a/pandatool/src/eggbase/eggSingleBase.h b/pandatool/src/eggbase/eggSingleBase.h new file mode 100644 index 0000000000..a2a430c1c7 --- /dev/null +++ b/pandatool/src/eggbase/eggSingleBase.h @@ -0,0 +1,59 @@ +// Filename: eggSingleBase.h +// Created by: drose (21Jul03) +// +//////////////////////////////////////////////////////////////////// +// +// PANDA 3D SOFTWARE +// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved +// +// All use of this software is subject to the terms of the Panda 3d +// Software license. You should have received a copy of this license +// along with this source code; you will also find a current copy of +// the license at http://www.panda3d.org/license.txt . +// +// To contact the maintainers of this program write to +// panda3d@yahoogroups.com . +// +//////////////////////////////////////////////////////////////////// + +#ifndef EGGSINGLEBASE_H +#define EGGSINGLEBASE_H + +#include "pandatoolbase.h" + +#include "eggBase.h" +#include "coordinateSystem.h" +#include "eggData.h" + +class EggReader; +class EggWriter; +class EggNode; +class PathReplace; + +//////////////////////////////////////////////////////////////////// +// Class : EggSingleBase +// Description : This specialization of EggBase is intended for +// programs that read and/or write a single egg file. +// (See EggMultiBase for programs that operate on +// multiple egg files at once.) +// +// This is just a base class; see EggReader, EggWriter, +// or EggFilter according to your particular I/O needs. +//////////////////////////////////////////////////////////////////// +class EggSingleBase : public EggBase { +public: + EggSingleBase(); + + virtual EggReader *as_reader(); + virtual EggWriter *as_writer(); + +protected: + virtual bool post_command_line(); + +protected: + EggData _data; +}; + +#endif + + diff --git a/pandatool/src/eggbase/eggWriter.cxx b/pandatool/src/eggbase/eggWriter.cxx index 44e757ef48..20a28ab320 100644 --- a/pandatool/src/eggbase/eggWriter.cxx +++ b/pandatool/src/eggbase/eggWriter.cxx @@ -92,89 +92,9 @@ EggWriter(bool allow_last_param, bool allow_stdout) : "Specify the coordinate system of the resulting egg file. This may be " "one of 'y-up', 'z-up', 'y-up-left', or 'z-up-left'. The default is " "y-up."); - - _normals_mode = NM_preserve; - _normals_threshold = 0.0; - - _got_transform = false; - _transform = LMatrix4d::ident_mat(); } -//////////////////////////////////////////////////////////////////// -// Function: EggWriter::add_normals_options -// Access: Public -// Description: Adds -no, -np, etc. as valid options for this -// program. If the user specifies one of the options on -// the command line, the normals will be adjusted when -// the egg file is written out. -//////////////////////////////////////////////////////////////////// -void EggWriter:: -add_normals_options() { - static NormalsMode strip = NM_strip; - static NormalsMode polygon = NM_polygon; - static NormalsMode vertex = NM_vertex; - static NormalsMode preserve = NM_preserve; - - add_option - ("no", "", 48, - "Strip all normals.", - &EggWriter::dispatch_normals, NULL, &strip); - - add_option - ("np", "", 48, - "Strip existing normals and redefine polygon normals.", - &EggWriter::dispatch_normals, NULL, &polygon); - - add_option - ("nv", "threshold", 48, - "Strip existing normals and redefine vertex normals. Consider an edge " - "between adjacent polygons to be smooth if the angle between them " - "is less than threshold degrees.", - &EggWriter::dispatch_normals, NULL, &vertex); - - add_option - ("nn", "", 48, - "Preserve normals exactly as they are. This is the default.", - &EggWriter::dispatch_normals, NULL, &preserve); -} - -//////////////////////////////////////////////////////////////////// -// Function: EggWriter::add_transform_options -// Access: Public -// Description: Adds -TS, -TT, etc. as valid options for this -// program. If the user specifies one of the options on -// the command line, the data will be transformed when -// the egg file is written out. -//////////////////////////////////////////////////////////////////// -void EggWriter:: -add_transform_options() { - add_option - ("TS", "sx[,sy,sz]", 49, - "Scale the model uniformly by the given factor (if only one number " - "is given) or in each axis by sx, sy, sz (if three numbers are given).", - &EggWriter::dispatch_scale, &_got_transform, &_transform); - - add_option - ("TR", "x,y,z", 49, - "Rotate the model x degrees about the x axis, then y degrees about the " - "y axis, and then z degrees about the z axis.", - &EggWriter::dispatch_rotate_xyz, &_got_transform, &_transform); - - add_option - ("TA", "angle,x,y,z", 49, - "Rotate the model angle degrees counterclockwise about the given " - "axis.", - &EggWriter::dispatch_rotate_axis, &_got_transform, &_transform); - - add_option - ("TT", "x,y,z", 49, - "Translate the model by the indicated amount.\n\n" - "All transformation options (-TS, -TR, -TA, -TT) are cumulative and are " - "applied in the order they are encountered on the command line.", - &EggWriter::dispatch_translate, &_got_transform, &_transform); -} - //////////////////////////////////////////////////////////////////// // Function: EggWriter::as_writer // Access: Public, Virtual @@ -184,7 +104,7 @@ add_transform_options() { // This is intended to work around the C++ limitation // that prevents downcasts past virtual inheritance. // Since both EggReader and EggWriter inherit virtually -// from EggBase, we need functions like this to downcast +// from EggSingleBase, we need functions like this to downcast // to the appropriate pointer. //////////////////////////////////////////////////////////////////// EggWriter *EggWriter:: @@ -304,217 +224,5 @@ post_command_line() { append_command_comment(_data); - return EggBase::post_command_line(); -} - -//////////////////////////////////////////////////////////////////// -// Function: EggWriter::dispatch_normals -// Access: Protected, Static -// Description: Accepts one of -no, -np, etc. and sets _normals_mode -// as indicated. The void * argument is a pointer to a -// NormalsMode variable that indicates which switch was -// passed. -//////////////////////////////////////////////////////////////////// -bool EggWriter:: -dispatch_normals(ProgramBase *self, const string &opt, const string &arg, void *mode) { - EggBase *base = (EggBase *)self; - EggWriter *me = base->as_writer(); - return me->ns_dispatch_normals(opt, arg, mode); -} - -//////////////////////////////////////////////////////////////////// -// Function: EggWriter::ns_dispatch_normals -// Access: Protected -// Description: Accepts one of -no, -np, etc. and sets _normals_mode -// as indicated. The void * argument is a pointer to a -// NormalsMode variable that indicates which switch was -// passed. -//////////////////////////////////////////////////////////////////// -bool EggWriter:: -ns_dispatch_normals(const string &opt, const string &arg, void *mode) { - _normals_mode = *(NormalsMode *)mode; - - if (_normals_mode == NM_vertex) { - if (!string_to_double(arg, _normals_threshold)) { - nout << "Invalid numeric parameter for -" << opt << ": " - << arg << "\n"; - return false; - } - } - - return true; -} - -//////////////////////////////////////////////////////////////////// -// Function: EggWriter::dispatch_scale -// Access: Protected, Static -// Description: Handles -TS, which specifies a scale transform. Var -// is an LMatrix4d. -//////////////////////////////////////////////////////////////////// -bool EggWriter:: -dispatch_scale(const string &opt, const string &arg, void *var) { - LMatrix4d *transform = (LMatrix4d *)var; - - vector_string words; - tokenize(arg, words, ","); - - double sx, sy, sz; - - bool okflag = false; - if (words.size() == 3) { - okflag = - string_to_double(words[0], sx) && - string_to_double(words[1], sy) && - string_to_double(words[2], sz); - - } else if (words.size() == 1) { - okflag = - string_to_double(words[0], sx); - sy = sz = sx; - } - - if (!okflag) { - nout << "-" << opt - << " requires one or three numbers separated by commas.\n"; - return false; - } - - *transform = (*transform) * LMatrix4d::scale_mat(sx, sy, sz); - - return true; -} - -//////////////////////////////////////////////////////////////////// -// Function: EggWriter::dispatch_rotate_xyz -// Access: Protected, Static -// Description: Handles -TR, which specifies a rotate transform about -// the three cardinal axes. Var is an LMatrix4d. -//////////////////////////////////////////////////////////////////// -bool EggWriter:: -dispatch_rotate_xyz(ProgramBase *self, const string &opt, const string &arg, void *var) { - EggBase *base = (EggBase *)self; - EggWriter *me = base->as_writer(); - return me->ns_dispatch_rotate_xyz(opt, arg, var); -} - -//////////////////////////////////////////////////////////////////// -// Function: EggWriter::ns_dispatch_rotate_xyz -// Access: Protected -// Description: Handles -TR, which specifies a rotate transform about -// the three cardinal axes. Var is an LMatrix4d. -//////////////////////////////////////////////////////////////////// -bool EggWriter:: -ns_dispatch_rotate_xyz(const string &opt, const string &arg, void *var) { - LMatrix4d *transform = (LMatrix4d *)var; - - vector_string words; - tokenize(arg, words, ","); - - LVecBase3d xyz; - - bool okflag = false; - if (words.size() == 3) { - okflag = - string_to_double(words[0], xyz[0]) && - string_to_double(words[1], xyz[1]) && - string_to_double(words[2], xyz[2]); - } - - if (!okflag) { - nout << "-" << opt - << " requires three numbers separated by commas.\n"; - return false; - } - - LMatrix4d mat = - LMatrix4d::rotate_mat(xyz[0], LVector3d(1.0, 0.0, 0.0), _coordinate_system) * - LMatrix4d::rotate_mat(xyz[1], LVector3d(0.0, 1.0, 0.0), _coordinate_system) * - LMatrix4d::rotate_mat(xyz[2], LVector3d(0.0, 0.0, 1.0), _coordinate_system); - - *transform = (*transform) * mat; - - return true; -} - -//////////////////////////////////////////////////////////////////// -// Function: EggWriter::dispatch_rotate_axis -// Access: Protected, Static -// Description: Handles -TA, which specifies a rotate transform about -// an arbitrary axis. Var is an LMatrix4d. -//////////////////////////////////////////////////////////////////// -bool EggWriter:: -dispatch_rotate_axis(ProgramBase *self, const string &opt, const string &arg, void *var) { - EggBase *base = (EggBase *)self; - EggWriter *me = base->as_writer(); - return me->ns_dispatch_rotate_axis(opt, arg, var); -} - -//////////////////////////////////////////////////////////////////// -// Function: EggWriter::ns_dispatch_rotate_axis -// Access: Protected -// Description: Handles -TA, which specifies a rotate transform about -// an arbitrary axis. Var is an LMatrix4d. -//////////////////////////////////////////////////////////////////// -bool EggWriter:: -ns_dispatch_rotate_axis(const string &opt, const string &arg, void *var) { - LMatrix4d *transform = (LMatrix4d *)var; - - vector_string words; - tokenize(arg, words, ","); - - double angle; - LVecBase3d axis; - - bool okflag = false; - if (words.size() == 4) { - okflag = - string_to_double(words[0], angle) && - string_to_double(words[1], axis[0]) && - string_to_double(words[2], axis[1]) && - string_to_double(words[3], axis[2]); - } - - if (!okflag) { - nout << "-" << opt - << " requires four numbers separated by commas.\n"; - return false; - } - - *transform = (*transform) * LMatrix4d::rotate_mat(angle, axis, _coordinate_system); - - return true; -} - -//////////////////////////////////////////////////////////////////// -// Function: EggWriter::dispatch_translate -// Access: Protected, Static -// Description: Handles -TT, which specifies a translate transform. -// Var is an LMatrix4d. -//////////////////////////////////////////////////////////////////// -bool EggWriter:: -dispatch_translate(const string &opt, const string &arg, void *var) { - LMatrix4d *transform = (LMatrix4d *)var; - - vector_string words; - tokenize(arg, words, ","); - - LVector3d trans; - - bool okflag = false; - if (words.size() == 3) { - okflag = - string_to_double(words[0], trans[0]) && - string_to_double(words[1], trans[1]) && - string_to_double(words[2], trans[2]); - } - - if (!okflag) { - nout << "-" << opt - << " requires three numbers separated by commas.\n"; - return false; - } - - *transform = (*transform) * LMatrix4d::translate_mat(trans); - - return true; + return EggSingleBase::post_command_line(); } diff --git a/pandatool/src/eggbase/eggWriter.h b/pandatool/src/eggbase/eggWriter.h index 7b5e53716e..60973d2e83 100644 --- a/pandatool/src/eggbase/eggWriter.h +++ b/pandatool/src/eggbase/eggWriter.h @@ -20,7 +20,7 @@ #define EGGWRITER_H #include "pandatoolbase.h" -#include "eggBase.h" +#include "eggSingleBase.h" #include "withOutputFile.h" #include "filename.h" @@ -31,13 +31,10 @@ // Description : This is the base class for a program that generates // an egg file output, but doesn't read any for input. //////////////////////////////////////////////////////////////////// -class EggWriter : virtual public EggBase, public WithOutputFile { +class EggWriter : virtual public EggSingleBase, public WithOutputFile { public: EggWriter(bool allow_last_param = false, bool allow_stdout = true); - void add_normals_options(); - void add_transform_options(); - virtual EggWriter *as_writer(); virtual void post_process_egg_file(); @@ -47,29 +44,6 @@ protected: virtual bool handle_args(Args &args); virtual bool post_command_line(); - static bool dispatch_normals(ProgramBase *self, const string &opt, const string &arg, void *mode); - bool ns_dispatch_normals(const string &opt, const string &arg, void *mode); - - static bool dispatch_scale(const string &opt, const string &arg, void *var); - static bool dispatch_rotate_xyz(ProgramBase *self, const string &opt, const string &arg, void *var); - bool ns_dispatch_rotate_xyz(const string &opt, const string &arg, void *var); - static bool dispatch_rotate_axis(ProgramBase *self, const string &opt, const string &arg, void *var); - bool ns_dispatch_rotate_axis(const string &opt, const string &arg, void *var); - static bool dispatch_translate(const string &opt, const string &arg, void *var); - -protected: - enum NormalsMode { - NM_strip, - NM_polygon, - NM_vertex, - NM_preserve - }; - NormalsMode _normals_mode; - double _normals_threshold; - - bool _got_transform; - LMatrix4d _transform; - private: ofstream _output_stream; ostream *_output_ptr; diff --git a/pandatool/src/eggbase/eggbase_composite1.cxx b/pandatool/src/eggbase/eggbase_composite1.cxx index 6c11839be1..7a051de172 100644 --- a/pandatool/src/eggbase/eggbase_composite1.cxx +++ b/pandatool/src/eggbase/eggbase_composite1.cxx @@ -6,6 +6,7 @@ #include "eggMultiFilter.cxx" #include "eggReader.cxx" #include "eggWriter.cxx" +#include "eggSingleBase.cxx" #include "eggToSomething.cxx" #include "somethingToEgg.cxx"