*** empty log message ***

This commit is contained in:
David Rose 2001-04-18 01:52:55 +00:00
parent beaa04e2c9
commit 557ced9f66
15 changed files with 841 additions and 33 deletions

View File

@ -33,10 +33,8 @@ SomethingToEgg(const string &format_name,
redescribe_option
("cs",
"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 the same coordinate system as the input " + _format_name +
" file, if this can be determined.");
"Specify the coordinate system of the input " + _format_name +
"file. Normally, this can inferred from the file itself.");
}
////////////////////////////////////////////////////////////////////

View File

@ -18,6 +18,28 @@ FltBeadID::
FltBeadID(FltHeader *header) : FltBead(header) {
}
////////////////////////////////////////////////////////////////////
// Function: FltBeadID::get_id
// Access: Public
// Description: Returns the id (name) of this particular bead. Each
// MultiGen bead will have a unique name.
////////////////////////////////////////////////////////////////////
const string &FltBeadID::
get_id() const {
return _id;
}
////////////////////////////////////////////////////////////////////
// Function: FltBeadID::set_id
// Access: Public
// Description: Changes the id (name) of this particular bead. This
// should be a name that is unique to this bead.
////////////////////////////////////////////////////////////////////
void FltBeadID::
set_id(const string &id) {
_id = id;
}
////////////////////////////////////////////////////////////////////
// Function: FltBeadID::output
// Access: Public
@ -64,7 +86,9 @@ extract_record(FltRecordReader &reader) {
bool FltBeadID::
extract_ancillary(FltRecordReader &reader) {
if (reader.get_opcode() == FO_long_id) {
_id = reader.get_iterator().get_remaining_bytes();
string s = reader.get_iterator().get_remaining_bytes();
size_t zero_byte = s.find('\0');
_id = s.substr(0, zero_byte);
return true;
}

View File

@ -12,5 +12,5 @@
////////////////////////////////////////////////////////////////////
INLINE bool FltVertex::
has_color() const {
return (_flags & F_no_color) == 0;
return (_flags & F_no_color) != 0;
}

View File

@ -0,0 +1,16 @@
#begin ss_lib_target
#define TARGET fltegg
#define LOCAL_LIBS pandatoolbase progbase flt
#define OTHER_LIBS \
egg:c pandaegg:m \
mathutil:c linmath:c putil:c express:c panda:m dtoolconfig dtool
#define UNIX_SYS_LIBS \
m
#define SOURCES \
fltToEggConverter.I fltToEggConverter.cxx fltToEggConverter.h
#define INSTALL_HEADERS \
fltToEggConverter.I fltToEggConverter.h
#end ss_lib_target

View File

@ -0,0 +1,37 @@
// Filename: fltToEggConverter.I
// Created by: drose (17Apr01)
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: FltToEggConverter::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE FltToEggConverter::
~FltToEggConverter() {
}
////////////////////////////////////////////////////////////////////
// Function: FltToEggConverter::set_input_units
// Access: Public
// Description: Sets the units the input flt file is considered to
// represent. If this is unset or DU_invalid, the units
// are taken from the flt header.
////////////////////////////////////////////////////////////////////
INLINE void FltToEggConverter::
set_input_units(DistanceUnit input_units) {
_input_units = input_units;
}
////////////////////////////////////////////////////////////////////
// Function: FltToEggConverter::set_output_units
// Access: Public
// Description: Sets the units to generate in the resulting egg file.
// If this is unset, no units conversion is performed.
////////////////////////////////////////////////////////////////////
INLINE void FltToEggConverter::
set_output_units(DistanceUnit output_units) {
_output_units = output_units;
}

View File

@ -0,0 +1,423 @@
// Filename: fltToEggConverter.cxx
// Created by: drose (17Apr01)
//
////////////////////////////////////////////////////////////////////
#include "fltToEggConverter.h"
#include <fltRecord.h>
#include <fltLOD.h>
#include <fltGroup.h>
#include <fltObject.h>
#include <fltBeadID.h>
#include <fltBead.h>
#include <fltFace.h>
#include <fltVertex.h>
#include <fltVertexList.h>
#include <eggGroup.h>
#include <eggSwitchCondition.h>
#include <eggPrimitive.h>
#include <eggPolygon.h>
#include <eggPoint.h>
#include <eggVertex.h>
#include <eggVertexPool.h>
#include <string_utils.h>
////////////////////////////////////////////////////////////////////
// Function: FltToEggConverter::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
FltToEggConverter::
FltToEggConverter(EggData &egg_data) : _egg_data(egg_data) {
_input_units = DU_invalid;
_output_units = DU_invalid;
}
////////////////////////////////////////////////////////////////////
// Function: FltToEggConverter::convert_flt
// Access: Public
// Description: Returns a newly-allocated EggData structure
// corresponding to the indicated flt structure.
////////////////////////////////////////////////////////////////////
void FltToEggConverter::
convert_flt(const FltHeader *flt_header) {
_flt_header = flt_header;
if (_input_units == DU_invalid) {
switch (_flt_header->_vertex_units) {
case FltHeader::U_meters:
_input_units = DU_meters;
break;
case FltHeader::U_kilometers:
_input_units = DU_kilometers;
break;
case FltHeader::U_feet:
_input_units = DU_feet;
break;
case FltHeader::U_inches:
_input_units = DU_inches;
break;
case FltHeader::U_nautical_miles:
_input_units = DU_nautical_miles;
break;
}
}
// Generate a default vertex pool.
_main_egg_vpool = new EggVertexPool("vpool");
_egg_data.add_child(_main_egg_vpool);
// We could populate the vertex pool right away, but it's better to
// defer each vertex until we encounter it, since some of the
// vertices may need to be adjusted to match the particular polygon
// they're assigned to (for instance, to apply a transparency or
// something).
convert_record(_flt_header, (FltObject *)NULL, &_egg_data);
if (_main_egg_vpool->empty()) {
// If we didn't get any global vertices, remove the vertex pool
// just for cleanliness.
_egg_data.remove_child(_main_egg_vpool);
}
}
////////////////////////////////////////////////////////////////////
// Function: FltToEggConverter::convert_record
// Access: Private
// Description: Converts the record and all of its children.
////////////////////////////////////////////////////////////////////
void FltToEggConverter::
convert_record(const FltRecord *flt_record, const FltObject *flt_object,
EggGroupNode *egg_group) {
int num_children = flt_record->get_num_children();
for (int i = 0; i < num_children; i++) {
const FltRecord *child = flt_record->get_child(i);
if (child->is_of_type(FltLOD::get_class_type())) {
convert_lod(DCAST(FltLOD, child), flt_object, egg_group);
} else if (child->is_of_type(FltGroup::get_class_type())) {
convert_group(DCAST(FltGroup, child), flt_object, egg_group);
} else if (child->is_of_type(FltObject::get_class_type())) {
convert_object(DCAST(FltObject, child), flt_object, egg_group);
} else if (child->is_of_type(FltFace::get_class_type())) {
convert_face(DCAST(FltFace, child), flt_object, egg_group);
// Fallbacks.
} else if (child->is_of_type(FltBeadID::get_class_type())) {
convert_bead_id(DCAST(FltBeadID, child), flt_object, egg_group);
} else if (child->is_of_type(FltBead::get_class_type())) {
convert_bead(DCAST(FltBead, child), flt_object, egg_group);
} else {
convert_record(child, flt_object, egg_group);
}
}
}
////////////////////////////////////////////////////////////////////
// Function: FltToEggConverter::convert_lod
// Access: Private
// Description: Converts the LOD bead and all of its children.
////////////////////////////////////////////////////////////////////
void FltToEggConverter::
convert_lod(const FltLOD *flt_lod, const FltObject *flt_object,
EggGroupNode *egg_parent) {
EggGroup *egg_group = new EggGroup(flt_lod->get_id());
egg_parent->add_child(egg_group);
EggSwitchConditionDistance lod
(flt_lod->_switch_in, flt_lod->_switch_out,
LPoint3d(flt_lod->_center_x, flt_lod->_center_y, flt_lod->_center_z),
flt_lod->_transition_range);
egg_group->set_lod(lod);
convert_record(flt_lod, flt_object, egg_group);
}
////////////////////////////////////////////////////////////////////
// Function: FltToEggConverter::convert_group
// Access: Private
// Description: Converts the group and all of its children.
////////////////////////////////////////////////////////////////////
void FltToEggConverter::
convert_group(const FltGroup *flt_group, const FltObject *flt_object,
EggGroupNode *egg_parent) {
EggGroup *egg_group = new EggGroup(flt_group->get_id());
egg_parent->add_child(egg_group);
if ((flt_group->_flags & FltGroup::F_forward_animation) != 0) {
// It's a sequence animation.
egg_group->set_switch_flag(true);
egg_group->set_switch_fps(24.0);
}
if (flt_group->has_transform()) {
egg_group->set_transform(flt_group->get_transform());
}
///*** replicate count.
convert_record(flt_group, flt_object, egg_group);
}
////////////////////////////////////////////////////////////////////
// Function: FltToEggConverter::convert_object
// Access: Private
// Description: Converts the object and all of its children.
////////////////////////////////////////////////////////////////////
void FltToEggConverter::
convert_object(const FltObject *flt_object, const FltObject *,
EggGroupNode *egg_parent) {
EggGroup *egg_group = new EggGroup(flt_object->get_id());
egg_parent->add_child(egg_group);
if (flt_object->has_transform()) {
egg_group->set_transform(flt_object->get_transform());
}
convert_record(flt_object, flt_object, egg_group);
}
////////////////////////////////////////////////////////////////////
// Function: FltToEggConverter::convert_bead_id
// Access: Private
// Description: Converts the generic bead (with ID) and all of its
// children.
////////////////////////////////////////////////////////////////////
void FltToEggConverter::
convert_bead_id(const FltBeadID *flt_bead, const FltObject *flt_object,
EggGroupNode *egg_parent) {
EggGroup *egg_group = new EggGroup(flt_bead->get_id());
egg_parent->add_child(egg_group);
if (flt_bead->has_transform()) {
egg_group->set_transform(flt_bead->get_transform());
}
convert_record(flt_bead, flt_object, egg_group);
}
////////////////////////////////////////////////////////////////////
// Function: FltToEggConverter::convert_bead
// Access: Private
// Description: Converts the generic bead (without ID) and all of its
// children.
////////////////////////////////////////////////////////////////////
void FltToEggConverter::
convert_bead(const FltBead *flt_bead, const FltObject *flt_object,
EggGroupNode *egg_parent) {
EggGroup *egg_group = new EggGroup;
egg_parent->add_child(egg_group);
if (flt_bead->has_transform()) {
egg_group->set_transform(flt_bead->get_transform());
}
convert_record(flt_bead, flt_object, egg_group);
}
////////////////////////////////////////////////////////////////////
// Function: FltToEggConverter::convert_face
// Access: Private
// Description: Converts the face and all of its children.
////////////////////////////////////////////////////////////////////
void FltToEggConverter::
convert_face(const FltFace *flt_face, const FltObject *flt_object,
EggGroupNode *egg_parent) {
bool is_light;
switch (flt_face->_draw_type) {
case FltGeometry::DT_omni_light:
case FltGeometry::DT_uni_light:
case FltGeometry::DT_bi_light:
is_light = true;
break;
default:
is_light = false;
}
EggPrimitive *egg_prim;
if (is_light) {
egg_prim = new EggPoint;
} else {
egg_prim = new EggPolygon;
}
egg_parent->add_child(egg_prim);
// Collect the vertices for this primitive.
vector< PT(EggVertex) > vertices;
const FltVertexList *vlist = (FltVertexList *)NULL;
int num_children = flt_face->get_num_children();
for (int i = 0; i < num_children && vlist == (FltVertexList *)NULL; i++) {
const FltRecord *child = flt_face->get_child(i);
if (child->is_of_type(FltVertexList::get_class_type())) {
vlist = DCAST(FltVertexList, child);
}
}
if (vlist != (FltVertexList *)NULL) {
int num_vertices = vlist->get_num_vertices();
for (int i = 0; i < num_vertices; i++) {
FltVertex *flt_vertex = vlist->get_vertex(i);
vertices.push_back(make_egg_vertex(flt_vertex));
}
}
setup_geometry(flt_face, flt_object, egg_prim, _main_egg_vpool, vertices);
}
////////////////////////////////////////////////////////////////////
// Function: FltToEggConverter::setup_geometry
// Access: Private
// Description: Applies the state indicated in the FltGeometry record
// to the indicated EggPrimitive and all of its
// indicated vertices, and then officially adds the
// vertices to the vertex pool and to the primitive.
////////////////////////////////////////////////////////////////////
void FltToEggConverter::
setup_geometry(const FltGeometry *flt_geom, const FltObject *,
EggPrimitive *egg_prim, EggVertexPool *egg_vpool,
const FltToEggConverter::EggVertices &vertices) {
EggVertices::const_iterator vi;
if (flt_geom->has_color()) {
egg_prim->set_color(flt_geom->get_color());
}
bool use_vertex_color = true;
bool keep_normals = true;
switch (flt_geom->_light_mode) {
case FltGeometry::LM_face_no_normal:
use_vertex_color = false;
keep_normals = false;
break;
case FltGeometry::LM_vertex_no_normal:
use_vertex_color = true;
keep_normals = false;
break;
case FltGeometry::LM_face_with_normal:
use_vertex_color = false;
keep_normals = true;
break;
case FltGeometry::LM_vertex_with_normal:
use_vertex_color = true;
keep_normals = true;
break;
}
if (flt_geom->has_texture()) {
// If the geometry has a texture, apply it.
egg_prim->set_texture(make_egg_texture(flt_geom->get_texture()));
if (flt_geom->_texwhite) {
// If the geometry should be colored white under the texture,
// then eliminate any explicit color; the egg loader will
// implicitly color it white.
egg_prim->clear_color();
use_vertex_color = false;
}
}
if (use_vertex_color) {
// If we're to use vertex color instead of the face color, remove
// the face color to eliminate any ambiguity.
if (flt_geom->has_color()) {
// Also, if some of our vertices don't have a color, set them to
// use the face color.
for (vi = vertices.begin(); vi != vertices.end(); ++vi) {
if (!(*vi)->has_color()) {
(*vi)->set_color(flt_geom->get_color());
}
}
egg_prim->clear_color();
}
} else {
// If we're to use face color instead of vertex color, remove the
// vertex color to eliminate any ambiguity.
for (vi = vertices.begin(); vi != vertices.end(); ++vi) {
(*vi)->clear_color();
}
}
if (!keep_normals) {
// If we're not to use the normals, then eliminate them.
for (vi = vertices.begin(); vi != vertices.end(); ++vi) {
(*vi)->clear_normal();
}
}
for (vi = vertices.begin(); vi != vertices.end(); ++vi) {
EggVertex *egg_vertex = egg_vpool->create_unique_vertex(*(*vi));
egg_prim->add_vertex(egg_vertex);
}
}
////////////////////////////////////////////////////////////////////
// Function: FltToEggConverter::make_egg_vertex
// Access: Private
// Description: Makes a new EggVertex for the indicated FltVertex.
// The vertex is not automatically added to the vertex
// pool.
////////////////////////////////////////////////////////////////////
PT(EggVertex) FltToEggConverter::
make_egg_vertex(const FltVertex *flt_vertex) {
PT(EggVertex) egg_vertex = new EggVertex;
egg_vertex->set_pos(flt_vertex->_pos);
if (flt_vertex->_has_normal) {
egg_vertex->set_normal(LCAST(double, flt_vertex->_normal));
}
if (flt_vertex->_has_uv) {
egg_vertex->set_uv(LCAST(double, flt_vertex->_uv));
}
if (flt_vertex->has_color()) {
egg_vertex->set_color(flt_vertex->get_color());
}
return egg_vertex;
}
////////////////////////////////////////////////////////////////////
// Function: FltToEggConverter::make_egg_texture
// Access: Private
// Description: Makes a new EggTexture for the indicated FltTexture,
// or returns a pointer to one previously made for the
// same FltTexture.
////////////////////////////////////////////////////////////////////
PT(EggTexture) FltToEggConverter::
make_egg_texture(const FltTexture *flt_texture) {
Textures::const_iterator ti;
ti = _textures.find(flt_texture);
if (ti != _textures.end()) {
// There's one previously created.
return (*ti).second;
}
// Create a new one.
string tref_name = format_string(flt_texture->_pattern_index);
Filename filename = flt_texture->get_texture_filename();
PT(EggTexture) egg_texture = new EggTexture(tref_name, filename);
_textures.insert(Textures::value_type(flt_texture, egg_texture));
return egg_texture;
}

View File

@ -0,0 +1,92 @@
// Filename: fltToEggConverter.h
// Created by: drose (17Apr01)
//
////////////////////////////////////////////////////////////////////
#ifndef FLTTOEGGCONVERTER_H
#define FLTTOEGGCONVERTER_H
#include <pandatoolbase.h>
#include <distanceUnit.h>
#include <fltHeader.h>
#include <eggData.h>
#include <eggVertex.h>
#include <eggTexture.h>
#include <pointerTo.h>
class FltRecord;
class FltLOD;
class FltGroup;
class FltObject;
class FltBeadID;
class FltBead;
class FltVertex;
class FltGeometry;
class FltFace;
class FltTexture;
class EggGroupNode;
class EggPrimitive;
class EggVertexPool;
////////////////////////////////////////////////////////////////////
// Class : FltToEggConverter
// Description : This class supervises the construction of an EggData
// structure from the data represented by the FltHeader.
// Reading and writing the egg and flt structures is
// left to the user.
////////////////////////////////////////////////////////////////////
class FltToEggConverter {
public:
FltToEggConverter(EggData &egg_data);
INLINE ~FltToEggConverter();
INLINE void set_input_units(DistanceUnit input_units);
INLINE void set_output_units(DistanceUnit output_units);
void convert_flt(const FltHeader *flt_header);
private:
typedef vector< PT(EggVertex) > EggVertices;
void convert_record(const FltRecord *flt_record, const FltObject *flt_object,
EggGroupNode *egg_group);
void convert_lod(const FltLOD *flt_lod, const FltObject *flt_object,
EggGroupNode *egg_parent);
void convert_group(const FltGroup *flt_group, const FltObject *flt_object,
EggGroupNode *egg_parent);
void convert_object(const FltObject *flt_object, const FltObject *flt_object,
EggGroupNode *egg_parent);
void convert_bead_id(const FltBeadID *flt_bead, const FltObject *flt_object,
EggGroupNode *egg_parent);
void convert_bead(const FltBead *flt_bead, const FltObject *flt_object,
EggGroupNode *egg_parent);
void convert_face(const FltFace *flt_face, const FltObject *flt_object,
EggGroupNode *egg_parent);
void setup_geometry(const FltGeometry *flt_geom, const FltObject *flt_object,
EggPrimitive *egg_prim, EggVertexPool *egg_vpool,
const EggVertices &vertices);
PT(EggVertex) make_egg_vertex(const FltVertex *flt_vertex);
PT(EggTexture) make_egg_texture(const FltTexture *flt_texture);
DistanceUnit _input_units;
DistanceUnit _output_units;
EggData &_egg_data;
CPT(FltHeader) _flt_header;
EggVertexPool *_main_egg_vpool;
typedef map<const FltTexture *, PT(EggTexture) > Textures;
Textures _textures;
};
#include "fltToEggConverter.I"
#endif

View File

@ -25,3 +25,18 @@
fltTrans.cxx fltTrans.h
#end bin_target
#begin noinst_bin_target
#define TARGET flt2egg
#define LOCAL_LIBS flt fltegg eggbase progbase
#define OTHER_LIBS \
egg:c pandaegg:m \
linmath:c panda:m \
express:c pandaexpress:m \
dtoolutil:c dconfig:c dtoolconfig:m dtool:m pystub
#define SOURCES \
fltToEgg.cxx fltToEgg.h
#end noinst_bin_target

View File

@ -77,22 +77,23 @@ run() {
if (result != FE_ok) {
nout << "Unable to read: " << result << "\n";
exit(1);
} else {
if (header->check_version()) {
nout << "Version is " << header->get_flt_version() << "\n";
}
if (_got_new_version) {
header->set_flt_version(_new_version);
}
result = header->write_flt(get_output());
if (result != FE_ok) {
nout << "Unable to write: " << result << "\n";
} else {
nout << "Successfully written.\n";
}
}
if (header->check_version()) {
nout << "Version is " << header->get_flt_version() << "\n";
}
if (_got_new_version) {
header->set_flt_version(_new_version);
}
result = header->write_flt(get_output());
if (result != FE_ok) {
nout << "Unable to write: " << result << "\n";
exit(1);
}
nout << "Successfully written.\n";
}

View File

@ -70,22 +70,18 @@ run() {
exit(1);
}
// First, we build the egg file in the same coordinate system as
// Maya.
if (MGlobal::isYAxisUp()) {
_data.set_coordinate_system(CS_yup_right);
} else {
_data.set_coordinate_system(CS_zup_right);
if (!_got_coordinate_system) {
// Choose a suitable coordinate system matching Maya.
if (MGlobal::isYAxisUp()) {
_coordinate_system = CS_yup_right;
} else {
_coordinate_system = CS_zup_right;
}
}
_data.set_coordinate_system(_coordinate_system);
_maya.make_egg(_data);
// Then, if the user so requested, we convert the egg file to the
// desired output coordinate system.
if (_got_coordinate_system) {
_data.set_coordinate_system(_coordinate_system);
}
write_egg_file();
}

View File

@ -6,6 +6,7 @@
linmath:c putil:c express:c panda:m pystub dtool
#define SOURCES \
distanceUnit.cxx distanceUnit.h \
programBase.I programBase.cxx programBase.h \
withOutputFile.cxx withOutputFile.h \
wordWrapStream.cxx \
@ -13,6 +14,7 @@
wordWrapStreamBuf.h
#define INSTALL_HEADERS \
distanceUnit.h \
programBase.I programBase.h \
withOutputFile.h \
wordWrapStream.h wordWrapStreamBuf.I \

View File

@ -0,0 +1,144 @@
// Filename: distanceUnit.cxx
// Created by: drose (17Apr01)
//
////////////////////////////////////////////////////////////////////
#include "distanceUnit.h"
#include <string_utils.h>
////////////////////////////////////////////////////////////////////
// Function: DistanceUnit output operator
// Description:
////////////////////////////////////////////////////////////////////
ostream &
operator << (ostream &out, DistanceUnit unit) {
switch (unit) {
case DU_millimeters:
return out << "mm";
case DU_centimeters:
return out << "cm";
case DU_meters:
return out << "m";
case DU_kilometers:
return out << "km";
case DU_yards:
return out << "yd";
case DU_feet:
return out << "ft";
case DU_inches:
return out << "in";
case DU_nautical_miles:
return out << "nmi";
case DU_statute_miles:
return out << "mi";
case DU_invalid:
return out << "invalid";
}
return out << "**unexpected DistanceUnit value: (" << (int)unit << ")**";
}
////////////////////////////////////////////////////////////////////
// Function: string_distance_unit
// Description: Converts from a string, as might be input by the
// user, to one of the known DistanceUnit types.
// Returns DU_invalid if the string is unknown.
////////////////////////////////////////////////////////////////////
DistanceUnit
string_distance_unit(const string &str) {
if (cmp_nocase(str, "mm") == 0 || cmp_nocase(str, "millimeters") == 0) {
return DU_millimeters;
} else if (cmp_nocase(str, "cm") == 0 || cmp_nocase(str, "centimeters") == 0) {
return DU_centimeters;
} else if (cmp_nocase(str, "m") == 0 || cmp_nocase(str, "meters") == 0) {
return DU_meters;
} else if (cmp_nocase(str, "km") == 0 || cmp_nocase(str, "kilometers") == 0) {
return DU_kilometers;
} else if (cmp_nocase(str, "yd") == 0 || cmp_nocase(str, "yards") == 0) {
return DU_yards;
} else if (cmp_nocase(str, "ft") == 0 || cmp_nocase(str, "feet") == 0) {
return DU_feet;
} else if (cmp_nocase(str, "in") == 0 || cmp_nocase(str, "inches") == 0) {
return DU_inches;
} else if (cmp_nocase(str, "nmi") == 0 ||
cmp_nocase(str, "nm") == 0 ||
cmp_nocase_uh(str, "nautical_miles") == 0) {
return DU_nautical_miles;
} else if (cmp_nocase(str, "mi") == 0 ||
cmp_nocase(str, "miles") == 0 ||
cmp_nocase_uh(str, "statute_miles") == 0) {
return DU_statute_miles;
} else {
return DU_invalid;
}
}
////////////////////////////////////////////////////////////////////
// Function: unit_scale
// Description: Returns the number of the indicated unit per each
// centimeter. This internal function is used to
// implement convert_units(), below.
////////////////////////////////////////////////////////////////////
static double unit_scale(DistanceUnit unit) {
switch (unit) {
case DU_millimeters:
return 0.1;
case DU_centimeters:
return 1.0;
case DU_meters:
return 100.0;
case DU_kilometers:
return 100000.0;
case DU_yards:
return 3.0 * 12.0 * 2.54;
case DU_feet:
return 12.0 * 2.54;
case DU_inches:
return 2.54;
case DU_nautical_miles:
// This is the U.S. definition.
return 185200.0;
case DU_statute_miles:
return 5280.0 * 12.0 * 2.54;
case DU_invalid:
return 1.0;
}
return 1.0;
}
////////////////////////////////////////////////////////////////////
// Function: convert_units
// Description: Returns the scaling factor that must be applied to
// convert from units of "from" to "to".
////////////////////////////////////////////////////////////////////
double convert_units(DistanceUnit from, DistanceUnit to) {
return unit_scale(to) / unit_scale(from);
}

View File

@ -0,0 +1,35 @@
// Filename: distanceUnit.h
// Created by: drose (17Apr01)
//
////////////////////////////////////////////////////////////////////
#ifndef DISTANCEUNIT_H
#define DISTANCEUNIT_H
#include <pandatoolbase.h>
////////////////////////////////////////////////////////////////////
// Enum : DistanceUnit
// Description : This enumerated type lists all the kinds of units
// we're likely to come across in model conversion
// programs.
////////////////////////////////////////////////////////////////////
enum DistanceUnit {
DU_millimeters,
DU_centimeters,
DU_meters,
DU_kilometers,
DU_yards,
DU_feet,
DU_inches,
DU_nautical_miles,
DU_statute_miles,
DU_invalid
};
ostream &operator << (ostream &out, DistanceUnit unit);
DistanceUnit string_distance_unit(const string &str);
double convert_units(DistanceUnit from, DistanceUnit to);
#endif

View File

@ -904,6 +904,28 @@ dispatch_coordinate_system(const string &opt, const string &arg, void *var) {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: ProgramBase::dispatch_units
// Access: Protected, Static
// Description: Standard dispatch function for an option that takes
// one parameter, which is to be interpreted as a
// unit of distance measurement. The data pointer is to
// a DistanceUnit variable.
////////////////////////////////////////////////////////////////////
bool ProgramBase::
dispatch_units(const string &opt, const string &arg, void *var) {
DistanceUnit *ip = (DistanceUnit *)var;
(*ip) = string_distance_unit(arg);
if ((*ip) == DU_invalid) {
nout << "Invalid units for -" << opt << ": " << arg << "\n"
<< "Valid units are mm, cm, m, km, yd, ft, in, nmi, and mi.\n";
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////
// Function: ProgramBase::handle_help_option
// Access: Protected, Static

View File

@ -8,6 +8,8 @@
#include <pandatoolbase.h>
#include "distanceUnit.h"
#include <filename.h>
#include <vector_string.h>
@ -80,6 +82,7 @@ protected:
static bool dispatch_filename(const string &opt, const string &arg, void *var);
static bool dispatch_search_path(const string &opt, const string &arg, void *var);
static bool dispatch_coordinate_system(const string &opt, const string &arg, void *var);
static bool dispatch_units(const string &opt, const string &arg, void *var);
static bool handle_help_option(const string &opt, const string &arg, void *);