423 lines
17 KiB
C++
423 lines
17 KiB
C++
// Filename: somethingToEgg.cxx
|
|
// Created by: drose (15Feb00)
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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 "somethingToEgg.h"
|
|
|
|
#include <config_util.h>
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: SomethingToEgg::Constructor
|
|
// Access: Public
|
|
// Description: The first parameter to the constructor should be the
|
|
// one-word name of the file format that is to be read,
|
|
// for instance "OpenFlight" or "Alias". It's just used
|
|
// in printing error messages and such.
|
|
////////////////////////////////////////////////////////////////////
|
|
SomethingToEgg::
|
|
SomethingToEgg(const string &format_name,
|
|
const string &preferred_extension,
|
|
bool allow_last_param, bool allow_stdout) :
|
|
EggConverter(format_name, preferred_extension, allow_last_param, allow_stdout)
|
|
{
|
|
clear_runlines();
|
|
if (_allow_last_param) {
|
|
add_runline("[opts] input" + _preferred_extension + " output.egg");
|
|
}
|
|
add_runline("[opts] -o output.egg input" + _preferred_extension);
|
|
if (_allow_stdout) {
|
|
add_runline("[opts] input" + _preferred_extension + " >output.egg");
|
|
}
|
|
|
|
// -f doesn't make sense if we aren't reading egg files.
|
|
remove_option("f");
|
|
|
|
redescribe_option
|
|
("cs",
|
|
"Specify the coordinate system of the input " + _format_name +
|
|
" file. Normally, this can inferred from the file itself.");
|
|
|
|
add_option
|
|
("ignore", "", 0,
|
|
"Ignore non-fatal errors and generate an egg file anyway.",
|
|
&SomethingToEgg::dispatch_none, &_allow_errors);
|
|
|
|
_input_units = DU_invalid;
|
|
_output_units = DU_invalid;
|
|
_texture_path_convert = SomethingToEggConverter::PC_unchanged;
|
|
_model_path_convert = SomethingToEggConverter::PC_unchanged;
|
|
_append_to_sys_paths = false;
|
|
_merge_externals = false;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: SomethingToEgg::add_units_options
|
|
// Access: Public
|
|
// Description: Adds -ui and -uo as valid options for this program.
|
|
// If the user specifies -uo and -ui, or just -uo and
|
|
// the program specifies -ui by setting _input_units,
|
|
// the indicated units conversion will be automatically
|
|
// applied before writing out the egg file.
|
|
////////////////////////////////////////////////////////////////////
|
|
void SomethingToEgg::
|
|
add_units_options() {
|
|
add_option
|
|
("ui", "units", 40,
|
|
"Specify the units of the input " + _format_name +
|
|
" file. Normally, this can be inferred from the file itself.",
|
|
&SomethingToEgg::dispatch_units, NULL, &_input_units);
|
|
|
|
add_option
|
|
("uo", "units", 40,
|
|
"Specify the units of the resulting egg file. If this is "
|
|
"specified, the vertices in the egg file will be scaled as "
|
|
"necessary to make the appropriate units conversion; otherwise, "
|
|
"the vertices will be left as they are.",
|
|
&SomethingToEgg::dispatch_units, NULL, &_output_units);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: SomethingToEgg::add_texture_path_options
|
|
// Access: Public
|
|
// Description: Adds -rt etc. as valid options for this program.
|
|
// These specify how the texture pathnames that appear
|
|
// in the source file should be changed for the egg
|
|
// file.
|
|
////////////////////////////////////////////////////////////////////
|
|
void SomethingToEgg::
|
|
add_texture_path_options() {
|
|
add_option
|
|
("rt", "", 40,
|
|
"Convert texture filenames to relative pathnames, relative to the "
|
|
"directory specified by -rd.",
|
|
&SomethingToEgg::dispatch_path_convert_relative, NULL, &_texture_path_convert);
|
|
|
|
add_option
|
|
("rta", "", 40,
|
|
"Convert texture filenames to absolute pathnames.",
|
|
&SomethingToEgg::dispatch_path_convert_absolute, NULL, &_texture_path_convert);
|
|
|
|
add_option
|
|
("rtA", "", 40,
|
|
"Convert texture filenames to absolute pathnames that begin with the "
|
|
"prefix specified by -rd.",
|
|
&SomethingToEgg::dispatch_path_convert_rel_abs, NULL, &_texture_path_convert);
|
|
|
|
add_option
|
|
("rts", "", 40,
|
|
"Strip paths from texture filenames. Only the basename of the texture "
|
|
"will be preserved.",
|
|
&SomethingToEgg::dispatch_path_convert_strip, NULL, &_texture_path_convert);
|
|
|
|
add_option
|
|
("rtu", "", 40,
|
|
"Leave texture filenames unchanged. They will be relative if they "
|
|
"are relative in the source file, or absolute if they are absolute in "
|
|
"the source file.",
|
|
&SomethingToEgg::dispatch_path_convert_unchanged, NULL, &_texture_path_convert);
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: SomethingToEgg::add_model_path_options
|
|
// Access: Public
|
|
// Description: Adds -re etc. as valid options for this program.
|
|
// These specify how the model pathnames that appear
|
|
// in the source file should be changed for the egg
|
|
// file.
|
|
////////////////////////////////////////////////////////////////////
|
|
void SomethingToEgg::
|
|
add_model_path_options() {
|
|
add_option
|
|
("re", "", 40,
|
|
"Convert model filenames (external references) to relative pathnames, "
|
|
"relative to the directory specified by -rd.",
|
|
&SomethingToEgg::dispatch_path_convert_relative, NULL, &_model_path_convert);
|
|
|
|
add_option
|
|
("rea", "", 40,
|
|
"Convert model filenames to absolute pathnames.",
|
|
&SomethingToEgg::dispatch_path_convert_absolute, NULL, &_model_path_convert);
|
|
|
|
add_option
|
|
("reA", "", 40,
|
|
"Convert model filenames to absolute pathnames that begin with the "
|
|
"prefix specified by -rd.",
|
|
&SomethingToEgg::dispatch_path_convert_rel_abs, NULL, &_model_path_convert);
|
|
|
|
add_option
|
|
("res", "", 40,
|
|
"Strip paths from model filenames. Only the basename of the model "
|
|
"will be preserved.",
|
|
&SomethingToEgg::dispatch_path_convert_strip, NULL, &_model_path_convert);
|
|
|
|
add_option
|
|
("reu", "", 40,
|
|
"Leave model filenames unchanged. They will be relative if they "
|
|
"are relative in the source file, or absolute if they are absolute in "
|
|
"the source file.",
|
|
&SomethingToEgg::dispatch_path_convert_unchanged, NULL, &_model_path_convert);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: SomethingToEgg::add_rel_dir_options
|
|
// Access: Public
|
|
// Description: Adds -rd. This should generally be called if
|
|
// add_texture_path_options() or
|
|
// add_model_path_options() is called.
|
|
////////////////////////////////////////////////////////////////////
|
|
void SomethingToEgg::
|
|
add_rel_dir_options() {
|
|
add_option
|
|
("rd", "dir", 40,
|
|
"Specify the directory to make relative to. This is the "
|
|
"directory that all pathnames given in the source file will be "
|
|
"rewritten to be relative to, if -re or -rt is given. It is "
|
|
"ignored if one of these options is not given. If omitted, it "
|
|
"is taken from the source filename.",
|
|
&SomethingToEgg::dispatch_string, &_got_make_rel_dir, &_make_rel_dir);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: SomethingToEgg::add_search_path_options
|
|
// Access: Public
|
|
// Description: Adds -rs. If append_to_sys_paths is true, the
|
|
// specified search path is prepended to the system
|
|
// paths returned by get_texture_path() and
|
|
// get_model_path(); otherwise, it's up to the caller to
|
|
// do the right thing with the _search_path.
|
|
////////////////////////////////////////////////////////////////////
|
|
void SomethingToEgg::
|
|
add_search_path_options(bool append_to_sys_paths) {
|
|
_append_to_sys_paths = append_to_sys_paths;
|
|
add_option
|
|
("rs", "path", 40,
|
|
"A search path for textures and external file references. This "
|
|
"is a colon-separated set of directories that will be searched "
|
|
"for filenames that are not fully specified in the source file. It "
|
|
"is unrelated to -re and -rt, and is used only if the source file "
|
|
"does not store absolute pathnames. The directory containing "
|
|
"the source filename is always implicitly included.",
|
|
&SomethingToEgg::dispatch_search_path, &_got_search_path, &_search_path);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: SomethingToEgg::add_merge_externals_options
|
|
// Access: Public
|
|
// Description: Adds -f.
|
|
////////////////////////////////////////////////////////////////////
|
|
void SomethingToEgg::
|
|
add_merge_externals_options() {
|
|
add_option
|
|
("f", "", 40,
|
|
"Follow and convert all external references in the source file.",
|
|
&SomethingToEgg::dispatch_none, &_merge_externals);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: SomethingToEgg::apply_units_scale
|
|
// Access: Protected
|
|
// Description: Applies the scale indicated by the input and output
|
|
// units to the indicated egg file. This is normally
|
|
// done automatically when the file is written out.
|
|
////////////////////////////////////////////////////////////////////
|
|
void SomethingToEgg::
|
|
apply_units_scale(EggData &data) {
|
|
if (_output_units != DU_invalid && _input_units != DU_invalid &&
|
|
_input_units != _output_units) {
|
|
nout << "Converting from " << format_long_unit(_input_units)
|
|
<< " to " << format_long_unit(_output_units) << "\n";
|
|
double scale = convert_units(_input_units, _output_units);
|
|
data.transform(LMatrix4d::scale_mat(scale));
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: SomethingToEgg::handle_args
|
|
// Access: Protected
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
bool SomethingToEgg::
|
|
handle_args(Args &args) {
|
|
if (_allow_last_param && !_got_output_filename && args.size() > 1) {
|
|
_got_output_filename = true;
|
|
_output_filename = args.back();
|
|
args.pop_back();
|
|
|
|
if (!(_output_filename.get_extension() == "egg")) {
|
|
nout << "Output filename " << _output_filename
|
|
<< " does not end in .egg. If this is really what you intended, "
|
|
"use the -o output_file syntax.\n";
|
|
return false;
|
|
}
|
|
|
|
if (!verify_output_file_safe()) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (args.empty()) {
|
|
nout << "You must specify the " << _format_name
|
|
<< " file to read on the command line.\n";
|
|
return false;
|
|
}
|
|
|
|
if (args.size() != 1) {
|
|
nout << "You may only specify one " << _format_name
|
|
<< " file to read on the command line. "
|
|
<< "You specified: ";
|
|
copy(args.begin(), args.end(), ostream_iterator<string>(nout, " "));
|
|
nout << "\n";
|
|
return false;
|
|
}
|
|
|
|
_input_filename = args[0];
|
|
|
|
if (!_input_filename.exists()) {
|
|
nout << "Cannot find input file " << _input_filename << "\n";
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: SomethingToEgg::post_command_line
|
|
// Access: Protected, Virtual
|
|
// Description: This is called after the command line has been
|
|
// completely processed, and it gives the program a
|
|
// chance to do some last-minute processing and
|
|
// validation of the options and arguments. It should
|
|
// return true if everything is fine, false if there is
|
|
// an error.
|
|
////////////////////////////////////////////////////////////////////
|
|
bool SomethingToEgg::
|
|
post_command_line() {
|
|
if (!_got_make_rel_dir) {
|
|
_make_rel_dir = _input_filename.get_dirname();
|
|
}
|
|
|
|
if (_append_to_sys_paths) {
|
|
DSearchPath &texture_path = get_texture_path();
|
|
DSearchPath &model_path = get_model_path();
|
|
|
|
// Prepend the source filename to the search paths.
|
|
Filename directory = _input_filename.get_dirname();
|
|
if (directory.empty()) {
|
|
directory = ".";
|
|
}
|
|
texture_path.prepend_directory(directory);
|
|
model_path.prepend_directory(directory);
|
|
|
|
// Then prepend whatever the user specified on the command line.
|
|
if (_got_search_path) {
|
|
texture_path.prepend_path(_search_path);
|
|
model_path.prepend_path(_search_path);
|
|
}
|
|
}
|
|
|
|
return EggConverter::post_command_line();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: SomethingToEgg::post_process_egg_file
|
|
// Access: Protected, Virtual
|
|
// Description: Performs any processing of the egg file that is
|
|
// appropriate before writing it out. This includes any
|
|
// normal adjustments the user requested via -np, etc.
|
|
//
|
|
// Normally, you should not need to call this function
|
|
// directly; write_egg_file() calls it for you. You
|
|
// should call this only if you do not use
|
|
// write_egg_file() to write out the resulting egg file.
|
|
////////////////////////////////////////////////////////////////////
|
|
void SomethingToEgg::
|
|
post_process_egg_file() {
|
|
apply_units_scale(_data);
|
|
EggConverter::post_process_egg_file();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: SomethingToEgg::dispatch_path_convert_relative
|
|
// Access: Protected, Static
|
|
// Description: Dispatch function to set the given path convert mode
|
|
// to PC_relative. var is a pointer to a
|
|
// SomethingToEggConverter::PathConvert variable.
|
|
////////////////////////////////////////////////////////////////////
|
|
bool SomethingToEgg::
|
|
dispatch_path_convert_relative(const string &opt, const string &, void *var) {
|
|
SomethingToEggConverter::PathConvert *ip = (SomethingToEggConverter::PathConvert *)var;
|
|
(*ip) = SomethingToEggConverter::PC_relative;
|
|
return true;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: SomethingToEgg::dispatch_path_convert_absolute
|
|
// Access: Protected, Static
|
|
// Description: Dispatch function to set the given path convert mode
|
|
// to PC_absolute. var is a pointer to a
|
|
// SomethingToEggConverter::PathConvert variable.
|
|
////////////////////////////////////////////////////////////////////
|
|
bool SomethingToEgg::
|
|
dispatch_path_convert_absolute(const string &opt, const string &, void *var) {
|
|
SomethingToEggConverter::PathConvert *ip = (SomethingToEggConverter::PathConvert *)var;
|
|
(*ip) = SomethingToEggConverter::PC_absolute;
|
|
return true;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: SomethingToEgg::dispatch_path_convert_rel_abs
|
|
// Access: Protected, Static
|
|
// Description: Dispatch function to set the given path convert mode
|
|
// to PC_rel_abs. var is a pointer to a
|
|
// SomethingToEggConverter::PathConvert variable.
|
|
////////////////////////////////////////////////////////////////////
|
|
bool SomethingToEgg::
|
|
dispatch_path_convert_rel_abs(const string &opt, const string &, void *var) {
|
|
SomethingToEggConverter::PathConvert *ip = (SomethingToEggConverter::PathConvert *)var;
|
|
(*ip) = SomethingToEggConverter::PC_rel_abs;
|
|
return true;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: SomethingToEgg::dispatch_path_convert_strip
|
|
// Access: Protected, Static
|
|
// Description: Dispatch function to set the given path convert mode
|
|
// to PC_strip. var is a pointer to a
|
|
// SomethingToEggConverter::PathConvert variable.
|
|
////////////////////////////////////////////////////////////////////
|
|
bool SomethingToEgg::
|
|
dispatch_path_convert_strip(const string &opt, const string &, void *var) {
|
|
SomethingToEggConverter::PathConvert *ip = (SomethingToEggConverter::PathConvert *)var;
|
|
(*ip) = SomethingToEggConverter::PC_strip;
|
|
return true;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: SomethingToEgg::dispatch_path_convert_unchanged
|
|
// Access: Protected, Static
|
|
// Description: Dispatch function to set the given path convert mode
|
|
// to PC_unchanged. var is a pointer to a
|
|
// SomethingToEggConverter::PathConvert variable.
|
|
////////////////////////////////////////////////////////////////////
|
|
bool SomethingToEgg::
|
|
dispatch_path_convert_unchanged(const string &opt, const string &, void *var) {
|
|
SomethingToEggConverter::PathConvert *ip = (SomethingToEggConverter::PathConvert *)var;
|
|
(*ip) = SomethingToEggConverter::PC_unchanged;
|
|
return true;
|
|
}
|