Convert from DOS back to Unix newlines

This commit is contained in:
rdb 2015-11-08 02:12:43 +01:00
parent d1732a4dca
commit 0f2f27689a
7 changed files with 2519 additions and 2519 deletions

View File

@ -1,230 +1,230 @@
// Filename: config_egg.cxx
// Created by: drose (19Mar00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#include "config_egg.h"
#include "eggRenderMode.h"
#include "eggAnimData.h"
#include "eggAnimPreload.h"
#include "eggAttributes.h"
#include "eggBin.h"
#include "eggBinMaker.h"
#include "eggComment.h"
#include "eggCompositePrimitive.h"
#include "eggCoordinateSystem.h"
#include "eggCurve.h"
#include "eggExternalReference.h"
#include "eggFilenameNode.h"
#include "eggGroup.h"
#include "eggGroupNode.h"
#include "eggGroupUniquifier.h"
#include "eggLine.h"
#include "eggMaterial.h"
#include "eggNameUniquifier.h"
#include "eggNamedObject.h"
#include "eggNode.h"
#include "eggNurbsCurve.h"
#include "eggNurbsSurface.h"
#include "eggObject.h"
#include "eggPatch.h"
#include "eggPoint.h"
#include "eggPolygon.h"
#include "eggPolysetMaker.h"
#include "eggPoolUniquifier.h"
#include "eggPrimitive.h"
#include "eggSAnimData.h"
#include "eggSurface.h"
#include "eggSwitchCondition.h"
#include "eggTable.h"
#include "eggTexture.h"
#include "eggTriangleFan.h"
#include "eggTriangleStrip.h"
#include "eggUserData.h"
#include "eggVertex.h"
#include "eggVertexPool.h"
#include "eggVertexUV.h"
#include "eggVertexAux.h"
#include "eggXfmAnimData.h"
#include "eggXfmSAnim.h"
#include "dconfig.h"
Configure(config_egg);
NotifyCategoryDef(egg, "");
ConfigureFn(config_egg) {
init_libegg();
}
ConfigVariableBool egg_support_old_anims
("egg-support-old-anims", true,
PRC_DESC("Set this true to support loading of old character animation files, which "
"had the convention that the order \"phr\" implied a reversed roll."));
ConfigVariableBool egg_mesh
("egg-mesh", true,
PRC_DESC("Set this true to convert triangles and higher-order polygons "
"into triangle strips and triangle fans when an egg file is "
"loaded or converted to bam. Set this false just to triangulate "
"everything into independent triangles."));
ConfigVariableBool egg_retesselate_coplanar
("egg-retesselate-coplanar", false,
PRC_DESC("If this is true, the egg loader may reverse the "
"tesselation direction of a single pair of planar triangles that "
"share the same properties, if that will help get a better "
"triangle strip. In some rare cases, doing so can distort the "
"UV's on a face; turning this off should eliminate that artifact "
"(at the cost of less-effective triangle stripping)."));
ConfigVariableBool egg_unroll_fans
("egg-unroll-fans", true,
PRC_DESC("Set this true to allow the egg loader to convert weak triangle "
"fans--triangles that share the same vertex but aren't "
"connected enough to justify making a triangle fan primitive "
"from them--into a series of zig-zag triangles that can make "
"a triangle strip that might connect better with its neighbors."));
ConfigVariableBool egg_show_tstrips
("egg-show-tstrips", false,
PRC_DESC("Set this true to color each triangle strip a random color, with "
"the leading triangle a little bit darker, so you can visually "
"observe the quality of the triangle stripping algorithm."));
ConfigVariableBool egg_show_qsheets
("egg-show-qsheets", false,
PRC_DESC("Set this true to color each quadsheet a random color, so you "
"can visually observe the quadsheet algorithm."));
ConfigVariableBool egg_show_quads
("egg-show-quads", false,
PRC_DESC("Set this true to color each detected quad a random color, so "
"you can visually observe the algorithm that unifies pairs of "
"triangles into quads (prior to generating triangle strips)."));
ConfigVariableBool egg_subdivide_polys
("egg-subdivide-polys", true,
PRC_DESC("This is obsolete. In the old Geom implementation, it used to "
"be true to force higher-order polygons that were not otherwise "
"meshed to be subdivided into triangles. In the new "
"Geom implementation, this happens anyway."));
ConfigVariableBool egg_consider_fans
("egg-consider-fans", false,
PRC_DESC("Set this true to enable the egg mesher to consider making "
"triangle fans out of triangles that are connected at a common "
"vertex. This may help if your scene involves lots of such "
"connected triangles, but it can also make the overall stripping "
"less effective (by interfering with triangle strips)."));
ConfigVariableDouble egg_max_tfan_angle
("egg-max-tfan-angle", 40.0,
PRC_DESC("The maximum average angle per triangle to allow in a triangle "
"fan. If triangles are larger than this--that is, more loosely "
"packed--then we figure a triangle strip is likely to do a "
"more effective job than a triangle fan, and the fan maker leaves "
"it alone."));
ConfigVariableInt egg_min_tfan_tris
("egg-min-tfan-tris", 4,
PRC_DESC("The minimum number of triangles that must be involved in order "
"to generate a triangle fan. Fewer than this is just interrupting "
"a triangle strip."));
ConfigVariableDouble egg_coplanar_threshold
("egg-coplanar-threshold", 0.01,
PRC_DESC("The numerical threshold below which polygons are considered "
"to be coplanar. Determined empirically."));
ConfigVariableInt egg_test_vref_integrity
("egg-test-vref-integrity", 20,
PRC_DESC("The maximum number of vertices a primitive may have before "
"its vertices will no longer be checked for internal integrity. "
"This is meaningful in non-production builds only."));
ConfigVariableInt egg_recursion_limit
("egg-recursion-limit", 1000,
PRC_DESC("The maximum number of levels that recursive algorithms within "
"the egg library are allowed to traverse. This is a simple hack "
"to prevent deeply-recursive algorithms from triggering a stack "
"overflow. Set it larger to run more efficiently if your stack "
"allows it; set it lower if you experience stack overflows."));
ConfigVariableInt egg_precision
("egg-precision", 15,
PRC_DESC("The number of digits of precision to write out for values in "
"an egg file. Leave this at 0 to use the default setting for the "
"stream."));
////////////////////////////////////////////////////////////////////
// Function: init_libegg
// Description: Initializes the library. This must be called at
// least once before any of the functions or classes in
// this library can be used. Normally it will be
// called by the static initializers and need not be
// called explicitly, but special cases exist.
////////////////////////////////////////////////////////////////////
void
init_libegg() {
static bool initialized = false;
if (initialized) {
return;
}
initialized = true;
EggRenderMode::init_type();
EggAnimData::init_type();
EggAnimPreload::init_type();
EggAttributes::init_type();
EggBin::init_type();
EggBinMaker::init_type();
EggComment::init_type();
EggCompositePrimitive::init_type();
EggCoordinateSystem::init_type();
EggCurve::init_type();
EggData::init_type();
EggExternalReference::init_type();
EggFilenameNode::init_type();
EggGroup::init_type();
EggGroupNode::init_type();
EggGroupUniquifier::init_type();
EggLine::init_type();
EggMaterial::init_type();
EggNameUniquifier::init_type();
EggNamedObject::init_type();
EggNode::init_type();
EggNurbsCurve::init_type();
EggNurbsSurface::init_type();
EggObject::init_type();
EggPatch::init_type();
EggPoint::init_type();
EggPolygon::init_type();
EggPolysetMaker::init_type();
EggPoolUniquifier::init_type();
EggPrimitive::init_type();
EggSAnimData::init_type();
EggSurface::init_type();
EggSwitchCondition::init_type();
EggSwitchConditionDistance::init_type();
EggTable::init_type();
EggTexture::init_type();
EggTriangleFan::init_type();
EggTriangleStrip::init_type();
EggUserData::init_type();
EggVertex::init_type();
EggVertexPool::init_type();
EggVertexUV::init_type();
EggVertexAux::init_type();
EggXfmAnimData::init_type();
EggXfmSAnim::init_type();
}
// Filename: config_egg.cxx
// Created by: drose (19Mar00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#include "config_egg.h"
#include "eggRenderMode.h"
#include "eggAnimData.h"
#include "eggAnimPreload.h"
#include "eggAttributes.h"
#include "eggBin.h"
#include "eggBinMaker.h"
#include "eggComment.h"
#include "eggCompositePrimitive.h"
#include "eggCoordinateSystem.h"
#include "eggCurve.h"
#include "eggExternalReference.h"
#include "eggFilenameNode.h"
#include "eggGroup.h"
#include "eggGroupNode.h"
#include "eggGroupUniquifier.h"
#include "eggLine.h"
#include "eggMaterial.h"
#include "eggNameUniquifier.h"
#include "eggNamedObject.h"
#include "eggNode.h"
#include "eggNurbsCurve.h"
#include "eggNurbsSurface.h"
#include "eggObject.h"
#include "eggPatch.h"
#include "eggPoint.h"
#include "eggPolygon.h"
#include "eggPolysetMaker.h"
#include "eggPoolUniquifier.h"
#include "eggPrimitive.h"
#include "eggSAnimData.h"
#include "eggSurface.h"
#include "eggSwitchCondition.h"
#include "eggTable.h"
#include "eggTexture.h"
#include "eggTriangleFan.h"
#include "eggTriangleStrip.h"
#include "eggUserData.h"
#include "eggVertex.h"
#include "eggVertexPool.h"
#include "eggVertexUV.h"
#include "eggVertexAux.h"
#include "eggXfmAnimData.h"
#include "eggXfmSAnim.h"
#include "dconfig.h"
Configure(config_egg);
NotifyCategoryDef(egg, "");
ConfigureFn(config_egg) {
init_libegg();
}
ConfigVariableBool egg_support_old_anims
("egg-support-old-anims", true,
PRC_DESC("Set this true to support loading of old character animation files, which "
"had the convention that the order \"phr\" implied a reversed roll."));
ConfigVariableBool egg_mesh
("egg-mesh", true,
PRC_DESC("Set this true to convert triangles and higher-order polygons "
"into triangle strips and triangle fans when an egg file is "
"loaded or converted to bam. Set this false just to triangulate "
"everything into independent triangles."));
ConfigVariableBool egg_retesselate_coplanar
("egg-retesselate-coplanar", false,
PRC_DESC("If this is true, the egg loader may reverse the "
"tesselation direction of a single pair of planar triangles that "
"share the same properties, if that will help get a better "
"triangle strip. In some rare cases, doing so can distort the "
"UV's on a face; turning this off should eliminate that artifact "
"(at the cost of less-effective triangle stripping)."));
ConfigVariableBool egg_unroll_fans
("egg-unroll-fans", true,
PRC_DESC("Set this true to allow the egg loader to convert weak triangle "
"fans--triangles that share the same vertex but aren't "
"connected enough to justify making a triangle fan primitive "
"from them--into a series of zig-zag triangles that can make "
"a triangle strip that might connect better with its neighbors."));
ConfigVariableBool egg_show_tstrips
("egg-show-tstrips", false,
PRC_DESC("Set this true to color each triangle strip a random color, with "
"the leading triangle a little bit darker, so you can visually "
"observe the quality of the triangle stripping algorithm."));
ConfigVariableBool egg_show_qsheets
("egg-show-qsheets", false,
PRC_DESC("Set this true to color each quadsheet a random color, so you "
"can visually observe the quadsheet algorithm."));
ConfigVariableBool egg_show_quads
("egg-show-quads", false,
PRC_DESC("Set this true to color each detected quad a random color, so "
"you can visually observe the algorithm that unifies pairs of "
"triangles into quads (prior to generating triangle strips)."));
ConfigVariableBool egg_subdivide_polys
("egg-subdivide-polys", true,
PRC_DESC("This is obsolete. In the old Geom implementation, it used to "
"be true to force higher-order polygons that were not otherwise "
"meshed to be subdivided into triangles. In the new "
"Geom implementation, this happens anyway."));
ConfigVariableBool egg_consider_fans
("egg-consider-fans", false,
PRC_DESC("Set this true to enable the egg mesher to consider making "
"triangle fans out of triangles that are connected at a common "
"vertex. This may help if your scene involves lots of such "
"connected triangles, but it can also make the overall stripping "
"less effective (by interfering with triangle strips)."));
ConfigVariableDouble egg_max_tfan_angle
("egg-max-tfan-angle", 40.0,
PRC_DESC("The maximum average angle per triangle to allow in a triangle "
"fan. If triangles are larger than this--that is, more loosely "
"packed--then we figure a triangle strip is likely to do a "
"more effective job than a triangle fan, and the fan maker leaves "
"it alone."));
ConfigVariableInt egg_min_tfan_tris
("egg-min-tfan-tris", 4,
PRC_DESC("The minimum number of triangles that must be involved in order "
"to generate a triangle fan. Fewer than this is just interrupting "
"a triangle strip."));
ConfigVariableDouble egg_coplanar_threshold
("egg-coplanar-threshold", 0.01,
PRC_DESC("The numerical threshold below which polygons are considered "
"to be coplanar. Determined empirically."));
ConfigVariableInt egg_test_vref_integrity
("egg-test-vref-integrity", 20,
PRC_DESC("The maximum number of vertices a primitive may have before "
"its vertices will no longer be checked for internal integrity. "
"This is meaningful in non-production builds only."));
ConfigVariableInt egg_recursion_limit
("egg-recursion-limit", 1000,
PRC_DESC("The maximum number of levels that recursive algorithms within "
"the egg library are allowed to traverse. This is a simple hack "
"to prevent deeply-recursive algorithms from triggering a stack "
"overflow. Set it larger to run more efficiently if your stack "
"allows it; set it lower if you experience stack overflows."));
ConfigVariableInt egg_precision
("egg-precision", 15,
PRC_DESC("The number of digits of precision to write out for values in "
"an egg file. Leave this at 0 to use the default setting for the "
"stream."));
////////////////////////////////////////////////////////////////////
// Function: init_libegg
// Description: Initializes the library. This must be called at
// least once before any of the functions or classes in
// this library can be used. Normally it will be
// called by the static initializers and need not be
// called explicitly, but special cases exist.
////////////////////////////////////////////////////////////////////
void
init_libegg() {
static bool initialized = false;
if (initialized) {
return;
}
initialized = true;
EggRenderMode::init_type();
EggAnimData::init_type();
EggAnimPreload::init_type();
EggAttributes::init_type();
EggBin::init_type();
EggBinMaker::init_type();
EggComment::init_type();
EggCompositePrimitive::init_type();
EggCoordinateSystem::init_type();
EggCurve::init_type();
EggData::init_type();
EggExternalReference::init_type();
EggFilenameNode::init_type();
EggGroup::init_type();
EggGroupNode::init_type();
EggGroupUniquifier::init_type();
EggLine::init_type();
EggMaterial::init_type();
EggNameUniquifier::init_type();
EggNamedObject::init_type();
EggNode::init_type();
EggNurbsCurve::init_type();
EggNurbsSurface::init_type();
EggObject::init_type();
EggPatch::init_type();
EggPoint::init_type();
EggPolygon::init_type();
EggPolysetMaker::init_type();
EggPoolUniquifier::init_type();
EggPrimitive::init_type();
EggSAnimData::init_type();
EggSurface::init_type();
EggSwitchCondition::init_type();
EggSwitchConditionDistance::init_type();
EggTable::init_type();
EggTexture::init_type();
EggTriangleFan::init_type();
EggTriangleStrip::init_type();
EggUserData::init_type();
EggVertex::init_type();
EggVertexPool::init_type();
EggVertexUV::init_type();
EggVertexAux::init_type();
EggXfmAnimData::init_type();
EggXfmSAnim::init_type();
}

View File

@ -1,48 +1,48 @@
// Filename: config_egg.h
// Created by: drose (19Mar00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#ifndef CONFIG_EGG_H
#define CONFIG_EGG_H
#include "pandabase.h"
#include "notifyCategoryProxy.h"
#include "configVariableSearchPath.h"
#include "configVariableBool.h"
#include "configVariableEnum.h"
#include "configVariableDouble.h"
#include "configVariableInt.h"
NotifyCategoryDecl(egg, EXPCL_PANDAEGG, EXPTP_PANDAEGG);
extern ConfigVariableBool egg_support_old_anims;
extern EXPCL_PANDAEGG ConfigVariableBool egg_mesh;
extern EXPCL_PANDAEGG ConfigVariableBool egg_retesselate_coplanar;
extern EXPCL_PANDAEGG ConfigVariableBool egg_unroll_fans;
extern EXPCL_PANDAEGG ConfigVariableBool egg_show_tstrips;
extern EXPCL_PANDAEGG ConfigVariableBool egg_show_qsheets;
extern EXPCL_PANDAEGG ConfigVariableBool egg_show_quads;
#define egg_false_color (egg_show_tstrips | egg_show_qsheets | egg_show_quads)
extern EXPCL_PANDAEGG ConfigVariableBool egg_subdivide_polys;
extern EXPCL_PANDAEGG ConfigVariableBool egg_consider_fans;
extern EXPCL_PANDAEGG ConfigVariableDouble egg_max_tfan_angle;
extern EXPCL_PANDAEGG ConfigVariableInt egg_min_tfan_tris;
extern EXPCL_PANDAEGG ConfigVariableDouble egg_coplanar_threshold;
extern EXPCL_PANDAEGG ConfigVariableInt egg_test_vref_integrity;
extern EXPCL_PANDAEGG ConfigVariableInt egg_recursion_limit;
extern EXPCL_PANDAEGG ConfigVariableInt egg_precision;
extern EXPCL_PANDAEGG void init_libegg();
#endif
// Filename: config_egg.h
// Created by: drose (19Mar00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#ifndef CONFIG_EGG_H
#define CONFIG_EGG_H
#include "pandabase.h"
#include "notifyCategoryProxy.h"
#include "configVariableSearchPath.h"
#include "configVariableBool.h"
#include "configVariableEnum.h"
#include "configVariableDouble.h"
#include "configVariableInt.h"
NotifyCategoryDecl(egg, EXPCL_PANDAEGG, EXPTP_PANDAEGG);
extern ConfigVariableBool egg_support_old_anims;
extern EXPCL_PANDAEGG ConfigVariableBool egg_mesh;
extern EXPCL_PANDAEGG ConfigVariableBool egg_retesselate_coplanar;
extern EXPCL_PANDAEGG ConfigVariableBool egg_unroll_fans;
extern EXPCL_PANDAEGG ConfigVariableBool egg_show_tstrips;
extern EXPCL_PANDAEGG ConfigVariableBool egg_show_qsheets;
extern EXPCL_PANDAEGG ConfigVariableBool egg_show_quads;
#define egg_false_color (egg_show_tstrips | egg_show_qsheets | egg_show_quads)
extern EXPCL_PANDAEGG ConfigVariableBool egg_subdivide_polys;
extern EXPCL_PANDAEGG ConfigVariableBool egg_consider_fans;
extern EXPCL_PANDAEGG ConfigVariableDouble egg_max_tfan_angle;
extern EXPCL_PANDAEGG ConfigVariableInt egg_min_tfan_tris;
extern EXPCL_PANDAEGG ConfigVariableDouble egg_coplanar_threshold;
extern EXPCL_PANDAEGG ConfigVariableInt egg_test_vref_integrity;
extern EXPCL_PANDAEGG ConfigVariableInt egg_recursion_limit;
extern EXPCL_PANDAEGG ConfigVariableInt egg_precision;
extern EXPCL_PANDAEGG void init_libegg();
#endif

View File

@ -1,414 +1,414 @@
// Filename: eggData.cxx
// Created by: drose (20Jan99)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#include "eggData.h"
#include "eggCoordinateSystem.h"
#include "eggTextureCollection.h"
#include "eggMaterialCollection.h"
#include "eggComment.h"
#include "eggPoolUniquifier.h"
#include "config_egg.h"
#include "config_util.h"
#include "config_express.h"
#include "string_utils.h"
#include "dSearchPath.h"
#include "virtualFileSystem.h"
#include "lightMutexHolder.h"
#include "zStream.h"
extern int eggyyparse();
#include "parserDefs.h"
#include "lexerDefs.h"
TypeHandle EggData::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: EggData::resolve_egg_filename
// Access: Public, Static
// Description: Looks for the indicated filename, first along the
// indicated searchpath, and then along the model_path.
// If found, updates the filename to the full path and
// returns true; otherwise, returns false.
////////////////////////////////////////////////////////////////////
bool EggData::
resolve_egg_filename(Filename &egg_filename, const DSearchPath &searchpath) {
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
if (egg_filename.is_fully_qualified() && vfs->exists(egg_filename)) {
return true;
}
vfs->resolve_filename(egg_filename, searchpath, "egg") ||
vfs->resolve_filename(egg_filename, get_model_path(), "egg");
return vfs->exists(egg_filename);
}
////////////////////////////////////////////////////////////////////
// Function: EggData::read
// Access: Public
// Description: Opens the indicated filename and reads the egg data
// contents from it. Returns true if the file was
// successfully opened and read, false if there were
// some errors, in which case the data may be partially
// read.
//
// error is the output stream to which to write error
// messages.
////////////////////////////////////////////////////////////////////
bool EggData::
read(Filename filename, string display_name) {
filename.set_text();
set_egg_filename(filename);
if (display_name.empty()) {
display_name = filename;
}
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
PT(VirtualFile) vfile = vfs->get_file(filename);
if (vfile == NULL) {
egg_cat.error() << "Could not find " << display_name << "\n";
return false;
}
set_egg_timestamp(vfile->get_timestamp());
istream *file = vfile->open_read_file(true);
if (file == (istream *)NULL) {
egg_cat.error() << "Unable to open " << display_name << "\n";
return false;
}
egg_cat.info()
<< "Reading " << display_name << "\n";
bool read_ok = read(*file);
vfile->close_read_file(file);
return read_ok;
}
////////////////////////////////////////////////////////////////////
// Function: EggData::read
// Access: Public
// Description: Parses the egg syntax contained in the indicated
// input stream. Returns true if the stream was a
// completely valid egg file, false if there were some
// errors, in which case the data may be partially read.
//
// Before you call this routine, you should probably
// call set_egg_filename() to set the name of the egg
// file we're processing, if at all possible. If there
// is no such filename, you may set it to the empty
// string.
////////////////////////////////////////////////////////////////////
bool EggData::
read(istream &in) {
// First, dispense with any children we had previously. We will
// replace them with the new data.
clear();
// Create a temporary EggData structure to read into. We initialize
// it with a copy of ourselves, so that it will get our _coordsys
// value, if the user set it.
PT(EggData) data = new EggData(*this);
int error_count;
{
LightMutexHolder holder(egg_lock);
egg_init_parser(in, get_egg_filename(), data, data);
eggyyparse();
egg_cleanup_parser();
error_count = egg_error_count();
}
data->post_read();
steal_children(*data);
(*this) = *data;
return (error_count == 0);
}
////////////////////////////////////////////////////////////////////
// Function: EggData::merge
// Access: Public
// Description: Appends the other egg structure to the end of this
// one. The other egg structure is invalidated.
////////////////////////////////////////////////////////////////////
void EggData::
merge(EggData &other) {
if (get_coordinate_system() == CS_default) {
// If we haven't specified a coordinate system yet, we inherit the
// other one's.
set_coordinate_system(other.get_coordinate_system());
} else {
// Otherwise, the other one is forced into our coordinate system
// before we merge.
other.set_coordinate_system(get_coordinate_system());
}
steal_children(other);
}
////////////////////////////////////////////////////////////////////
// Function: EggData::load_externals
// Access: Public
// Description: Loads up all the egg files referenced by <File>
// entries within the egg structure, and inserts their
// contents in place of the <File> entries. Searches
// for files in the searchpath, if not found directly,
// and writes error messages to the indicated output
// stream. Returns true if all externals were loaded
// successfully, false otherwise.
////////////////////////////////////////////////////////////////////
bool EggData::
load_externals(const DSearchPath &searchpath) {
return
r_load_externals(searchpath, get_coordinate_system(), NULL);
}
////////////////////////////////////////////////////////////////////
// Function: EggData::load_externals
// Access: Public
// Description: Loads up all the egg files referenced by <File>
// entries within the egg structure, and inserts their
// contents in place of the <File> entries. Searches
// for files in the searchpath, if not found directly,
// and writes error messages to the indicated output
// stream. Returns true if all externals were loaded
// successfully, false otherwise.
////////////////////////////////////////////////////////////////////
bool EggData::
load_externals(const DSearchPath &searchpath, BamCacheRecord *record) {
return
r_load_externals(searchpath, get_coordinate_system(), record);
}
////////////////////////////////////////////////////////////////////
// Function: EggData::collapse_equivalent_textures
// Access: Public
// Description: Removes duplicate references to the same texture
// image with the same properties. Considers two
// texture references with identical properties, but
// different tref names, to be equivalent, and collapses
// them, choosing one tref name to keep arbitrarily.
// Returns the number of textures removed.
////////////////////////////////////////////////////////////////////
int EggData::
collapse_equivalent_textures() {
EggTextureCollection textures;
textures.find_used_textures(this);
return
textures.collapse_equivalent_textures(~EggTexture::E_tref_name, this);
}
////////////////////////////////////////////////////////////////////
// Function: EggData::collapse_equivalent_materials
// Access: Public
// Description: Removes duplicate references to the same material
// with the same properties. Considers two material
// references with identical properties, but different
// mref names, to be equivalent, and collapses them,
// choosing one mref name to keep arbitrarily. Returns
// the number of materials removed.
////////////////////////////////////////////////////////////////////
int EggData::
collapse_equivalent_materials() {
EggMaterialCollection materials;
materials.find_used_materials(this);
return
materials.collapse_equivalent_materials(~EggMaterial::E_mref_name, this);
}
////////////////////////////////////////////////////////////////////
// Function: EggData::write_egg
// Access: Public
// Description: The main interface for writing complete egg files.
////////////////////////////////////////////////////////////////////
bool EggData::
write_egg(Filename filename) {
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
filename.set_text();
vfs->delete_file(filename);
ostream *file = vfs->open_write_file(filename, true, true);
if (file == (ostream *)NULL) {
egg_cat.error() << "Unable to open " << filename << " for writing.\n";
return false;
}
bool wrote_ok = write_egg(*file);
vfs->close_write_file(file);
return wrote_ok;
}
////////////////////////////////////////////////////////////////////
// Function: EggData::write_egg
// Access: Public
// Description: The main interface for writing complete egg files.
////////////////////////////////////////////////////////////////////
bool EggData::
write_egg(ostream &out) {
pre_write();
if (egg_precision > 0) {
// Change the egg precision as requested.
streamsize orig_precision = out.precision();
out.precision((streamsize)egg_precision);
write(out, 0);
out.precision(orig_precision);
} else {
// Use the stream default precision.
write(out, 0);
}
return true;
}
////////////////////////////////////////////////////////////////////
// Function: EggData::set_coordinate_system
// Access: Public
// Description: Changes the coordinate system of the EggData. If the
// coordinate system was previously different, this may
// result in a conversion of the data.
////////////////////////////////////////////////////////////////////
void EggData::
set_coordinate_system(CoordinateSystem new_coordsys) {
if (new_coordsys == CS_default) {
new_coordsys = get_default_coordinate_system();
}
if (new_coordsys != _coordsys &&
(_coordsys != CS_default && _coordsys != CS_invalid)) {
// Time to convert the data.
LMatrix4d mat = LMatrix4d::convert_mat(_coordsys, new_coordsys);
LMatrix4d inv = LMatrix4d::convert_mat(new_coordsys, _coordsys);
r_transform(mat, inv, new_coordsys);
r_transform_vertices(mat);
// Now we have to update the under_flags to ensure that all the
// cached relative matrices are correct.
update_under(0);
}
_coordsys = new_coordsys;
}
////////////////////////////////////////////////////////////////////
// Function: EggData::write
// Access: Protected, Virtual
// Description: Writes the egg data out to the indicated output
// stream.
////////////////////////////////////////////////////////////////////
void EggData::
write(ostream &out, int indent_level) const {
PT(EggCoordinateSystem) ecs = new EggCoordinateSystem(_coordsys);
ecs->write(out, indent_level);
EggGroupNode::write(out, indent_level);
out << flush;
}
////////////////////////////////////////////////////////////////////
// Function: EggData::post_read
// Access: Private
// Description: Does whatever processing is appropriate after reading
// the data in from an egg file.
////////////////////////////////////////////////////////////////////
void EggData::
post_read() {
CoordinateSystem old_coordsys = _coordsys;
_coordsys = find_coordsys_entry();
if (_coordsys == CS_default) {
// If the egg file didn't contain a <CoordinateSystem> entry,
// assume it's Y-up, by convention.
_coordsys = CS_yup_right;
} else if (_coordsys == CS_invalid) {
egg_cat.warning()
<< "Contradictory <CoordinateSystem> entries encountered.\n";
_coordsys = CS_yup_right;
}
r_mark_coordsys(_coordsys);
if (old_coordsys != CS_default) {
// Now if we had a previous definition, enforce it. This might
// convert the data to the given coordinate system.
set_coordinate_system(old_coordsys);
}
// Fill this in before we automatically resolve pathnames.
_had_absolute_pathnames = has_absolute_pathnames();
if (get_auto_resolve_externals()) {
// Resolve filenames that are relative to the egg file.
DSearchPath dir;
dir.append_directory(get_egg_filename().get_dirname());
resolve_filenames(dir);
}
}
////////////////////////////////////////////////////////////////////
// Function: EggData::pre_write
// Access: Private
// Description: Does whatever processing is appropriate just before
// writing the data out to an egg file. This includes
// verifying that vertex pool names are unique, etc.
////////////////////////////////////////////////////////////////////
void EggData::
pre_write() {
// Pull out all of the texture definitions in the file and massage
// them a bit.
EggTextureCollection textures;
textures.extract_textures(this);
// Remove any textures that aren't being used.
textures.remove_unused_textures(this);
// Collapse out any textures that are completely equivalent. For
// this purpose, we consider two textures with identical properties
// but different tref names to be different.
textures.collapse_equivalent_textures(~0, this);
// Make sure all of the textures have unique TRef names.
textures.uniquify_trefs();
textures.sort_by_tref();
// Do the same thing with the materials.
EggMaterialCollection materials;
materials.extract_materials(this);
materials.remove_unused_materials(this);
materials.collapse_equivalent_materials(~0, this);
materials.uniquify_mrefs();
materials.sort_by_mref();
// Now put them all back at the head of the file, after any initial
// comment records.
iterator ci = begin();
while (ci != end() && (*ci)->is_of_type(EggComment::get_class_type())) {
++ci;
}
textures.insert_textures(this, ci);
materials.insert_materials(this, ci);
// Also make sure that the vertex pools are uniquely named. This
// also checks textures and materials, which is kind of redundant
// since we just did that, but we don't mind.
EggPoolUniquifier pu;
pu.uniquify(this);
}
// Filename: eggData.cxx
// Created by: drose (20Jan99)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#include "eggData.h"
#include "eggCoordinateSystem.h"
#include "eggTextureCollection.h"
#include "eggMaterialCollection.h"
#include "eggComment.h"
#include "eggPoolUniquifier.h"
#include "config_egg.h"
#include "config_util.h"
#include "config_express.h"
#include "string_utils.h"
#include "dSearchPath.h"
#include "virtualFileSystem.h"
#include "lightMutexHolder.h"
#include "zStream.h"
extern int eggyyparse();
#include "parserDefs.h"
#include "lexerDefs.h"
TypeHandle EggData::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: EggData::resolve_egg_filename
// Access: Public, Static
// Description: Looks for the indicated filename, first along the
// indicated searchpath, and then along the model_path.
// If found, updates the filename to the full path and
// returns true; otherwise, returns false.
////////////////////////////////////////////////////////////////////
bool EggData::
resolve_egg_filename(Filename &egg_filename, const DSearchPath &searchpath) {
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
if (egg_filename.is_fully_qualified() && vfs->exists(egg_filename)) {
return true;
}
vfs->resolve_filename(egg_filename, searchpath, "egg") ||
vfs->resolve_filename(egg_filename, get_model_path(), "egg");
return vfs->exists(egg_filename);
}
////////////////////////////////////////////////////////////////////
// Function: EggData::read
// Access: Public
// Description: Opens the indicated filename and reads the egg data
// contents from it. Returns true if the file was
// successfully opened and read, false if there were
// some errors, in which case the data may be partially
// read.
//
// error is the output stream to which to write error
// messages.
////////////////////////////////////////////////////////////////////
bool EggData::
read(Filename filename, string display_name) {
filename.set_text();
set_egg_filename(filename);
if (display_name.empty()) {
display_name = filename;
}
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
PT(VirtualFile) vfile = vfs->get_file(filename);
if (vfile == NULL) {
egg_cat.error() << "Could not find " << display_name << "\n";
return false;
}
set_egg_timestamp(vfile->get_timestamp());
istream *file = vfile->open_read_file(true);
if (file == (istream *)NULL) {
egg_cat.error() << "Unable to open " << display_name << "\n";
return false;
}
egg_cat.info()
<< "Reading " << display_name << "\n";
bool read_ok = read(*file);
vfile->close_read_file(file);
return read_ok;
}
////////////////////////////////////////////////////////////////////
// Function: EggData::read
// Access: Public
// Description: Parses the egg syntax contained in the indicated
// input stream. Returns true if the stream was a
// completely valid egg file, false if there were some
// errors, in which case the data may be partially read.
//
// Before you call this routine, you should probably
// call set_egg_filename() to set the name of the egg
// file we're processing, if at all possible. If there
// is no such filename, you may set it to the empty
// string.
////////////////////////////////////////////////////////////////////
bool EggData::
read(istream &in) {
// First, dispense with any children we had previously. We will
// replace them with the new data.
clear();
// Create a temporary EggData structure to read into. We initialize
// it with a copy of ourselves, so that it will get our _coordsys
// value, if the user set it.
PT(EggData) data = new EggData(*this);
int error_count;
{
LightMutexHolder holder(egg_lock);
egg_init_parser(in, get_egg_filename(), data, data);
eggyyparse();
egg_cleanup_parser();
error_count = egg_error_count();
}
data->post_read();
steal_children(*data);
(*this) = *data;
return (error_count == 0);
}
////////////////////////////////////////////////////////////////////
// Function: EggData::merge
// Access: Public
// Description: Appends the other egg structure to the end of this
// one. The other egg structure is invalidated.
////////////////////////////////////////////////////////////////////
void EggData::
merge(EggData &other) {
if (get_coordinate_system() == CS_default) {
// If we haven't specified a coordinate system yet, we inherit the
// other one's.
set_coordinate_system(other.get_coordinate_system());
} else {
// Otherwise, the other one is forced into our coordinate system
// before we merge.
other.set_coordinate_system(get_coordinate_system());
}
steal_children(other);
}
////////////////////////////////////////////////////////////////////
// Function: EggData::load_externals
// Access: Public
// Description: Loads up all the egg files referenced by <File>
// entries within the egg structure, and inserts their
// contents in place of the <File> entries. Searches
// for files in the searchpath, if not found directly,
// and writes error messages to the indicated output
// stream. Returns true if all externals were loaded
// successfully, false otherwise.
////////////////////////////////////////////////////////////////////
bool EggData::
load_externals(const DSearchPath &searchpath) {
return
r_load_externals(searchpath, get_coordinate_system(), NULL);
}
////////////////////////////////////////////////////////////////////
// Function: EggData::load_externals
// Access: Public
// Description: Loads up all the egg files referenced by <File>
// entries within the egg structure, and inserts their
// contents in place of the <File> entries. Searches
// for files in the searchpath, if not found directly,
// and writes error messages to the indicated output
// stream. Returns true if all externals were loaded
// successfully, false otherwise.
////////////////////////////////////////////////////////////////////
bool EggData::
load_externals(const DSearchPath &searchpath, BamCacheRecord *record) {
return
r_load_externals(searchpath, get_coordinate_system(), record);
}
////////////////////////////////////////////////////////////////////
// Function: EggData::collapse_equivalent_textures
// Access: Public
// Description: Removes duplicate references to the same texture
// image with the same properties. Considers two
// texture references with identical properties, but
// different tref names, to be equivalent, and collapses
// them, choosing one tref name to keep arbitrarily.
// Returns the number of textures removed.
////////////////////////////////////////////////////////////////////
int EggData::
collapse_equivalent_textures() {
EggTextureCollection textures;
textures.find_used_textures(this);
return
textures.collapse_equivalent_textures(~EggTexture::E_tref_name, this);
}
////////////////////////////////////////////////////////////////////
// Function: EggData::collapse_equivalent_materials
// Access: Public
// Description: Removes duplicate references to the same material
// with the same properties. Considers two material
// references with identical properties, but different
// mref names, to be equivalent, and collapses them,
// choosing one mref name to keep arbitrarily. Returns
// the number of materials removed.
////////////////////////////////////////////////////////////////////
int EggData::
collapse_equivalent_materials() {
EggMaterialCollection materials;
materials.find_used_materials(this);
return
materials.collapse_equivalent_materials(~EggMaterial::E_mref_name, this);
}
////////////////////////////////////////////////////////////////////
// Function: EggData::write_egg
// Access: Public
// Description: The main interface for writing complete egg files.
////////////////////////////////////////////////////////////////////
bool EggData::
write_egg(Filename filename) {
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
filename.set_text();
vfs->delete_file(filename);
ostream *file = vfs->open_write_file(filename, true, true);
if (file == (ostream *)NULL) {
egg_cat.error() << "Unable to open " << filename << " for writing.\n";
return false;
}
bool wrote_ok = write_egg(*file);
vfs->close_write_file(file);
return wrote_ok;
}
////////////////////////////////////////////////////////////////////
// Function: EggData::write_egg
// Access: Public
// Description: The main interface for writing complete egg files.
////////////////////////////////////////////////////////////////////
bool EggData::
write_egg(ostream &out) {
pre_write();
if (egg_precision > 0) {
// Change the egg precision as requested.
streamsize orig_precision = out.precision();
out.precision((streamsize)egg_precision);
write(out, 0);
out.precision(orig_precision);
} else {
// Use the stream default precision.
write(out, 0);
}
return true;
}
////////////////////////////////////////////////////////////////////
// Function: EggData::set_coordinate_system
// Access: Public
// Description: Changes the coordinate system of the EggData. If the
// coordinate system was previously different, this may
// result in a conversion of the data.
////////////////////////////////////////////////////////////////////
void EggData::
set_coordinate_system(CoordinateSystem new_coordsys) {
if (new_coordsys == CS_default) {
new_coordsys = get_default_coordinate_system();
}
if (new_coordsys != _coordsys &&
(_coordsys != CS_default && _coordsys != CS_invalid)) {
// Time to convert the data.
LMatrix4d mat = LMatrix4d::convert_mat(_coordsys, new_coordsys);
LMatrix4d inv = LMatrix4d::convert_mat(new_coordsys, _coordsys);
r_transform(mat, inv, new_coordsys);
r_transform_vertices(mat);
// Now we have to update the under_flags to ensure that all the
// cached relative matrices are correct.
update_under(0);
}
_coordsys = new_coordsys;
}
////////////////////////////////////////////////////////////////////
// Function: EggData::write
// Access: Protected, Virtual
// Description: Writes the egg data out to the indicated output
// stream.
////////////////////////////////////////////////////////////////////
void EggData::
write(ostream &out, int indent_level) const {
PT(EggCoordinateSystem) ecs = new EggCoordinateSystem(_coordsys);
ecs->write(out, indent_level);
EggGroupNode::write(out, indent_level);
out << flush;
}
////////////////////////////////////////////////////////////////////
// Function: EggData::post_read
// Access: Private
// Description: Does whatever processing is appropriate after reading
// the data in from an egg file.
////////////////////////////////////////////////////////////////////
void EggData::
post_read() {
CoordinateSystem old_coordsys = _coordsys;
_coordsys = find_coordsys_entry();
if (_coordsys == CS_default) {
// If the egg file didn't contain a <CoordinateSystem> entry,
// assume it's Y-up, by convention.
_coordsys = CS_yup_right;
} else if (_coordsys == CS_invalid) {
egg_cat.warning()
<< "Contradictory <CoordinateSystem> entries encountered.\n";
_coordsys = CS_yup_right;
}
r_mark_coordsys(_coordsys);
if (old_coordsys != CS_default) {
// Now if we had a previous definition, enforce it. This might
// convert the data to the given coordinate system.
set_coordinate_system(old_coordsys);
}
// Fill this in before we automatically resolve pathnames.
_had_absolute_pathnames = has_absolute_pathnames();
if (get_auto_resolve_externals()) {
// Resolve filenames that are relative to the egg file.
DSearchPath dir;
dir.append_directory(get_egg_filename().get_dirname());
resolve_filenames(dir);
}
}
////////////////////////////////////////////////////////////////////
// Function: EggData::pre_write
// Access: Private
// Description: Does whatever processing is appropriate just before
// writing the data out to an egg file. This includes
// verifying that vertex pool names are unique, etc.
////////////////////////////////////////////////////////////////////
void EggData::
pre_write() {
// Pull out all of the texture definitions in the file and massage
// them a bit.
EggTextureCollection textures;
textures.extract_textures(this);
// Remove any textures that aren't being used.
textures.remove_unused_textures(this);
// Collapse out any textures that are completely equivalent. For
// this purpose, we consider two textures with identical properties
// but different tref names to be different.
textures.collapse_equivalent_textures(~0, this);
// Make sure all of the textures have unique TRef names.
textures.uniquify_trefs();
textures.sort_by_tref();
// Do the same thing with the materials.
EggMaterialCollection materials;
materials.extract_materials(this);
materials.remove_unused_materials(this);
materials.collapse_equivalent_materials(~0, this);
materials.uniquify_mrefs();
materials.sort_by_mref();
// Now put them all back at the head of the file, after any initial
// comment records.
iterator ci = begin();
while (ci != end() && (*ci)->is_of_type(EggComment::get_class_type())) {
++ci;
}
textures.insert_textures(this, ci);
materials.insert_materials(this, ci);
// Also make sure that the vertex pools are uniquely named. This
// also checks textures and materials, which is kind of redundant
// since we just did that, but we don't mind.
EggPoolUniquifier pu;
pu.uniquify(this);
}

View File

@ -1,25 +1,25 @@
#begin ss_lib_target
#define TARGET p3objegg
#define LOCAL_LIBS p3converter p3pandatoolbase
#define OTHER_LIBS \
p3egg:c pandaegg:m \
p3pipeline:c p3event:c p3pstatclient:c panda:m \
p3pandabase:c p3pnmimage:c p3mathutil:c p3linmath:c p3putil:c p3express:c \
p3interrogatedb:c p3prc:c p3dconfig:c p3dtoolconfig:m \
p3dtoolutil:c p3dtoolbase:c p3dtool:m \
$[if $[WANT_NATIVE_NET],p3nativenet:c] \
$[if $[and $[HAVE_NET],$[WANT_NATIVE_NET]],p3net:c p3downloader:c]
#define UNIX_SYS_LIBS \
m
#define SOURCES \
config_objegg.cxx config_objegg.h \
objToEggConverter.cxx objToEggConverter.h objToEggConverter.I \
eggToObjConverter.cxx eggToObjConverter.h
#define INSTALL_HEADERS \
objToEggConverter.h objToEggConverter.I \
eggToObjConverter.h
#end ss_lib_target
#begin ss_lib_target
#define TARGET p3objegg
#define LOCAL_LIBS p3converter p3pandatoolbase
#define OTHER_LIBS \
p3egg:c pandaegg:m \
p3pipeline:c p3event:c p3pstatclient:c panda:m \
p3pandabase:c p3pnmimage:c p3mathutil:c p3linmath:c p3putil:c p3express:c \
p3interrogatedb:c p3prc:c p3dconfig:c p3dtoolconfig:m \
p3dtoolutil:c p3dtoolbase:c p3dtool:m \
$[if $[WANT_NATIVE_NET],p3nativenet:c] \
$[if $[and $[HAVE_NET],$[WANT_NATIVE_NET]],p3net:c p3downloader:c]
#define UNIX_SYS_LIBS \
m
#define SOURCES \
config_objegg.cxx config_objegg.h \
objToEggConverter.cxx objToEggConverter.h objToEggConverter.I \
eggToObjConverter.cxx eggToObjConverter.h
#define INSTALL_HEADERS \
objToEggConverter.h objToEggConverter.I \
eggToObjConverter.h
#end ss_lib_target

View File

@ -1,462 +1,462 @@
// Filename: eggToObjConverter.cxx
// Created by: drose (19Dec12)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#include "eggToObjConverter.h"
#include "config_objegg.h"
#include "config_egg.h"
#include "eggData.h"
#include "string_utils.h"
#include "streamReader.h"
#include "virtualFileSystem.h"
#include "eggPolygon.h"
#include "eggPoint.h"
#include "eggLine.h"
#include "dcast.h"
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
EggToObjConverter::
EggToObjConverter() {
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::Copy Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
EggToObjConverter::
EggToObjConverter(const EggToObjConverter &copy) :
EggToSomethingConverter(copy)
{
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
EggToObjConverter::
~EggToObjConverter() {
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::make_copy
// Access: Public, Virtual
// Description: Allocates and returns a new copy of the converter.
////////////////////////////////////////////////////////////////////
EggToSomethingConverter *EggToObjConverter::
make_copy() {
return new EggToObjConverter(*this);
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::get_name
// Access: Public, Virtual
// Description: Returns the English name of the file type this
// converter supports.
////////////////////////////////////////////////////////////////////
string EggToObjConverter::
get_name() const {
return "obj";
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::get_extension
// Access: Public, Virtual
// Description: Returns the common extension of the file type this
// converter supports.
////////////////////////////////////////////////////////////////////
string EggToObjConverter::
get_extension() const {
return "obj";
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::supports_compressed
// Access: Published, Virtual
// Description: Returns true if this file type can transparently save
// compressed files (with a .pz extension), false
// otherwise.
////////////////////////////////////////////////////////////////////
bool EggToObjConverter::
supports_compressed() const {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::write_file
// Access: Public, Virtual
// Description: Handles the conversion of the internal EggData to the
// target file format, written to the specified
// filename.
////////////////////////////////////////////////////////////////////
bool EggToObjConverter::
write_file(const Filename &filename) {
clear_error();
if (_egg_data->get_coordinate_system() == CS_default) {
_egg_data->set_coordinate_system(CS_zup_right);
}
if (!process(filename)) {
_error = true;
}
return !had_error();
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::process
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
bool EggToObjConverter::
process(const Filename &filename) {
_egg_data->flatten_transforms();
collect_vertices(_egg_data);
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
Filename obj_filename = Filename::text_filename(filename);
vfs->delete_file(obj_filename);
ostream *file = vfs->open_write_file(obj_filename, true, true);
if (file == (ostream *)NULL) {
return false;
}
if (egg_precision != 0) {
file->precision(egg_precision);
}
_current_group = NULL;
/*
(*file) << "\n#\n"
<< "# obj file generated by the following command:\n"
<< "# " << get_exec_command() << "\n"
<< "#\n\n";
*/
write_vertices(*file, "v", 3, _unique_vert3);
write_vertices(*file, "v", 4, _unique_vert4);
write_vertices(*file, "vt", 2, _unique_uv2);
write_vertices(*file, "vt", 3, _unique_uv3);
write_vertices(*file, "vn", 3, _unique_norm);
write_faces(*file, _egg_data);
bool success = (file != (ostream *)NULL);
vfs->close_write_file(file);
return success;
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::collect_vertices
// Access: Private
// Description: Recursively walks the egg structure, looking for
// vertices referenced by polygons or points. Any such
// vertices are added to the vertex tables for writing
// to the obj file.
////////////////////////////////////////////////////////////////////
void EggToObjConverter::
collect_vertices(EggNode *egg_node) {
if (egg_node->is_of_type(EggPrimitive::get_class_type())) {
EggPrimitive *egg_prim = DCAST(EggPrimitive, egg_node);
EggPrimitive::iterator pi;
for (pi = egg_prim->begin(); pi != egg_prim->end(); ++pi) {
record_vertex(*pi);
}
} else if (egg_node->is_of_type(EggGroupNode::get_class_type())) {
EggGroupNode *egg_group = DCAST(EggGroupNode, egg_node);
EggGroupNode::iterator ci;
for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
collect_vertices(*ci);
}
}
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::write_faces
// Access: Private
// Description: Recursively walks the egg structure again, this time
// writing out the face records for any polygons,
// points, or lines encountered.
////////////////////////////////////////////////////////////////////
void EggToObjConverter::
write_faces(ostream &out, EggNode *egg_node) {
if (egg_node->is_of_type(EggPrimitive::get_class_type())) {
const char *prim_type = NULL;
if (egg_node->is_of_type(EggPolygon::get_class_type())) {
prim_type = "f";
} else if (egg_node->is_of_type(EggPoint::get_class_type())) {
prim_type = "p";
} else if (egg_node->is_of_type(EggLine::get_class_type())) {
prim_type = "l";
}
if (prim_type != NULL) {
write_group_reference(out, egg_node);
EggPrimitive *egg_prim = DCAST(EggPrimitive, egg_node);
out << prim_type;
EggPrimitive::iterator pi;
for (pi = egg_prim->begin(); pi != egg_prim->end(); ++pi) {
VertexDef &vdef = _vmap[(*pi)];
int vert_index = -1;
int uv_index = -1;
int norm_index = -1;
if (vdef._vert3_index != -1) {
vert_index = vdef._vert3_index + 1;
} else if (vdef._vert4_index != -1) {
vert_index = vdef._vert4_index + 1 + (int)_unique_vert3.size();
}
if (vdef._uv2_index != -1) {
uv_index = vdef._uv2_index + 1;
} else if (vdef._uv3_index != -1) {
uv_index = vdef._uv3_index + 1 + (int)_unique_uv2.size();
}
if (vdef._norm_index != -1) {
norm_index = vdef._norm_index + 1;
}
if (vert_index == -1) {
continue;
}
if (norm_index != -1) {
if (uv_index != -1) {
out << " " << vert_index << "/" << uv_index << "/" << norm_index;
} else {
out << " " << vert_index << "//" << norm_index;
}
} else if (uv_index != -1) {
out << " " << vert_index << "/" << uv_index;
} else {
out << " " << vert_index;
}
}
out << "\n";
}
} else if (egg_node->is_of_type(EggGroupNode::get_class_type())) {
EggGroupNode *egg_group = DCAST(EggGroupNode, egg_node);
EggGroupNode::iterator ci;
for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
write_faces(out, *ci);
}
}
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::write_group_reference
// Access: Private
// Description: Writes the "g" tag to describe this polygon's group,
// if needed.
////////////////////////////////////////////////////////////////////
void EggToObjConverter::
write_group_reference(ostream &out, EggNode *egg_node) {
EggGroupNode *egg_group = egg_node->get_parent();
if (egg_group == _current_group) {
// Same group we wrote last time.
return;
}
string group_name;
get_group_name(group_name, egg_group);
if (group_name.empty()) {
out << "g default\n";
} else {
out << "g" << group_name << "\n";
}
_current_group = egg_group;
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::get_group_name
// Access: Private
// Description: Recursively determines the appropriate string to
// write for the "g" tag to describe a particular
// EggGroupNode.
////////////////////////////////////////////////////////////////////
void EggToObjConverter::
get_group_name(string &group_name, EggGroupNode *egg_group) {
string name = trim(egg_group->get_name());
if (!name.empty()) {
group_name += ' ';
// Remove nonstandard characters.
for (string::const_iterator ni = name.begin(); ni != name.end(); ++ni) {
char c = (*ni);
if (!isalnum(c)) {
c = '_';
}
group_name += c;
}
}
// Now recurse.
EggGroupNode *egg_parent = egg_group->get_parent();
if (egg_parent != NULL) {
get_group_name(group_name, egg_parent);
}
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::record_vertex
// Access: Private
// Description: Adds the indicated EggVertex to the unique vertex
// tables, for writing later by write_vertices().
////////////////////////////////////////////////////////////////////
void EggToObjConverter::
record_vertex(EggVertex *vertex) {
VertexDef &vdef = _vmap[vertex];
switch (vertex->get_num_dimensions()) {
case 1:
vdef._vert3_index = record_unique(_unique_vert3, vertex->get_pos1());
break;
case 2:
vdef._vert3_index = record_unique(_unique_vert3, vertex->get_pos2());
break;
case 3:
vdef._vert3_index = record_unique(_unique_vert3, vertex->get_pos3());
break;
case 4:
vdef._vert4_index = record_unique(_unique_vert4, vertex->get_pos4());
break;
}
if (vertex->has_uv("")) {
vdef._uv2_index = record_unique(_unique_uv2, vertex->get_uv(""));
} else if (vertex->has_uvw("")) {
vdef._uv3_index = record_unique(_unique_uv3, vertex->get_uvw(""));
}
if (vertex->has_normal()) {
vdef._norm_index = record_unique(_unique_norm, vertex->get_normal());
}
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::record_unique
// Access: Private
// Description: Records the indicated vertex value, returning the
// shared index if this value already appears elsewhere
// in the table, or the new unique index if this is the
// first time this value appears.
////////////////////////////////////////////////////////////////////
int EggToObjConverter::
record_unique(UniqueVertices &unique, const LVecBase4d &vec) {
// We record a zero-based index. Note that we will actually write
// out a one-based index to the obj file, as required by the
// standard.
int index = unique.size();
UniqueVertices::iterator ui = unique.insert(UniqueVertices::value_type(vec, index)).first;
return (*ui).second;
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::record_unique
// Access: Private
// Description: Records the indicated vertex value, returning the
// shared index if this value already appears elsewhere
// in the table, or the new unique index if this is the
// first time this value appears.
////////////////////////////////////////////////////////////////////
int EggToObjConverter::
record_unique(UniqueVertices &unique, const LVecBase3d &vec) {
return record_unique(unique, LVecBase4d(vec[0], vec[1], vec[2], 0.0));
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::record_unique
// Access: Private
// Description: Records the indicated vertex value, returning the
// shared index if this value already appears elsewhere
// in the table, or the new unique index if this is the
// first time this value appears.
////////////////////////////////////////////////////////////////////
int EggToObjConverter::
record_unique(UniqueVertices &unique, const LVecBase2d &vec) {
return record_unique(unique, LVecBase4d(vec[0], vec[1], 0.0, 0.0));
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::record_unique
// Access: Private
// Description: Records the indicated vertex value, returning the
// shared index if this value already appears elsewhere
// in the table, or the new unique index if this is the
// first time this value appears.
////////////////////////////////////////////////////////////////////
int EggToObjConverter::
record_unique(UniqueVertices &unique, double pos) {
return record_unique(unique, LVecBase4d(pos, 0.0, 0.0, 0.0));
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::write_vertices
// Access: Private
// Description: Actually writes the vertex values recorded in the
// indicated table to the obj output stream.
////////////////////////////////////////////////////////////////////
void EggToObjConverter::
write_vertices(ostream &out, const string &prefix, int num_components,
const UniqueVertices &unique) {
// First, sort the list into numeric order.
int num_vertices = (int)unique.size();
const LVecBase4d **vertices = (const LVecBase4d **)PANDA_MALLOC_ARRAY(num_vertices * sizeof(LVecBase4d *));
memset(vertices, 0, num_vertices * sizeof(LVecBase4d *));
UniqueVertices::const_iterator ui;
for (ui = unique.begin(); ui != unique.end(); ++ui) {
int index = (*ui).second;
const LVecBase4d &vec = (*ui).first;
nassertv(index >= 0 && index < num_vertices);
nassertv(vertices[index] == NULL);
vertices[index] = &vec;
}
for (int i = 0; i < num_vertices; ++i) {
out << prefix;
const LVecBase4d &vec = *(vertices[i]);
for (int ci = 0; ci < num_components; ++ci) {
out << " " << vec[ci];
}
out << "\n";
}
PANDA_FREE_ARRAY(vertices);
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::VertexDef::Constructor
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
EggToObjConverter::VertexDef::
VertexDef() :
_vert3_index(-1),
_vert4_index(-1),
_uv2_index(-1),
_uv3_index(-1),
_norm_index(-1)
{
}
// Filename: eggToObjConverter.cxx
// Created by: drose (19Dec12)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#include "eggToObjConverter.h"
#include "config_objegg.h"
#include "config_egg.h"
#include "eggData.h"
#include "string_utils.h"
#include "streamReader.h"
#include "virtualFileSystem.h"
#include "eggPolygon.h"
#include "eggPoint.h"
#include "eggLine.h"
#include "dcast.h"
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
EggToObjConverter::
EggToObjConverter() {
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::Copy Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
EggToObjConverter::
EggToObjConverter(const EggToObjConverter &copy) :
EggToSomethingConverter(copy)
{
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
EggToObjConverter::
~EggToObjConverter() {
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::make_copy
// Access: Public, Virtual
// Description: Allocates and returns a new copy of the converter.
////////////////////////////////////////////////////////////////////
EggToSomethingConverter *EggToObjConverter::
make_copy() {
return new EggToObjConverter(*this);
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::get_name
// Access: Public, Virtual
// Description: Returns the English name of the file type this
// converter supports.
////////////////////////////////////////////////////////////////////
string EggToObjConverter::
get_name() const {
return "obj";
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::get_extension
// Access: Public, Virtual
// Description: Returns the common extension of the file type this
// converter supports.
////////////////////////////////////////////////////////////////////
string EggToObjConverter::
get_extension() const {
return "obj";
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::supports_compressed
// Access: Published, Virtual
// Description: Returns true if this file type can transparently save
// compressed files (with a .pz extension), false
// otherwise.
////////////////////////////////////////////////////////////////////
bool EggToObjConverter::
supports_compressed() const {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::write_file
// Access: Public, Virtual
// Description: Handles the conversion of the internal EggData to the
// target file format, written to the specified
// filename.
////////////////////////////////////////////////////////////////////
bool EggToObjConverter::
write_file(const Filename &filename) {
clear_error();
if (_egg_data->get_coordinate_system() == CS_default) {
_egg_data->set_coordinate_system(CS_zup_right);
}
if (!process(filename)) {
_error = true;
}
return !had_error();
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::process
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
bool EggToObjConverter::
process(const Filename &filename) {
_egg_data->flatten_transforms();
collect_vertices(_egg_data);
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
Filename obj_filename = Filename::text_filename(filename);
vfs->delete_file(obj_filename);
ostream *file = vfs->open_write_file(obj_filename, true, true);
if (file == (ostream *)NULL) {
return false;
}
if (egg_precision != 0) {
file->precision(egg_precision);
}
_current_group = NULL;
/*
(*file) << "\n#\n"
<< "# obj file generated by the following command:\n"
<< "# " << get_exec_command() << "\n"
<< "#\n\n";
*/
write_vertices(*file, "v", 3, _unique_vert3);
write_vertices(*file, "v", 4, _unique_vert4);
write_vertices(*file, "vt", 2, _unique_uv2);
write_vertices(*file, "vt", 3, _unique_uv3);
write_vertices(*file, "vn", 3, _unique_norm);
write_faces(*file, _egg_data);
bool success = (file != (ostream *)NULL);
vfs->close_write_file(file);
return success;
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::collect_vertices
// Access: Private
// Description: Recursively walks the egg structure, looking for
// vertices referenced by polygons or points. Any such
// vertices are added to the vertex tables for writing
// to the obj file.
////////////////////////////////////////////////////////////////////
void EggToObjConverter::
collect_vertices(EggNode *egg_node) {
if (egg_node->is_of_type(EggPrimitive::get_class_type())) {
EggPrimitive *egg_prim = DCAST(EggPrimitive, egg_node);
EggPrimitive::iterator pi;
for (pi = egg_prim->begin(); pi != egg_prim->end(); ++pi) {
record_vertex(*pi);
}
} else if (egg_node->is_of_type(EggGroupNode::get_class_type())) {
EggGroupNode *egg_group = DCAST(EggGroupNode, egg_node);
EggGroupNode::iterator ci;
for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
collect_vertices(*ci);
}
}
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::write_faces
// Access: Private
// Description: Recursively walks the egg structure again, this time
// writing out the face records for any polygons,
// points, or lines encountered.
////////////////////////////////////////////////////////////////////
void EggToObjConverter::
write_faces(ostream &out, EggNode *egg_node) {
if (egg_node->is_of_type(EggPrimitive::get_class_type())) {
const char *prim_type = NULL;
if (egg_node->is_of_type(EggPolygon::get_class_type())) {
prim_type = "f";
} else if (egg_node->is_of_type(EggPoint::get_class_type())) {
prim_type = "p";
} else if (egg_node->is_of_type(EggLine::get_class_type())) {
prim_type = "l";
}
if (prim_type != NULL) {
write_group_reference(out, egg_node);
EggPrimitive *egg_prim = DCAST(EggPrimitive, egg_node);
out << prim_type;
EggPrimitive::iterator pi;
for (pi = egg_prim->begin(); pi != egg_prim->end(); ++pi) {
VertexDef &vdef = _vmap[(*pi)];
int vert_index = -1;
int uv_index = -1;
int norm_index = -1;
if (vdef._vert3_index != -1) {
vert_index = vdef._vert3_index + 1;
} else if (vdef._vert4_index != -1) {
vert_index = vdef._vert4_index + 1 + (int)_unique_vert3.size();
}
if (vdef._uv2_index != -1) {
uv_index = vdef._uv2_index + 1;
} else if (vdef._uv3_index != -1) {
uv_index = vdef._uv3_index + 1 + (int)_unique_uv2.size();
}
if (vdef._norm_index != -1) {
norm_index = vdef._norm_index + 1;
}
if (vert_index == -1) {
continue;
}
if (norm_index != -1) {
if (uv_index != -1) {
out << " " << vert_index << "/" << uv_index << "/" << norm_index;
} else {
out << " " << vert_index << "//" << norm_index;
}
} else if (uv_index != -1) {
out << " " << vert_index << "/" << uv_index;
} else {
out << " " << vert_index;
}
}
out << "\n";
}
} else if (egg_node->is_of_type(EggGroupNode::get_class_type())) {
EggGroupNode *egg_group = DCAST(EggGroupNode, egg_node);
EggGroupNode::iterator ci;
for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
write_faces(out, *ci);
}
}
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::write_group_reference
// Access: Private
// Description: Writes the "g" tag to describe this polygon's group,
// if needed.
////////////////////////////////////////////////////////////////////
void EggToObjConverter::
write_group_reference(ostream &out, EggNode *egg_node) {
EggGroupNode *egg_group = egg_node->get_parent();
if (egg_group == _current_group) {
// Same group we wrote last time.
return;
}
string group_name;
get_group_name(group_name, egg_group);
if (group_name.empty()) {
out << "g default\n";
} else {
out << "g" << group_name << "\n";
}
_current_group = egg_group;
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::get_group_name
// Access: Private
// Description: Recursively determines the appropriate string to
// write for the "g" tag to describe a particular
// EggGroupNode.
////////////////////////////////////////////////////////////////////
void EggToObjConverter::
get_group_name(string &group_name, EggGroupNode *egg_group) {
string name = trim(egg_group->get_name());
if (!name.empty()) {
group_name += ' ';
// Remove nonstandard characters.
for (string::const_iterator ni = name.begin(); ni != name.end(); ++ni) {
char c = (*ni);
if (!isalnum(c)) {
c = '_';
}
group_name += c;
}
}
// Now recurse.
EggGroupNode *egg_parent = egg_group->get_parent();
if (egg_parent != NULL) {
get_group_name(group_name, egg_parent);
}
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::record_vertex
// Access: Private
// Description: Adds the indicated EggVertex to the unique vertex
// tables, for writing later by write_vertices().
////////////////////////////////////////////////////////////////////
void EggToObjConverter::
record_vertex(EggVertex *vertex) {
VertexDef &vdef = _vmap[vertex];
switch (vertex->get_num_dimensions()) {
case 1:
vdef._vert3_index = record_unique(_unique_vert3, vertex->get_pos1());
break;
case 2:
vdef._vert3_index = record_unique(_unique_vert3, vertex->get_pos2());
break;
case 3:
vdef._vert3_index = record_unique(_unique_vert3, vertex->get_pos3());
break;
case 4:
vdef._vert4_index = record_unique(_unique_vert4, vertex->get_pos4());
break;
}
if (vertex->has_uv("")) {
vdef._uv2_index = record_unique(_unique_uv2, vertex->get_uv(""));
} else if (vertex->has_uvw("")) {
vdef._uv3_index = record_unique(_unique_uv3, vertex->get_uvw(""));
}
if (vertex->has_normal()) {
vdef._norm_index = record_unique(_unique_norm, vertex->get_normal());
}
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::record_unique
// Access: Private
// Description: Records the indicated vertex value, returning the
// shared index if this value already appears elsewhere
// in the table, or the new unique index if this is the
// first time this value appears.
////////////////////////////////////////////////////////////////////
int EggToObjConverter::
record_unique(UniqueVertices &unique, const LVecBase4d &vec) {
// We record a zero-based index. Note that we will actually write
// out a one-based index to the obj file, as required by the
// standard.
int index = unique.size();
UniqueVertices::iterator ui = unique.insert(UniqueVertices::value_type(vec, index)).first;
return (*ui).second;
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::record_unique
// Access: Private
// Description: Records the indicated vertex value, returning the
// shared index if this value already appears elsewhere
// in the table, or the new unique index if this is the
// first time this value appears.
////////////////////////////////////////////////////////////////////
int EggToObjConverter::
record_unique(UniqueVertices &unique, const LVecBase3d &vec) {
return record_unique(unique, LVecBase4d(vec[0], vec[1], vec[2], 0.0));
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::record_unique
// Access: Private
// Description: Records the indicated vertex value, returning the
// shared index if this value already appears elsewhere
// in the table, or the new unique index if this is the
// first time this value appears.
////////////////////////////////////////////////////////////////////
int EggToObjConverter::
record_unique(UniqueVertices &unique, const LVecBase2d &vec) {
return record_unique(unique, LVecBase4d(vec[0], vec[1], 0.0, 0.0));
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::record_unique
// Access: Private
// Description: Records the indicated vertex value, returning the
// shared index if this value already appears elsewhere
// in the table, or the new unique index if this is the
// first time this value appears.
////////////////////////////////////////////////////////////////////
int EggToObjConverter::
record_unique(UniqueVertices &unique, double pos) {
return record_unique(unique, LVecBase4d(pos, 0.0, 0.0, 0.0));
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::write_vertices
// Access: Private
// Description: Actually writes the vertex values recorded in the
// indicated table to the obj output stream.
////////////////////////////////////////////////////////////////////
void EggToObjConverter::
write_vertices(ostream &out, const string &prefix, int num_components,
const UniqueVertices &unique) {
// First, sort the list into numeric order.
int num_vertices = (int)unique.size();
const LVecBase4d **vertices = (const LVecBase4d **)PANDA_MALLOC_ARRAY(num_vertices * sizeof(LVecBase4d *));
memset(vertices, 0, num_vertices * sizeof(LVecBase4d *));
UniqueVertices::const_iterator ui;
for (ui = unique.begin(); ui != unique.end(); ++ui) {
int index = (*ui).second;
const LVecBase4d &vec = (*ui).first;
nassertv(index >= 0 && index < num_vertices);
nassertv(vertices[index] == NULL);
vertices[index] = &vec;
}
for (int i = 0; i < num_vertices; ++i) {
out << prefix;
const LVecBase4d &vec = *(vertices[i]);
for (int ci = 0; ci < num_components; ++ci) {
out << " " << vec[ci];
}
out << "\n";
}
PANDA_FREE_ARRAY(vertices);
}
////////////////////////////////////////////////////////////////////
// Function: EggToObjConverter::VertexDef::Constructor
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
EggToObjConverter::VertexDef::
VertexDef() :
_vert3_index(-1),
_vert4_index(-1),
_uv2_index(-1),
_uv3_index(-1),
_norm_index(-1)
{
}

File diff suppressed because it is too large Load Diff

View File

@ -1,152 +1,152 @@
// Filename: ObjToEggConverter.h
// Created by: drose (07Dec10)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#ifndef OBJTOEGGCONVERTER_H
#define OBJTOEGGCONVERTER_H
#include "pandatoolbase.h"
#include "somethingToEggConverter.h"
#include "eggVertexPool.h"
#include "eggGroup.h"
#include "geomVertexData.h"
#include "geomVertexWriter.h"
#include "geomPrimitive.h"
#include "geomNode.h"
#include "pandaNode.h"
#include "pvector.h"
#include "epvector.h"
////////////////////////////////////////////////////////////////////
// Class : ObjToEggConverter
// Description : Convert an Obj file to egg data.
////////////////////////////////////////////////////////////////////
class ObjToEggConverter : public SomethingToEggConverter {
public:
ObjToEggConverter();
ObjToEggConverter(const ObjToEggConverter &copy);
~ObjToEggConverter();
virtual SomethingToEggConverter *make_copy();
virtual string get_name() const;
virtual string get_extension() const;
virtual bool supports_compressed() const;
virtual bool supports_convert_to_node(const LoaderOptions &options) const;
virtual bool convert_file(const Filename &filename);
virtual PT(PandaNode) convert_to_node(const LoaderOptions &options, const Filename &filename);
protected:
bool process(const Filename &filename);
bool process_line(const string &line);
bool process_ref_plane_res(const string &line);
bool process_v(vector_string &words);
bool process_vt(vector_string &words);
bool process_xvt(vector_string &words);
bool process_xvc(vector_string &words);
bool process_vn(vector_string &words);
bool process_f(vector_string &words);
bool process_g(vector_string &words);
EggVertex *get_face_vertex(const string &face_reference);
void generate_egg_points();
bool process_node(const Filename &filename);
bool process_line_node(const string &line);
bool process_f_node(vector_string &words);
bool process_g_node(vector_string &words);
void generate_points();
int add_synth_normal(const LVecBase3d &normal);
// Read from the obj file.
int _line_number;
typedef epvector<LVecBase4d> Vec4Table;
typedef epvector<LVecBase3d> Vec3Table;
typedef epvector<LVecBase2d> Vec2Table;
typedef pmap<LVecBase3d, int> UniqueVec3Table;
Vec4Table _v_table;
Vec3Table _vn_table, _rgb_table;
Vec3Table _vt_table;
Vec2Table _xvt_table;
Vec3Table _synth_vn_table;
UniqueVec3Table _unique_synth_vn_table;
LVecBase2d _ref_plane_res;
bool _v4_given, _vt3_given;
bool _f_given;
pset<string> _ignored_tags;
// Structures filled when creating an egg file.
PT(EggVertexPool) _vpool;
PT(EggGroup) _root_group;
EggGroup *_current_group;
// Structures filled when creating a PandaNode directly.
PT(PandaNode) _root_node;
class VertexEntry {
public:
VertexEntry();
VertexEntry(const ObjToEggConverter *converter, const string &obj_vertex);
INLINE bool operator < (const VertexEntry &other) const;
INLINE bool operator == (const VertexEntry &other) const;
INLINE bool matches_except_normal(const VertexEntry &other) const;
// The 1-based vertex, texcoord, and normal index numbers
// appearing in the obj file for this vertex. 0 if the index
// number is not given.
int _vi, _vti, _vni;
// The 1-based index number to the synthesized normal, if needed.
int _synth_vni;
};
typedef pmap<VertexEntry, int> UniqueVertexEntries;
typedef pvector<VertexEntry> VertexEntries;
class VertexData {
public:
VertexData(PandaNode *parent, const string &name);
int add_vertex(const ObjToEggConverter *converter, const VertexEntry &entry);
void add_triangle(const ObjToEggConverter *converter, const VertexEntry &v0,
const VertexEntry &v1, const VertexEntry &v2,
int synth_vni);
void close_geom(const ObjToEggConverter *converter);
PT(PandaNode) _parent;
string _name;
PT(GeomNode) _geom_node;
PT(GeomPrimitive) _prim;
VertexEntries _entries;
UniqueVertexEntries _unique_entries;
bool _v4_given, _vt3_given;
bool _vt_given, _rgb_given, _vn_given;
};
VertexData *_current_vertex_data;
friend class VertexData;
};
#include "objToEggConverter.I"
#endif
// Filename: ObjToEggConverter.h
// Created by: drose (07Dec10)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#ifndef OBJTOEGGCONVERTER_H
#define OBJTOEGGCONVERTER_H
#include "pandatoolbase.h"
#include "somethingToEggConverter.h"
#include "eggVertexPool.h"
#include "eggGroup.h"
#include "geomVertexData.h"
#include "geomVertexWriter.h"
#include "geomPrimitive.h"
#include "geomNode.h"
#include "pandaNode.h"
#include "pvector.h"
#include "epvector.h"
////////////////////////////////////////////////////////////////////
// Class : ObjToEggConverter
// Description : Convert an Obj file to egg data.
////////////////////////////////////////////////////////////////////
class ObjToEggConverter : public SomethingToEggConverter {
public:
ObjToEggConverter();
ObjToEggConverter(const ObjToEggConverter &copy);
~ObjToEggConverter();
virtual SomethingToEggConverter *make_copy();
virtual string get_name() const;
virtual string get_extension() const;
virtual bool supports_compressed() const;
virtual bool supports_convert_to_node(const LoaderOptions &options) const;
virtual bool convert_file(const Filename &filename);
virtual PT(PandaNode) convert_to_node(const LoaderOptions &options, const Filename &filename);
protected:
bool process(const Filename &filename);
bool process_line(const string &line);
bool process_ref_plane_res(const string &line);
bool process_v(vector_string &words);
bool process_vt(vector_string &words);
bool process_xvt(vector_string &words);
bool process_xvc(vector_string &words);
bool process_vn(vector_string &words);
bool process_f(vector_string &words);
bool process_g(vector_string &words);
EggVertex *get_face_vertex(const string &face_reference);
void generate_egg_points();
bool process_node(const Filename &filename);
bool process_line_node(const string &line);
bool process_f_node(vector_string &words);
bool process_g_node(vector_string &words);
void generate_points();
int add_synth_normal(const LVecBase3d &normal);
// Read from the obj file.
int _line_number;
typedef epvector<LVecBase4d> Vec4Table;
typedef epvector<LVecBase3d> Vec3Table;
typedef epvector<LVecBase2d> Vec2Table;
typedef pmap<LVecBase3d, int> UniqueVec3Table;
Vec4Table _v_table;
Vec3Table _vn_table, _rgb_table;
Vec3Table _vt_table;
Vec2Table _xvt_table;
Vec3Table _synth_vn_table;
UniqueVec3Table _unique_synth_vn_table;
LVecBase2d _ref_plane_res;
bool _v4_given, _vt3_given;
bool _f_given;
pset<string> _ignored_tags;
// Structures filled when creating an egg file.
PT(EggVertexPool) _vpool;
PT(EggGroup) _root_group;
EggGroup *_current_group;
// Structures filled when creating a PandaNode directly.
PT(PandaNode) _root_node;
class VertexEntry {
public:
VertexEntry();
VertexEntry(const ObjToEggConverter *converter, const string &obj_vertex);
INLINE bool operator < (const VertexEntry &other) const;
INLINE bool operator == (const VertexEntry &other) const;
INLINE bool matches_except_normal(const VertexEntry &other) const;
// The 1-based vertex, texcoord, and normal index numbers
// appearing in the obj file for this vertex. 0 if the index
// number is not given.
int _vi, _vti, _vni;
// The 1-based index number to the synthesized normal, if needed.
int _synth_vni;
};
typedef pmap<VertexEntry, int> UniqueVertexEntries;
typedef pvector<VertexEntry> VertexEntries;
class VertexData {
public:
VertexData(PandaNode *parent, const string &name);
int add_vertex(const ObjToEggConverter *converter, const VertexEntry &entry);
void add_triangle(const ObjToEggConverter *converter, const VertexEntry &v0,
const VertexEntry &v1, const VertexEntry &v2,
int synth_vni);
void close_geom(const ObjToEggConverter *converter);
PT(PandaNode) _parent;
string _name;
PT(GeomNode) _geom_node;
PT(GeomPrimitive) _prim;
VertexEntries _entries;
UniqueVertexEntries _unique_entries;
bool _v4_given, _vt3_given;
bool _vt_given, _rgb_given, _vn_given;
};
VertexData *_current_vertex_data;
friend class VertexData;
};
#include "objToEggConverter.I"
#endif