more work on egg loader with new geom format
This commit is contained in:
parent
fc2592fabb
commit
4af9b7b882
|
|
@ -10,9 +10,9 @@ for Panda tools. A number of utilities are provided that read and
|
|||
write egg files, for instance to convert to or from some other
|
||||
modeling format, or to apply a transform or optimize vertices. The
|
||||
egg file philosophy is to describe objects in an abstract way that
|
||||
facilitates easy manipulation; thus, the format doesn't include
|
||||
information such as polygon connectivity or triangle meshes. Egg
|
||||
files are furthermore designed to be human-readable to help a
|
||||
facilitates easy manipulation; thus, the format doesn't (usually)
|
||||
include information such as polygon connectivity or triangle meshes.
|
||||
Egg files are furthermore designed to be human-readable to help a
|
||||
developer diagnose (and sometimes repair) problems. Also, the egg
|
||||
syntax is always intended to be backward compatible with previous
|
||||
versions, so that as the egg syntax is extended, old egg files will
|
||||
|
|
@ -717,6 +717,59 @@ GEOMETRY ENTRIES
|
|||
draw_order, and the "thick" attribute are all valid.
|
||||
|
||||
|
||||
<TriangleStrip> name {
|
||||
[attributes]
|
||||
<VertexRef> {
|
||||
indices
|
||||
<Ref> { pool-name }
|
||||
}
|
||||
[component attributes]
|
||||
}
|
||||
|
||||
A triangle strip is only rarely encountered in an egg file; it is
|
||||
normally generated automatically only during load time, when
|
||||
connected triangles are automatically meshed for loading, and even
|
||||
then it exists only momentarily. Since a triangle strip is a
|
||||
rendering optimization only and adds no useful scene information
|
||||
over a loose collection of triangles, its usage is contrary to the
|
||||
general egg philosophy of representing a scene in the abstract.
|
||||
Nevertheless, the syntax exists, primarily to allow inspection of
|
||||
the meshing results when needed. You can also add custom
|
||||
TriangleStrip entries to force a particular mesh arrangement.
|
||||
|
||||
A triangle strip is defined as a series of connected triangles.
|
||||
After the first three vertices, which define the first triangle,
|
||||
each new vertex defines one additional triangle, by alternating up
|
||||
and down.
|
||||
|
||||
It is possible for the individual triangles of a triangle strip to
|
||||
have a separate normal and/or color. If so, a <Component> entry
|
||||
should be given for each so-modified triangle:
|
||||
|
||||
<Component> index {
|
||||
<RGBA> { r g b a [morph-list] }
|
||||
<Normal> { x y z [morph-list] }
|
||||
}
|
||||
|
||||
Where index ranges from 0 to the number of components defined by the
|
||||
triangle strip (less 1). Note that the component attribute list
|
||||
must always follow the vertex list.
|
||||
|
||||
|
||||
<TriangleFan> name {
|
||||
[attributes]
|
||||
<VertexRef> {
|
||||
indices
|
||||
<Ref> { pool-name }
|
||||
}
|
||||
[component attributes]
|
||||
}
|
||||
|
||||
A triangle fan is similar to a triangle strip, except all of the
|
||||
connected triangles share the same vertex, which is the first
|
||||
vertex. See <TriangleStrip>, above.
|
||||
|
||||
|
||||
|
||||
PARAMETRIC DESCRIPTION ENTRIES
|
||||
|
||||
|
|
|
|||
|
|
@ -13,24 +13,32 @@
|
|||
#define SOURCES \
|
||||
config_egg.h eggAnimData.I eggAnimData.h eggAttributes.I \
|
||||
eggAttributes.h eggBin.h eggBinMaker.h eggComment.I \
|
||||
eggComment.h eggCoordinateSystem.I eggCoordinateSystem.h \
|
||||
eggComment.h \
|
||||
eggCompositePrimitive.I eggCompositePrimitive.h \
|
||||
eggCoordinateSystem.I eggCoordinateSystem.h \
|
||||
eggCurve.I eggCurve.h eggData.I eggData.h \
|
||||
eggExternalReference.I eggExternalReference.h \
|
||||
eggFilenameNode.I eggFilenameNode.h eggGroup.I eggGroup.h \
|
||||
eggGroupNode.I eggGroupNode.h eggGroupUniquifier.h \
|
||||
eggLine.I eggLine.h \
|
||||
eggMaterial.I eggMaterial.h eggMaterialCollection.I \
|
||||
eggMaterialCollection.h eggMiscFuncs.I eggMiscFuncs.h \
|
||||
eggMaterialCollection.h \
|
||||
eggMesher.h eggMesher.I \
|
||||
eggMesherEdge.h eggMesherEdge.I \
|
||||
eggMesherStrip.h eggMesherStrip.I \
|
||||
eggMiscFuncs.I eggMiscFuncs.h \
|
||||
eggMorph.I eggMorph.h eggMorphList.I eggMorphList.h \
|
||||
eggNamedObject.I eggNamedObject.h eggNameUniquifier.h \
|
||||
eggNode.I eggNode.h eggNurbsCurve.I eggNurbsCurve.h \
|
||||
eggNurbsSurface.I eggNurbsSurface.h eggObject.I eggObject.h \
|
||||
eggParameters.h eggPoint.I eggPoint.h eggPolygon.I \
|
||||
eggPolygon.h eggPolysetMaker.h eggPoolUniquifier.h eggPrimitive.I \
|
||||
eggPrimitive.h eggRenderMode.I eggRenderMode.h \
|
||||
eggPolygon.h eggPolysetMaker.h eggPoolUniquifier.h \
|
||||
eggPrimitive.I eggPrimitive.h \
|
||||
eggRenderMode.I eggRenderMode.h \
|
||||
eggSAnimData.I eggSAnimData.h eggSurface.I eggSurface.h \
|
||||
eggSwitchCondition.h eggTable.I eggTable.h eggTexture.I \
|
||||
eggTexture.h eggTextureCollection.I eggTextureCollection.h \
|
||||
eggTriangleStrip.I eggTriangleStrip.h \
|
||||
eggTransform3d.I eggTransform3d.h \
|
||||
eggUserData.I eggUserData.h \
|
||||
eggUtilities.I eggUtilities.h \
|
||||
|
|
@ -44,11 +52,17 @@
|
|||
|
||||
#define INCLUDED_SOURCES \
|
||||
config_egg.cxx eggAnimData.cxx eggAttributes.cxx eggBin.cxx \
|
||||
eggBinMaker.cxx eggComment.cxx eggCoordinateSystem.cxx \
|
||||
eggBinMaker.cxx eggComment.cxx \
|
||||
eggCompositePrimitive.cxx \
|
||||
eggCoordinateSystem.cxx \
|
||||
eggCurve.cxx eggData.cxx eggExternalReference.cxx \
|
||||
eggFilenameNode.cxx eggGroup.cxx eggGroupNode.cxx \
|
||||
eggGroupUniquifier.cxx eggLine.cxx eggMaterial.cxx \
|
||||
eggMaterialCollection.cxx eggMiscFuncs.cxx eggMorphList.cxx \
|
||||
eggMaterialCollection.cxx \
|
||||
eggMesher.cxx \
|
||||
eggMesherEdge.cxx \
|
||||
eggMesherStrip.cxx \
|
||||
eggMiscFuncs.cxx eggMorphList.cxx \
|
||||
eggNamedObject.cxx eggNameUniquifier.cxx eggNode.cxx \
|
||||
eggNurbsCurve.cxx eggNurbsSurface.cxx eggObject.cxx \
|
||||
eggParameters.cxx eggPoint.cxx eggPolygon.cxx eggPolysetMaker.cxx \
|
||||
|
|
@ -56,6 +70,7 @@
|
|||
eggSAnimData.cxx eggSurface.cxx eggSwitchCondition.cxx \
|
||||
eggTable.cxx eggTexture.cxx eggTextureCollection.cxx \
|
||||
eggTransform3d.cxx \
|
||||
eggTriangleStrip.cxx \
|
||||
eggUserData.cxx \
|
||||
eggUtilities.cxx eggVertex.cxx eggVertexPool.cxx eggVertexUV.cxx \
|
||||
eggXfmAnimData.cxx eggXfmSAnim.cxx xx xx pt_EggMaterial.cxx \
|
||||
|
|
@ -66,7 +81,9 @@
|
|||
#define INSTALL_HEADERS \
|
||||
eggAnimData.I eggAnimData.h \
|
||||
eggAttributes.I eggAttributes.h eggBin.h eggBinMaker.h eggComment.I \
|
||||
eggComment.h eggCoordinateSystem.I eggCoordinateSystem.h eggCurve.I \
|
||||
eggComment.h \
|
||||
eggCompositePrimitive.I eggCompositePrimitive.h \
|
||||
eggCoordinateSystem.I eggCoordinateSystem.h eggCurve.I \
|
||||
eggCurve.h eggData.I eggData.h eggExternalReference.I \
|
||||
eggExternalReference.h eggFilenameNode.I eggFilenameNode.h \
|
||||
eggGroup.I eggGroup.h eggGroupNode.I eggGroupNode.h \
|
||||
|
|
@ -84,6 +101,7 @@
|
|||
eggSwitchCondition.h eggTable.I eggTable.h eggTexture.I \
|
||||
eggTexture.h eggTextureCollection.I eggTextureCollection.h \
|
||||
eggTransform3d.I eggTransform3d.h \
|
||||
eggTriangleStrip.I eggTriangleStrip.h \
|
||||
eggUserData.I eggUserData.h \
|
||||
eggUtilities.I eggUtilities.h eggVertex.I eggVertex.h \
|
||||
eggVertexPool.I eggVertexPool.h \
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include "eggBin.h"
|
||||
#include "eggBinMaker.h"
|
||||
#include "eggComment.h"
|
||||
#include "eggCompositePrimitive.h"
|
||||
#include "eggCoordinateSystem.h"
|
||||
#include "eggCurve.h"
|
||||
#include "eggExternalReference.h"
|
||||
|
|
@ -46,6 +47,7 @@
|
|||
#include "eggSwitchCondition.h"
|
||||
#include "eggTable.h"
|
||||
#include "eggTexture.h"
|
||||
#include "eggTriangleStrip.h"
|
||||
#include "eggUserData.h"
|
||||
#include "eggVertex.h"
|
||||
#include "eggVertexPool.h"
|
||||
|
|
@ -64,13 +66,36 @@ ConfigureFn(config_egg) {
|
|||
|
||||
ConfigVariableSearchPath egg_path
|
||||
("egg-path",
|
||||
"The search path along which only egg files are searched. Generally, you "
|
||||
"should use model-path instead of egg-path.");
|
||||
PRC_DESC("The search path along which only egg files are searched. Generally, you "
|
||||
"should use model-path instead of egg-path."));
|
||||
|
||||
ConfigVariableBool egg_support_old_anims
|
||||
("egg-support-old-anims", true,
|
||||
"Set this true to support loading of old character animation files, which "
|
||||
"had the convention that the order \"phr\" implied a reversed roll.");
|
||||
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);
|
||||
ConfigVariableBool egg_retesselate_coplanar
|
||||
("egg-retesselate-coplanar", true);
|
||||
ConfigVariableBool egg_unroll_fans
|
||||
("egg-unroll-fans", true);
|
||||
ConfigVariableBool egg_show_tstrips
|
||||
("egg-show-tstrips", false);
|
||||
ConfigVariableBool egg_show_qsheets
|
||||
("egg-show-qsheets", false);
|
||||
ConfigVariableBool egg_show_quads
|
||||
("egg-show-quads", false);
|
||||
ConfigVariableBool egg_subdivide_polys
|
||||
("egg-subdivide-polys", true);
|
||||
ConfigVariableBool egg_consider_fans
|
||||
("egg-consider-fans", true);
|
||||
ConfigVariableDouble egg_max_tfan_angle
|
||||
("egg-max-tfan-angle", 40.0);
|
||||
ConfigVariableInt egg_min_tfan_tris
|
||||
("egg-min-tfan-tris", 4);
|
||||
ConfigVariableDouble egg_coplanar_threshold
|
||||
("egg-coplanar-threshold", 0.01);
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: init_libegg
|
||||
|
|
@ -94,6 +119,7 @@ init_libegg() {
|
|||
EggBin::init_type();
|
||||
EggBinMaker::init_type();
|
||||
EggComment::init_type();
|
||||
EggCompositePrimitive::init_type();
|
||||
EggCoordinateSystem::init_type();
|
||||
EggCurve::init_type();
|
||||
EggData::init_type();
|
||||
|
|
@ -119,6 +145,7 @@ init_libegg() {
|
|||
EggSwitchConditionDistance::init_type();
|
||||
EggTable::init_type();
|
||||
EggTexture::init_type();
|
||||
EggTriangleStrip::init_type();
|
||||
EggUserData::init_type();
|
||||
EggVertex::init_type();
|
||||
EggVertexPool::init_type();
|
||||
|
|
|
|||
|
|
@ -23,12 +23,28 @@
|
|||
#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 ConfigVariableSearchPath egg_path;
|
||||
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 void init_libegg();
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggAttributes::has_normal
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool EggAttributes::
|
||||
|
|
@ -29,7 +29,7 @@ has_normal() const {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggAttributes::get_normal
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const Normald &EggAttributes::
|
||||
|
|
@ -40,7 +40,7 @@ get_normal() const {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggAttributes::set_normal
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void EggAttributes::
|
||||
|
|
@ -51,7 +51,7 @@ set_normal(const Normald &normal) {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggAttributes::clear_normal
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void EggAttributes::
|
||||
|
|
@ -61,7 +61,7 @@ clear_normal() {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggAttributes::has_color
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool EggAttributes::
|
||||
|
|
@ -71,7 +71,7 @@ has_color() const {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggAttributes::get_color
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description: Returns the color set on this particular attribute.
|
||||
// If there is no color set, returns white.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -86,7 +86,7 @@ get_color() const {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggAttributes::
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void EggAttributes::
|
||||
|
|
@ -97,10 +97,22 @@ set_color(const Colorf &color) {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggAttributes::
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void EggAttributes::
|
||||
clear_color() {
|
||||
_flags &= ~F_has_color;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggAttributes::sorts_less_than
|
||||
// Access: Published
|
||||
// Description: An ordering operator to compare two vertices for
|
||||
// sorting order. This imposes an arbitrary ordering
|
||||
// useful to identify unique vertices.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool EggAttributes::
|
||||
sorts_less_than(const EggAttributes &other) const {
|
||||
return compare_to(other) < 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,14 +22,13 @@
|
|||
#include "eggMorphList.h"
|
||||
|
||||
#include "indent.h"
|
||||
#include <math.h>
|
||||
|
||||
TypeHandle EggAttributes::_type_handle;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggAttributes::Constructor
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
EggAttributes::
|
||||
|
|
@ -39,7 +38,7 @@ EggAttributes() {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggAttributes::Copy constructor
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
EggAttributes::
|
||||
|
|
@ -49,7 +48,7 @@ EggAttributes(const EggAttributes ©) {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggAttributes::Copy assignment operator
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
EggAttributes &EggAttributes::
|
||||
|
|
@ -64,7 +63,7 @@ operator = (const EggAttributes ©) {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggAttributes::Destructor
|
||||
// Access: Public, Virtual
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
EggAttributes::
|
||||
|
|
@ -74,7 +73,7 @@ EggAttributes::
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggAttributes::write
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description: Writes the attributes to the indicated output stream in
|
||||
// Egg format.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -106,26 +105,27 @@ write(ostream &out, int indent_level) const {
|
|||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggAttributes::sorts_less_than
|
||||
// Access: Public
|
||||
// Function: EggAttributes::compare_to
|
||||
// Access: Published
|
||||
// Description: An ordering operator to compare two vertices for
|
||||
// sorting order. This imposes an arbitrary ordering
|
||||
// useful to identify unique vertices.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool EggAttributes::
|
||||
sorts_less_than(const EggAttributes &other) const {
|
||||
int EggAttributes::
|
||||
compare_to(const EggAttributes &other) const {
|
||||
if (_flags != other._flags) {
|
||||
return _flags < other._flags;
|
||||
return (int)_flags - (int)other._flags;
|
||||
}
|
||||
|
||||
if (has_normal()) {
|
||||
int compare =
|
||||
_normal.compare_to(other._normal, egg_parameters->_normal_threshold);
|
||||
if (compare != 0) {
|
||||
return compare < 0;
|
||||
return compare;
|
||||
}
|
||||
if (_dnormals != other._dnormals) {
|
||||
return _dnormals < other._dnormals;
|
||||
compare = _dnormals.compare_to(other._dnormals);
|
||||
if (compare != 0) {
|
||||
return compare;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -133,19 +133,20 @@ sorts_less_than(const EggAttributes &other) const {
|
|||
int compare =
|
||||
_color.compare_to(other._color, egg_parameters->_color_threshold);
|
||||
if (compare != 0) {
|
||||
return compare < 0;
|
||||
return compare;
|
||||
}
|
||||
if (_drgbas != other._drgbas) {
|
||||
return _drgbas < other._drgbas;
|
||||
compare = _drgbas.compare_to(other._drgbas);
|
||||
if (compare != 0) {
|
||||
return compare;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggAttributes::transform
|
||||
// Access: Public, Virtual
|
||||
// Access: Published, Virtual
|
||||
// Description: Applies the indicated transformation matrix to the
|
||||
// attributes.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -56,7 +56,8 @@ PUBLISHED:
|
|||
INLINE void clear_color();
|
||||
|
||||
void write(ostream &out, int indent_level) const;
|
||||
bool sorts_less_than(const EggAttributes &other) const;
|
||||
INLINE bool sorts_less_than(const EggAttributes &other) const;
|
||||
int compare_to(const EggAttributes &other) const;
|
||||
|
||||
void transform(const LMatrix4d &mat);
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,106 @@
|
|||
// Filename: eggCompositePrimitive.I
|
||||
// Created by: drose (13Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggCompositePrimitive::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE EggCompositePrimitive::
|
||||
EggCompositePrimitive(const string &name) : EggPrimitive(name) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggCompositePrimitive::Copy constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE EggCompositePrimitive::
|
||||
EggCompositePrimitive(const EggCompositePrimitive ©) : EggPrimitive(copy) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggCompositePrimitive::Destructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE EggCompositePrimitive::
|
||||
~EggCompositePrimitive() {
|
||||
clear();
|
||||
nassertv(_components.empty());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggCompositePrimitive::Copy assignment operator
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE EggCompositePrimitive &EggCompositePrimitive::
|
||||
operator = (const EggCompositePrimitive ©) {
|
||||
EggPrimitive::operator = (copy);
|
||||
return *this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggCompositePrimitive::get_num_components
|
||||
// Access: Published
|
||||
// Description: Returns the number of individual component triangles
|
||||
// within the composite. Each one of these might have a
|
||||
// different set of attributes.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int EggCompositePrimitive::
|
||||
get_num_components() const {
|
||||
return _components.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggCompositePrimitive::get_component
|
||||
// Access: Published
|
||||
// Description: Returns the attributes for the nth component
|
||||
// triangle.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const EggAttributes *EggCompositePrimitive::
|
||||
get_component(int i) const {
|
||||
nassertr(i >= 0 && i < (int)_components.size(), NULL);
|
||||
return _components[i];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggCompositePrimitive::get_component
|
||||
// Access: Published
|
||||
// Description: Returns the attributes for the nth component
|
||||
// triangle.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE EggAttributes *EggCompositePrimitive::
|
||||
get_component(int i) {
|
||||
nassertr(i >= 0 && i < (int)_components.size(), NULL);
|
||||
return _components[i];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggCompositePrimitive::set_component
|
||||
// Access: Published
|
||||
// Description: Changes the attributes for the nth component
|
||||
// triangle.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void EggCompositePrimitive::
|
||||
set_component(int i, const EggAttributes *attrib) {
|
||||
nassertv(i >= 0 && i < (int)_components.size());
|
||||
_components[i] = new EggAttributes(*attrib);
|
||||
}
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
// Filename: eggCompositePrimitive.cxx
|
||||
// Created by: drose (13Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "eggCompositePrimitive.h"
|
||||
|
||||
TypeHandle EggCompositePrimitive::_type_handle;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggCompositePrimitive::triangulate_in_place
|
||||
// Access: Published
|
||||
// Description: Subdivides the composite primitive into triangles and
|
||||
// adds those triangles to the parent group node in
|
||||
// place of the original primitive. Returns a pointer
|
||||
// to the original primitive, which is likely about to
|
||||
// be destructed.
|
||||
//
|
||||
// If convex_also is true, both concave and convex
|
||||
// polygons will be subdivided into triangles;
|
||||
// otherwise, only concave polygons will be subdivided,
|
||||
// and convex polygons will be copied unchanged into the
|
||||
// container.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(EggCompositePrimitive) EggCompositePrimitive::
|
||||
triangulate_in_place() {
|
||||
EggGroupNode *parent = get_parent();
|
||||
nassertr(parent != (EggGroupNode *)NULL, this);
|
||||
|
||||
PT(EggCompositePrimitive) save_me = this;
|
||||
parent->remove_child(this);
|
||||
do_triangulate(parent);
|
||||
|
||||
return save_me;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggCompositePrimitive::prepare_add_vertex
|
||||
// Access: Protected, Virtual
|
||||
// Description: Marks the vertex as belonging to the primitive. This
|
||||
// is an internal function called by the STL-like
|
||||
// functions push_back() and insert(), in preparation
|
||||
// for actually adding the vertex.
|
||||
//
|
||||
// i indicates the new position of the vertex in the
|
||||
// list; n indicates the new number of vertices after
|
||||
// the operation has completed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggCompositePrimitive::
|
||||
prepare_add_vertex(EggVertex *vertex, int i, int n) {
|
||||
EggPrimitive::prepare_add_vertex(vertex, i, n);
|
||||
|
||||
if (n >= 3) {
|
||||
i = max(i - 2, 0);
|
||||
nassertv(i <= (int)_components.size());
|
||||
_components.insert(_components.begin() + i, new EggAttributes(*this));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggCompositePrimitive::prepare_remove_vertex
|
||||
// Access: Protected, Virtual
|
||||
// Description: Marks the vertex as removed from the primitive. This
|
||||
// is an internal function called by the STL-like
|
||||
// functions pop_back() and erase(), in preparation for
|
||||
// actually doing the removal.
|
||||
//
|
||||
// i indicates the former position of the vertex in the
|
||||
// list; n indicates the current number of vertices
|
||||
// before the operation has completed.
|
||||
//
|
||||
// It is an error to attempt to remove a vertex that is
|
||||
// not already a vertex of this primitive.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggCompositePrimitive::
|
||||
prepare_remove_vertex(EggVertex *vertex, int i, int n) {
|
||||
EggPrimitive::prepare_remove_vertex(vertex, i, n);
|
||||
|
||||
if (n >= 3) {
|
||||
i = max(i - 2, 0);
|
||||
nassertv(i < (int)_components.size());
|
||||
delete _components[i];
|
||||
_components.erase(_components.begin() + i);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggCompositePrimitive::write_body
|
||||
// Access: Protected
|
||||
// Description: Writes the attributes and the vertices referenced by
|
||||
// the primitive to the indicated output stream in Egg
|
||||
// format.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggCompositePrimitive::
|
||||
write_body(ostream &out, int indent_level) const {
|
||||
EggPrimitive::write_body(out, indent_level);
|
||||
|
||||
for (int i = 0; i < get_num_components(); i++) {
|
||||
const EggAttributes *attrib = get_component(i);
|
||||
if (attrib->compare_to(*this) != 0) {
|
||||
indent(out, indent_level + 2)
|
||||
<< "<Component> " << i << " {\n";
|
||||
attrib->write(out, indent_level + 4);
|
||||
indent(out, indent_level + 2) << "}\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
// Filename: eggCompositePrimitive.h
|
||||
// Created by: drose (13Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef EGGCOMPOSITEPRIMITIVE_H
|
||||
#define EGGCOMPOSITEPRIMITIVE_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "eggPrimitive.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : EggCompositePrimitive
|
||||
// Description : The base class for primitives such as triangle strips
|
||||
// and triangle fans, which include several component
|
||||
// triangles, each of which might have its own color
|
||||
// and/or normal.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDAEGG EggCompositePrimitive : public EggPrimitive {
|
||||
PUBLISHED:
|
||||
INLINE EggCompositePrimitive(const string &name = "");
|
||||
INLINE EggCompositePrimitive(const EggCompositePrimitive ©);
|
||||
INLINE EggCompositePrimitive &operator = (const EggCompositePrimitive ©);
|
||||
INLINE ~EggCompositePrimitive();
|
||||
|
||||
INLINE int get_num_components() const;
|
||||
INLINE const EggAttributes *get_component(int i) const;
|
||||
INLINE EggAttributes *get_component(int i);
|
||||
INLINE void set_component(int i, const EggAttributes *attrib);
|
||||
|
||||
PT(EggCompositePrimitive) triangulate_in_place();
|
||||
|
||||
protected:
|
||||
virtual void prepare_add_vertex(EggVertex *vertex, int i, int n);
|
||||
virtual void prepare_remove_vertex(EggVertex *vertex, int i, int n);
|
||||
|
||||
virtual void do_triangulate(EggGroupNode *container)=0;
|
||||
|
||||
void write_body(ostream &out, int indent_level) const;
|
||||
|
||||
private:
|
||||
typedef pvector<EggAttributes *> Components;
|
||||
Components _components;
|
||||
|
||||
public:
|
||||
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
EggPrimitive::init_type();
|
||||
register_type(_type_handle, "EggCompositePrimitive",
|
||||
EggPrimitive::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
|
||||
};
|
||||
|
||||
#include "eggCompositePrimitive.I"
|
||||
|
||||
#endif
|
||||
|
|
@ -23,6 +23,8 @@
|
|||
#include "eggExternalReference.h"
|
||||
#include "eggPrimitive.h"
|
||||
#include "eggPolygon.h"
|
||||
#include "eggCompositePrimitive.h"
|
||||
#include "eggMesher.h"
|
||||
#include "eggVertexPool.h"
|
||||
#include "eggVertex.h"
|
||||
#include "eggTextureCollection.h"
|
||||
|
|
@ -699,13 +701,13 @@ strip_normals() {
|
|||
// the total number of new triangles produced, less
|
||||
// degenerate polygons removed.
|
||||
//
|
||||
// If convex_also is true, both concave and convex
|
||||
// If flags contains T_convex, both concave and convex
|
||||
// polygons will be subdivided into triangles;
|
||||
// otherwise, only concave polygons will be subdivided,
|
||||
// and convex polygons will be largely unchanged.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int EggGroupNode::
|
||||
triangulate_polygons(bool convex_also) {
|
||||
triangulate_polygons(int flags) {
|
||||
int num_produced = 0;
|
||||
|
||||
Children children_copy = _children;
|
||||
|
|
@ -718,10 +720,16 @@ triangulate_polygons(bool convex_also) {
|
|||
|
||||
if (child->is_of_type(EggPolygon::get_class_type())) {
|
||||
EggPolygon *poly = DCAST(EggPolygon, child);
|
||||
poly->triangulate_in_place(convex_also);
|
||||
poly->triangulate_in_place((flags & T_convex) != 0);
|
||||
|
||||
} else if (child->is_of_type(EggCompositePrimitive::get_class_type())) {
|
||||
EggCompositePrimitive *comp = DCAST(EggCompositePrimitive, child);
|
||||
comp->triangulate_in_place();
|
||||
|
||||
} else if (child->is_of_type(EggGroupNode::get_class_type())) {
|
||||
num_produced += DCAST(EggGroupNode, child)->triangulate_polygons(convex_also);
|
||||
if (flags & T_recurse) {
|
||||
num_produced += DCAST(EggGroupNode, child)->triangulate_polygons(flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -729,6 +737,27 @@ triangulate_polygons(bool convex_also) {
|
|||
return num_produced;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggGroupNode::mesh_triangles
|
||||
// Access: Published
|
||||
// Description: Combine triangles together into triangle strips, at
|
||||
// this group and below.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggGroupNode::
|
||||
mesh_triangles(int flags) {
|
||||
EggMesher mesher;
|
||||
mesher.mesh(this);
|
||||
|
||||
if (flags & T_recurse) {
|
||||
EggGroupNode::iterator ci;
|
||||
for (ci = begin(); ci != end(); ++ci) {
|
||||
if ((*ci)->is_of_type(EggGroupNode::get_class_type())) {
|
||||
EggGroupNode *group_child = DCAST(EggGroupNode, *ci);
|
||||
group_child->mesh_triangles(flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggGroupNode::remove_unused_vertices
|
||||
|
|
|
|||
|
|
@ -129,7 +129,14 @@ PUBLISHED:
|
|||
void recompute_polygon_normals(CoordinateSystem cs = CS_default);
|
||||
void strip_normals();
|
||||
|
||||
int triangulate_polygons(bool convex_also);
|
||||
enum TriangulateFlags {
|
||||
T_convex = 0x001,
|
||||
T_composite = 0x002,
|
||||
T_recurse = 0x004
|
||||
};
|
||||
|
||||
int triangulate_polygons(int flags);
|
||||
void mesh_triangles(int flags);
|
||||
|
||||
int remove_unused_vertices();
|
||||
int remove_invalid_primitives();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
// Filename: eggMesher.I
|
||||
// Created by: drose (13Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -0,0 +1,787 @@
|
|||
// Filename: eggMesher.cxx
|
||||
// Created by: drose (13Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "eggMesher.h"
|
||||
#include "eggPolygon.h"
|
||||
#include "eggCompositePrimitive.h"
|
||||
#include "eggTriangleStrip.h"
|
||||
#include "config_egg.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesher::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
EggMesher::
|
||||
EggMesher() {
|
||||
_vertex_pool = NULL;
|
||||
_strip_index = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesher::mesh
|
||||
// Access: Public
|
||||
// Description: Accepts an EggGroupNode, which contains a set of
|
||||
// EggPrimitives--typically, triangles and quads--as
|
||||
// children. All of the EggPrimitives must reference
|
||||
// the same vertex pool.
|
||||
//
|
||||
// At the completion of this function, the triangles in
|
||||
// the group will have been replaced with
|
||||
// EggTriangleStrips as appropriate.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggMesher::
|
||||
mesh(EggGroupNode *group) {
|
||||
_vertex_pool = NULL;
|
||||
_strip_index = 0;
|
||||
|
||||
// Create a temporary node to hold the children of groupthat aren't
|
||||
// involved in the meshing.
|
||||
PT(EggGroupNode) saved_children = new EggGroupNode;
|
||||
|
||||
// Add each primitive in the group to the mesh pool.
|
||||
EggGroupNode::iterator ci = group->begin();
|
||||
while (ci != group->end()) {
|
||||
EggGroupNode::iterator cnext = ci;
|
||||
++cnext;
|
||||
|
||||
if ((*ci)->is_of_type(EggPolygon::get_class_type())) {
|
||||
add_polygon(DCAST(EggPolygon, *ci), EggMesherStrip::MO_user);
|
||||
} else {
|
||||
// If it's not a polygon, preserve it.
|
||||
saved_children->add_child(*ci);
|
||||
}
|
||||
ci = cnext;
|
||||
}
|
||||
|
||||
do_mesh();
|
||||
|
||||
// Now copy the newly-meshed primitives back to the group.
|
||||
group->clear();
|
||||
group->steal_children(*saved_children);
|
||||
|
||||
Strips::iterator si;
|
||||
for (si = _done.begin(); si != _done.end(); ++si) {
|
||||
PT(EggPrimitive) egg_prim = get_prim(*si);
|
||||
if (egg_prim != (EggPrimitive *)NULL) {
|
||||
group->add_child(egg_prim);
|
||||
}
|
||||
}
|
||||
|
||||
_vertex_pool = NULL;
|
||||
_strip_index = 0;
|
||||
_color_sheets.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesher::write
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggMesher::
|
||||
write(ostream &out) const {
|
||||
/*
|
||||
out << _edges.size() << " edges:\n";
|
||||
copy(_edges.begin(), _edges.end(), ostream_iterator<Edge>(out, "\n"));
|
||||
*/
|
||||
|
||||
out << _verts.size() << " verts:\n";
|
||||
Verts::const_iterator vi;
|
||||
|
||||
for (vi = _verts.begin(); vi != _verts.end(); ++vi) {
|
||||
int v = (*vi).first;
|
||||
const EdgePtrs &edges = (*vi).second;
|
||||
out << v << " shares " << count_vert_edges(edges) << " edges:\n";
|
||||
EdgePtrs::const_iterator ei;
|
||||
for (ei = edges.begin(); ei != edges.end(); ++ei) {
|
||||
if (!(*ei)->_strips.empty() || !(*ei)->_opposite->_strips.empty()) {
|
||||
out << " " << **ei << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Strips::const_iterator si;
|
||||
out << _tris.size() << " tris:\n";
|
||||
for (si = _tris.begin(); si != _tris.end(); ++si) {
|
||||
out << (*si) << "\n";
|
||||
}
|
||||
|
||||
out << _quads.size() << " quads:\n";
|
||||
for (si = _quads.begin(); si != _quads.end(); ++si) {
|
||||
out << (*si) << "\n";
|
||||
}
|
||||
|
||||
out << _strips.size() << " strips:\n";
|
||||
for (si = _strips.begin(); si != _strips.end(); ++si) {
|
||||
out << (*si) << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesher::add_polygon
|
||||
// Access: Private
|
||||
// Description: Adds a single polygon into the pool of available
|
||||
// primitives for meshing.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool EggMesher::
|
||||
add_polygon(const EggPolygon *egg_poly, EggMesherStrip::MesherOrigin origin) {
|
||||
if (_vertex_pool == NULL) {
|
||||
_vertex_pool = egg_poly->get_pool();
|
||||
} else {
|
||||
nassertr(_vertex_pool == egg_poly->get_pool(), false);
|
||||
}
|
||||
|
||||
// Define an initial strip (probably of length 1) for the prim.
|
||||
EggMesherStrip temp_strip(egg_poly, _strip_index++, _vertex_pool);
|
||||
Strips &list = choose_strip_list(temp_strip);
|
||||
list.push_back(temp_strip);
|
||||
EggMesherStrip &strip = list.back();
|
||||
strip._origin = origin;
|
||||
|
||||
int i;
|
||||
int num_verts = egg_poly->size();
|
||||
|
||||
int *vptrs = (int *)alloca(num_verts * sizeof(int));
|
||||
EdgePtrs **eptrs = (EdgePtrs **)alloca(num_verts * sizeof(EdgePtrs *));
|
||||
|
||||
// Get the common vertex pointers for the primitive's vertices.
|
||||
for (i = 0; i < num_verts; i++) {
|
||||
Verts::value_type v(egg_poly->get_vertex(i)->get_index(), EdgePtrs());
|
||||
Verts::iterator n = _verts.insert(v).first;
|
||||
|
||||
vptrs[i] = (*n).first;
|
||||
eptrs[i] = &(*n).second;
|
||||
|
||||
strip._verts.push_back(vptrs[i]);
|
||||
}
|
||||
|
||||
// Now identify the common edges.
|
||||
|
||||
if (egg_poly->size() != 3 && egg_poly->size() != 4) {
|
||||
// If we have a higher-order polygon, triangulate it
|
||||
// automatically.
|
||||
PT(EggGroupNode) temp_group = new EggGroupNode;
|
||||
egg_poly->triangulate_into(temp_group, true);
|
||||
EggGroupNode::iterator ci;
|
||||
for (ci = temp_group->begin(); ci != temp_group->end(); ++ci) {
|
||||
add_polygon(DCAST(EggPolygon, *ci), EggMesherStrip::MO_user);
|
||||
}
|
||||
|
||||
} else {
|
||||
for (i = 0; i < num_verts; i++) {
|
||||
// Define an inner and outer edge. A polygon shares an edge with a
|
||||
// neighbor only when one of its inner edges matches a neighbor's
|
||||
// outer edge (and vice-versa).
|
||||
EggMesherEdge inner(vptrs[i], vptrs[(i+1) % num_verts]);
|
||||
EggMesherEdge outer(vptrs[(i+1) % num_verts], vptrs[i]);
|
||||
|
||||
// Add it to the list and get its common pointer.
|
||||
EggMesherEdge &inner_ref = (EggMesherEdge &)*_edges.insert(inner).first;
|
||||
EggMesherEdge &outer_ref = (EggMesherEdge &)*_edges.insert(outer).first;
|
||||
|
||||
// Tell the edges about each other.
|
||||
inner_ref._opposite = &outer_ref;
|
||||
outer_ref._opposite = &inner_ref;
|
||||
|
||||
// Associate the common edge to the strip.
|
||||
strip._edges.push_back(&inner_ref);
|
||||
|
||||
// Associate the strip, as well as the original prim, to the edge.
|
||||
outer_ref._strips.push_back(&strip);
|
||||
|
||||
// Associate the common edge with the vertices that share it.
|
||||
// EggMesherEdge *edge_ptr = inner_ref.common_ptr();
|
||||
eptrs[i]->insert(&outer_ref);
|
||||
eptrs[(i+1) % num_verts]->insert(&outer_ref);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesher::do_mesh
|
||||
// Access: Private
|
||||
// Description: Performs the meshing process on the set of primitives
|
||||
// that have been added via add_prim(), leaving the
|
||||
// result in _done.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggMesher::
|
||||
do_mesh() {
|
||||
if (egg_consider_fans) {
|
||||
find_fans();
|
||||
}
|
||||
|
||||
// First, we try to make all the best quads we can.
|
||||
if (egg_retesselate_coplanar) {
|
||||
make_quads();
|
||||
}
|
||||
|
||||
// Then, we do the rest of the tris.
|
||||
mesh_list(_tris);
|
||||
|
||||
if (egg_show_quads) {
|
||||
// If we're showing quads, we shouldn't do any more meshing.
|
||||
Strips::iterator si;
|
||||
for (si = _quads.begin(); si != _quads.end(); ++si) {
|
||||
if ((*si)._status == EggMesherStrip::MS_alive) {
|
||||
(*si)._status = EggMesherStrip::MS_done;
|
||||
}
|
||||
}
|
||||
for (si = _strips.begin(); si != _strips.end(); ++si) {
|
||||
if ((*si)._status == EggMesherStrip::MS_alive) {
|
||||
(*si)._status = EggMesherStrip::MS_done;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Then, build quads into sheets where possible.
|
||||
build_sheets();
|
||||
|
||||
// Pick up any quads that might have been left behind.
|
||||
mesh_list(_quads);
|
||||
|
||||
// Finally, do the longer strips.
|
||||
mesh_list(_strips);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesher::get_prim
|
||||
// Access: Private
|
||||
// Description: Creates an EggPrimitive that represents the result of
|
||||
// the meshed EggMesherStrip object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(EggPrimitive) EggMesher::
|
||||
get_prim(EggMesherStrip &strip) {
|
||||
EggMesherStrip::PrimType orig_type = strip._type;
|
||||
PT(EggPrimitive) egg_prim = strip.make_prim(_vertex_pool);
|
||||
|
||||
if (egg_show_tstrips) {
|
||||
// If we have egg_show_tstrips on, it means we need to color every
|
||||
// primitive according to which, if any, tristrip it is in.
|
||||
|
||||
Colorf color1, color2;
|
||||
|
||||
if (egg_prim->is_of_type(EggTriangleStrip::get_class_type()) /*||
|
||||
egg_prim->is_of_type(EggTriangleFan::get_class_type())*/) {
|
||||
make_random_color(color2);
|
||||
color1 = (color2 * 0.8); // somewhat darker.
|
||||
|
||||
} else {
|
||||
// not-a-tristrip.
|
||||
color1.set(0.85, 0.85, 0.85, 1.0);
|
||||
color2.set(0.85, 0.85, 0.85, 1.0);
|
||||
}
|
||||
|
||||
// Now color1 and color2 indicate the color for the first triangle
|
||||
// and the rest of the primitive, respectively.
|
||||
if (egg_prim->is_of_type(EggCompositePrimitive::get_class_type())) {
|
||||
EggCompositePrimitive *egg_comp = DCAST(EggCompositePrimitive, egg_prim);
|
||||
int num_components = egg_comp->get_num_components();
|
||||
if (num_components > 0) {
|
||||
egg_comp->get_component(0)->set_color(color1);
|
||||
for (int i = 1; i < num_components; i++) {
|
||||
egg_comp->get_component(i)->set_color(color2);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
egg_prim->set_color(color1);
|
||||
}
|
||||
|
||||
int num_verts = egg_prim->size();
|
||||
for (int i = 0; i < num_verts; i++) {
|
||||
egg_prim->get_vertex(i)->clear_color();
|
||||
}
|
||||
|
||||
} else if (egg_show_qsheets) {
|
||||
// egg_show_qsheets means to color every primitive according to
|
||||
// which, if any, quadsheet it is in. This is a bit easier,
|
||||
// because the entire primitive gets the same color.
|
||||
|
||||
// Is this a quadsheet?
|
||||
Colorf color1;
|
||||
if (strip._row_id < 0) {
|
||||
// Yep! Assign a new color, if it doesn't already have one.
|
||||
ColorSheetMap::iterator ci = _color_sheets.find(strip._row_id);
|
||||
|
||||
if (ci == _color_sheets.end()) {
|
||||
make_random_color(color1);
|
||||
_color_sheets[strip._row_id] = color1;
|
||||
} else {
|
||||
color1 = (*ci).second;
|
||||
}
|
||||
}
|
||||
|
||||
// Now color1 is the color we want to assign to the whole
|
||||
// primitive.
|
||||
egg_prim->set_color(color1);
|
||||
int num_verts = egg_prim->size();
|
||||
for (int i = 0; i < num_verts; i++) {
|
||||
egg_prim->get_vertex(i)->clear_color();
|
||||
}
|
||||
|
||||
} else if (egg_show_quads) {
|
||||
// egg_show_quads means to show the assembling of tris into quads
|
||||
// and fans.
|
||||
|
||||
// We use the following color convention:
|
||||
|
||||
// white: unchanged; as supplied by user.
|
||||
// dark blue: quads made in the initial pass. These are more certain.
|
||||
// light blue: quads made in the second pass. These are less certain.
|
||||
// very light blue: quadstrips. These are unlikely to appear.
|
||||
// random shades of red: triangles and tristrips.
|
||||
// green: fans and retesselated fan polygons.
|
||||
|
||||
// We need a handful of entries.
|
||||
Colorf white(0.85, 0.85, 0.85, 1.0);
|
||||
Colorf dark_blue(0.0, 0.0, 0.75, 1.0);
|
||||
Colorf light_blue(0.4, 0.4, 0.8, 1.0);
|
||||
Colorf very_light_blue(0.6, 0.6, 1.0, 1.0);
|
||||
Colorf green(0.2, 0.8, 0.2, 1.0);
|
||||
|
||||
Colorf color1;
|
||||
if (strip._origin == EggMesherStrip::MO_user) {
|
||||
color1 = white;
|
||||
} else if (strip._origin == EggMesherStrip::MO_firstquad) {
|
||||
color1 = dark_blue;
|
||||
} else if (strip._origin == EggMesherStrip::MO_fanpoly) {
|
||||
color1 = green;
|
||||
} else {
|
||||
switch (orig_type) {
|
||||
case EggMesherStrip::PT_quad:
|
||||
color1 = light_blue;
|
||||
break;
|
||||
|
||||
case EggMesherStrip::PT_quadstrip:
|
||||
color1 = very_light_blue;
|
||||
break;
|
||||
|
||||
case EggMesherStrip::PT_tristrip:
|
||||
make_random_color(color1);
|
||||
// Make it a shade of red.
|
||||
if (color1[0] < color1[1]) {
|
||||
float t = color1[0];
|
||||
color1[0] = color1[1];
|
||||
color1[1] = t;
|
||||
}
|
||||
color1[2] = color1[1];
|
||||
break;
|
||||
|
||||
case EggMesherStrip::PT_trifan:
|
||||
make_random_color(color1);
|
||||
// Make it a shade of green.
|
||||
if (color1[0] > color1[1]) {
|
||||
float t = color1[0];
|
||||
color1[0] = color1[1];
|
||||
color1[1] = t;
|
||||
}
|
||||
color1[2] = color1[0];
|
||||
break;
|
||||
|
||||
default:
|
||||
color1 = white;
|
||||
}
|
||||
}
|
||||
|
||||
// Now color1 is the color we want to assign to the whole
|
||||
// primitive.
|
||||
egg_prim->set_color(color1);
|
||||
int num_verts = egg_prim->size();
|
||||
for (int i = 0; i < num_verts; i++) {
|
||||
egg_prim->get_vertex(i)->clear_color();
|
||||
}
|
||||
}
|
||||
|
||||
return egg_prim;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesher::count_vert_edges
|
||||
// Access: Private
|
||||
// Description: Returns the number of edges in the list that are used
|
||||
// by at least one EggMesherStrip object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int EggMesher::
|
||||
count_vert_edges(const EdgePtrs &edges) const {
|
||||
int count = 0;
|
||||
EdgePtrs::const_iterator ei;
|
||||
for (ei = edges.begin(); ei != edges.end(); ++ei) {
|
||||
count += (!(*ei)->_strips.empty() || !(*ei)->_opposite->_strips.empty());
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesher::choose_strip_list
|
||||
// Access: Private
|
||||
// Description: Selects which of several strip lists on the EggMesher
|
||||
// class the indicated EggMesherStrip should be added
|
||||
// to.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
plist<EggMesherStrip> &EggMesher::
|
||||
choose_strip_list(const EggMesherStrip &strip) {
|
||||
switch (strip._status) {
|
||||
case EggMesherStrip::MS_done:
|
||||
return _done;
|
||||
|
||||
case EggMesherStrip::MS_dead:
|
||||
return _dead;
|
||||
|
||||
case EggMesherStrip::MS_alive:
|
||||
switch (strip._type) {
|
||||
case EggMesherStrip::PT_tri:
|
||||
return _tris;
|
||||
|
||||
case EggMesherStrip::PT_quad:
|
||||
return _quads;
|
||||
|
||||
default:
|
||||
return _strips;
|
||||
}
|
||||
|
||||
default:
|
||||
egg_cat.fatal() << "Invalid strip status!\n";
|
||||
abort();
|
||||
}
|
||||
|
||||
return _strips; // Unreachable; this is just to make the compiler happy.
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesher::build_sheets
|
||||
// Access: Private
|
||||
// Description: Attempts to locate large quadsheets in the polygon
|
||||
// soup. A quadsheet is defined as a uniform
|
||||
// rectangular mesh of quads joined at the corners.
|
||||
//
|
||||
// Sheets like this are commonly output by modeling
|
||||
// packages, especially uniform tesselators, and they
|
||||
// are trivially converted into a row of triangle
|
||||
// strips.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggMesher::
|
||||
build_sheets() {
|
||||
int first_row_id = 1;
|
||||
|
||||
// First, move all the quads to our own internal list.
|
||||
Strips pre_sheeted;
|
||||
pre_sheeted.splice(pre_sheeted.end(), _quads);
|
||||
|
||||
while (!pre_sheeted.empty()) {
|
||||
// Pick the first quad on the list.
|
||||
|
||||
Strips::iterator best = pre_sheeted.begin();
|
||||
|
||||
// If the row_id is negative, we've already built a sheet out of
|
||||
// this quad. Leave it alone. We also need to leave it be if it
|
||||
// has no available edges.
|
||||
if ((*best)._row_id >= 0 &&
|
||||
(*best)._status == EggMesherStrip::MS_alive &&
|
||||
!(*best)._edges.empty()) {
|
||||
// There are two possible sheets we could make from this quad,
|
||||
// in two different orientations. Measure them both and figure
|
||||
// out which one is best.
|
||||
|
||||
const EggMesherEdge *edge_a = (*best)._edges.front();
|
||||
const EggMesherEdge *edge_b = (*best).find_adjacent_edge(edge_a);
|
||||
|
||||
int num_prims_a = 0;
|
||||
int num_rows_a = 0;
|
||||
int first_row_id_a = first_row_id;
|
||||
(*best).measure_sheet(edge_a, true, num_prims_a, num_rows_a,
|
||||
first_row_id_a, 0, 0);
|
||||
first_row_id += num_rows_a;
|
||||
double avg_length_a = (double)num_prims_a / (double)num_rows_a;
|
||||
|
||||
int num_prims_b = 0;
|
||||
int num_rows_b = 0;
|
||||
int first_row_id_b = first_row_id;
|
||||
double avg_length_b;
|
||||
if (edge_b != NULL) {
|
||||
(*best).measure_sheet(edge_b, true, num_prims_b, num_rows_b,
|
||||
first_row_id_b, 0, 0);
|
||||
first_row_id += num_rows_b;
|
||||
avg_length_b = (double)num_prims_b / (double)num_rows_b;
|
||||
}
|
||||
|
||||
// Which sheet is better?
|
||||
if (edge_b != NULL && avg_length_b >= avg_length_a) {
|
||||
// Sheet b. That's easy.
|
||||
(*best).cut_sheet(first_row_id_b, true, _vertex_pool);
|
||||
|
||||
} else {
|
||||
// Nope, sheet a is better. This is a bit of a nuisance
|
||||
// because we've unfortunately wiped out the information we
|
||||
// stored when we measured sheet a. We'll have to do it
|
||||
// again.
|
||||
|
||||
num_prims_a = 0;
|
||||
num_rows_a = 0;
|
||||
first_row_id_a = first_row_id;
|
||||
(*best).measure_sheet(edge_a, true, num_prims_a, num_rows_a,
|
||||
first_row_id_a, 0, 0);
|
||||
first_row_id += num_rows_a;
|
||||
|
||||
// Now we can cut it.
|
||||
(*best).cut_sheet(first_row_id_a, true, _vertex_pool);
|
||||
}
|
||||
}
|
||||
|
||||
// Now put it somewhere. We'll never see this quad again in
|
||||
// build_sheets().
|
||||
Strips &list = choose_strip_list(*best);
|
||||
list.splice(list.end(), pre_sheeted, best);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesher::find_fans
|
||||
// Access: Private
|
||||
// Description: Looks for cases of multiple polygons all sharing a
|
||||
// common vertex, and replaces these with a single fan.
|
||||
//
|
||||
// This step is performed before detecting triangle
|
||||
// strips. We have to be careful: if we are too
|
||||
// aggressive in detecting fans, we may ruin the ability
|
||||
// to build good triangle strips, and we may thereby end
|
||||
// up with a less-than-optimal solution.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggMesher::
|
||||
find_fans() {
|
||||
#if 0
|
||||
pvector<Prim> unrolled_tris;
|
||||
|
||||
// Consider all vertices. Any vertex with over a certain number of
|
||||
// edges connected to it is eligible to become a fan.
|
||||
|
||||
Verts::iterator vi;
|
||||
|
||||
for (vi = _verts.begin(); vi != _verts.end(); ++vi) {
|
||||
EdgePtrs &edges = (*vi).second;
|
||||
|
||||
// 14 is the magic number of edges. 12 edges or fewer are likely
|
||||
// to be found on nearly every vertex in a quadsheet (six edges
|
||||
// times two, one each way). We don't want to waste time fanning
|
||||
// out each vertex of a quadsheet, and we don't want to break up
|
||||
// the quadsheets anyway. We bump this up to 14 because some
|
||||
// quadsheets are defined with triangles flipped here and there.
|
||||
if (edges.size() > 6) {
|
||||
const Vertex &v = (*vi).first;
|
||||
|
||||
// Build up a list of far fan edges.
|
||||
typedef pvector<FanMaker> FanMakers;
|
||||
|
||||
FanMakers fans;
|
||||
|
||||
EdgePtrs::iterator ei;
|
||||
Edge::Strips::iterator si;
|
||||
for (ei = edges.begin(); ei != edges.end(); ++ei) {
|
||||
for (si = (*ei)->_strips.begin();
|
||||
si != (*ei)->_strips.end();
|
||||
++si) {
|
||||
EggMesherStrip *strip = *si;
|
||||
if (strip->_type == EggMesherStrip::PT_tri) {
|
||||
FanMaker fan(&v, strip, this);
|
||||
if (!fan._edges.empty()) {
|
||||
fans.push_back(fan);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sort the fans list by edge pointers, and remove duplicates.
|
||||
sort(fans.begin(), fans.end());
|
||||
fans.erase(unique(fans.begin(), fans.end()),
|
||||
fans.end());
|
||||
|
||||
FanMakers::iterator fi, fi2;
|
||||
|
||||
// Now pull out connected edges.
|
||||
int joined_any;
|
||||
do {
|
||||
joined_any = false;
|
||||
for (fi = fans.begin(); fi != fans.end(); ++fi) {
|
||||
if (!(*fi).is_empty()) {
|
||||
fi2 = fi;
|
||||
for (++fi2; fi2 != fans.end(); ++fi2) {
|
||||
if (!(*fi2).is_empty()) {
|
||||
joined_any = (*fi).join(*fi2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (joined_any);
|
||||
|
||||
for (fi = fans.begin(); fi != fans.end(); ++fi) {
|
||||
if ((*fi).is_valid()) {
|
||||
(*fi).build(unrolled_tris);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, add back in the triangles we might have produced by
|
||||
// unrolling some of the fans. We can't add these back in safely
|
||||
// until we're done traversing all the vertices and primitives we
|
||||
// had in the first place (since adding them will affect the edge
|
||||
// lists).
|
||||
pvector<Prim>::iterator ti;
|
||||
for (ti = unrolled_tris.begin(); ti != unrolled_tris.end(); ++ti) {
|
||||
add_prim(*ti);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesher::make_quads
|
||||
// Access: Private
|
||||
// Description: Attempts to join up each single tri to its neighbor,
|
||||
// to reconstruct a pattern of quads, suitable for
|
||||
// making into quadsheets or at least quadstrips.
|
||||
//
|
||||
// Quads have some nice properties that make them easy
|
||||
// to manipulate when meshing. We will ultimately
|
||||
// convert the quadsheets and quadstrips into tristrips,
|
||||
// but it's easier to work with them first while they're
|
||||
// quads.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggMesher::
|
||||
make_quads() {
|
||||
// Ideally, we want to match tris across their hypotenuse to make a
|
||||
// pattern of quads. (This assumes that we are working with a
|
||||
// triangulated mesh pattern, of course. If we have some other
|
||||
// pattern of tris, all bets are off and it doesn't really matter
|
||||
// anyway.)
|
||||
|
||||
// First, we'll find all the tris that have no doubt about their
|
||||
// ideal mate, and pair them up right away. The others we'll get to
|
||||
// later. This way, the uncertain matches won't pollute the quad
|
||||
// alignment for everyone else.
|
||||
|
||||
typedef pair<EggMesherStrip *, EggMesherStrip *> Pair;
|
||||
typedef pair<Pair, EggMesherEdge *> Matched;
|
||||
typedef pvector<Matched> SoulMates;
|
||||
|
||||
SoulMates soulmates;
|
||||
|
||||
EggMesherStrip *tri, *mate, *mate2;
|
||||
EggMesherEdge *common_edge, *common_edge2;
|
||||
|
||||
Strips::iterator si;
|
||||
for (si = _tris.begin(); si != _tris.end(); ++si) {
|
||||
tri = &(*si);
|
||||
|
||||
if (tri->_status == EggMesherStrip::MS_alive) {
|
||||
if (tri->find_ideal_mate(mate, common_edge, _vertex_pool)) {
|
||||
// Does our chosen mate want us too?
|
||||
if (mate->_type == EggMesherStrip::PT_tri &&
|
||||
mate->_status == EggMesherStrip::MS_alive &&
|
||||
mate->find_ideal_mate(mate2, common_edge2, _vertex_pool) &&
|
||||
mate2 == tri) {
|
||||
// Hooray!
|
||||
soulmates.push_back(Matched(Pair(tri, mate), common_edge));
|
||||
// We'll temporarily mark the two tris as paired.
|
||||
tri->_status = EggMesherStrip::MS_paired;
|
||||
mate->_status = EggMesherStrip::MS_paired;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now that we've found all the tris that are sure about each other,
|
||||
// mate them.
|
||||
SoulMates::iterator mi;
|
||||
for (mi = soulmates.begin(); mi != soulmates.end(); ++mi) {
|
||||
tri = (*mi).first.first;
|
||||
mate = (*mi).first.second;
|
||||
common_edge = (*mi).second;
|
||||
|
||||
nassertv(tri->_status == EggMesherStrip::MS_paired);
|
||||
nassertv(mate->_status == EggMesherStrip::MS_paired);
|
||||
tri->_status = EggMesherStrip::MS_alive;
|
||||
mate->_status = EggMesherStrip::MS_alive;
|
||||
|
||||
EggMesherStrip::mate_pieces(common_edge, *tri, *mate, _vertex_pool);
|
||||
tri->_origin = EggMesherStrip::MO_firstquad;
|
||||
}
|
||||
|
||||
// Now move all the strips off the tri list that no longer belong.
|
||||
Strips::iterator next;
|
||||
si = _tris.begin();
|
||||
while (si != _tris.end()) {
|
||||
next = si;
|
||||
++next;
|
||||
|
||||
Strips &list = choose_strip_list(*si);
|
||||
if (&list != &_tris) {
|
||||
list.splice(list.end(), _tris, si);
|
||||
}
|
||||
|
||||
si = next;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesher::mesh_list
|
||||
// Access: Private
|
||||
// Description: Processes all of the strips on the indicated list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggMesher::
|
||||
mesh_list(Strips &strips) {
|
||||
while (!strips.empty()) {
|
||||
// Pick the first strip on the list.
|
||||
|
||||
Strips::iterator best = strips.begin();
|
||||
|
||||
if ((*best)._status == EggMesherStrip::MS_alive) {
|
||||
(*best).mate(_vertex_pool);
|
||||
}
|
||||
|
||||
// Put the strip back on the end of whichever list it wants. This
|
||||
// might be the same list, if the strip is still alive, or it
|
||||
// might be _done or _dead.
|
||||
Strips &list = choose_strip_list(*best);
|
||||
list.splice(list.end(), strips, best);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesher::make_random_color
|
||||
// Access: Private, Static
|
||||
// Description: Chooses a reasonable random color.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggMesher::
|
||||
make_random_color(Colorf &color) {
|
||||
LVector3f rgb;
|
||||
float len;
|
||||
do {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
rgb[i] = (double)rand() / (double)RAND_MAX;
|
||||
}
|
||||
len = length(rgb);
|
||||
|
||||
// Repeat until we have a color that's not too dark or too light.
|
||||
} while (len < .1 || len > 1.5);
|
||||
|
||||
color.set(rgb[0], rgb[1], rgb[2],
|
||||
0.25 + 0.75 * (double)rand() / (double)RAND_MAX);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
// Filename: eggMesher.h
|
||||
// Created by: drose (13Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef EGGMESHER_H
|
||||
#define EGGMESHER_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "eggMesherEdge.h"
|
||||
#include "eggMesherStrip.h"
|
||||
//#include "eggMesherFanMaker.h"
|
||||
#include "eggPolygon.h"
|
||||
#include "pvector.h"
|
||||
#include "plist.h"
|
||||
#include "pset.h"
|
||||
#include "pmap.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
class MesherFanMaker;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Class : EggMesher
|
||||
// Description : Collects together unrelated EggPrimitives, determines
|
||||
// their edge connectivity, and generates a set of
|
||||
// EggTriangleStrips that represent the same geometry.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EggMesher {
|
||||
public:
|
||||
EggMesher();
|
||||
|
||||
void mesh(EggGroupNode *group);
|
||||
|
||||
void write(ostream &out) const;
|
||||
|
||||
bool _consider_fans;
|
||||
bool _retesselate_coplanar;
|
||||
bool _show_quads;
|
||||
bool _show_qsheets;
|
||||
|
||||
private:
|
||||
bool add_polygon(const EggPolygon *egg_poly,
|
||||
EggMesherStrip::MesherOrigin origin);
|
||||
void do_mesh();
|
||||
PT(EggPrimitive) get_prim(EggMesherStrip &strip);
|
||||
|
||||
typedef plist<EggMesherStrip> Strips;
|
||||
typedef pset<EggMesherEdge> Edges;
|
||||
typedef pset<EggMesherEdge *> EdgePtrs;
|
||||
typedef pmap<int, EdgePtrs> Verts;
|
||||
|
||||
// This is used for show-qsheets.
|
||||
typedef pmap<int, Colorf> ColorSheetMap;
|
||||
|
||||
int count_vert_edges(const EdgePtrs &edges) const;
|
||||
plist<EggMesherStrip> &choose_strip_list(const EggMesherStrip &strip);
|
||||
|
||||
void build_sheets();
|
||||
void find_fans();
|
||||
void make_quads();
|
||||
void mesh_list(Strips &strips);
|
||||
static void make_random_color(Colorf &color);
|
||||
|
||||
Strips _tris, _quads, _strips;
|
||||
Strips _dead, _done;
|
||||
Verts _verts;
|
||||
Edges _edges;
|
||||
int _strip_index;
|
||||
EggVertexPool *_vertex_pool;
|
||||
ColorSheetMap _color_sheets;
|
||||
|
||||
friend class EggMesherStrip;
|
||||
friend class EggMesherFanMaker;
|
||||
};
|
||||
|
||||
#include "eggMesher.I"
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
// Filename: eggMesherEdge.I
|
||||
// Created by: drose (13Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesherEdge::Constructor
|
||||
// Access: Public
|
||||
// Description: Defines an edge as a pair of vertices. The _opposite
|
||||
// pointer should be filled in explicitly by the caller.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE EggMesherEdge::
|
||||
EggMesherEdge(int vi_a, int vi_b) : _vi_a(vi_a), _vi_b(vi_b) {
|
||||
_opposite = NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesherEdge::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE EggMesherEdge::
|
||||
EggMesherEdge(const EggMesherEdge ©) :
|
||||
_vi_a(copy._vi_a),
|
||||
_vi_b(copy._vi_b),
|
||||
_strips(copy._strips),
|
||||
_opposite(copy._opposite)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesherEdge::contains_vertex
|
||||
// Access: Public
|
||||
// Description: Returns true if the edge contains the indicated
|
||||
// vertex index, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool EggMesherEdge::
|
||||
contains_vertex(int vi) const {
|
||||
return (_vi_a == vi || _vi_b == vi);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesherEdge::matches
|
||||
// Access: Public
|
||||
// Description: Returns true if this edge represents the same line
|
||||
// segment as the other edge, in either direction.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool EggMesherEdge::
|
||||
matches(const EggMesherEdge &other) const {
|
||||
return ((_vi_a == other._vi_a && _vi_b == other._vi_b) ||
|
||||
(_vi_b == other._vi_a && _vi_a == other._vi_b));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesherEdge::common_ptr
|
||||
// Access: Public
|
||||
// Description: Returns an arbitrary pointer that is used to
|
||||
// represent both this edge and its opposite.
|
||||
// this->common_ptr() is guaranteed to be the same as
|
||||
// this->_opposite->common_ptr().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE EggMesherEdge *EggMesherEdge::
|
||||
common_ptr() {
|
||||
return min(this, _opposite);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesherEdge::operator ==
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool EggMesherEdge::
|
||||
operator == (const EggMesherEdge &other) const {
|
||||
return _vi_a == other._vi_a && _vi_b == other._vi_b;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesherEdge::operator !=
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool EggMesherEdge::
|
||||
operator != (const EggMesherEdge &other) const {
|
||||
return !operator == (other);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesherEdge::operator <
|
||||
// Access: Public
|
||||
// Description: Defines an arbitrary ordering for edges, used for
|
||||
// putting edges in a sorted container.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool EggMesherEdge::
|
||||
operator < (const EggMesherEdge &other) const {
|
||||
if (_vi_a != other._vi_a) {
|
||||
return _vi_a < other._vi_a;
|
||||
}
|
||||
return _vi_b < other._vi_b;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesherEdge::compute_length
|
||||
// Access: Public
|
||||
// Description: Returns the length of the edge in model units.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE double EggMesherEdge::
|
||||
compute_length(const EggVertexPool *vertex_pool) const {
|
||||
LPoint3d a = vertex_pool->get_vertex(_vi_a)->get_pos3();
|
||||
LPoint3d b = vertex_pool->get_vertex(_vi_b)->get_pos3();
|
||||
return (a - b).length();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesherEdge::compute_box
|
||||
// Access: Public
|
||||
// Description: Returns a 3-component vector that represents the
|
||||
// lengths of the sides of the smalled axis-aligned box
|
||||
// that contains the edge. That is, the projection the
|
||||
// edge onto each axis.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE LVecBase3d EggMesherEdge::
|
||||
compute_box(const EggVertexPool *vertex_pool) const {
|
||||
LPoint3d a = vertex_pool->get_vertex(_vi_a)->get_pos3();
|
||||
LPoint3d b = vertex_pool->get_vertex(_vi_b)->get_pos3();
|
||||
LVector3d v = (a - b);
|
||||
return LVecBase3d(fabs(v[0]), fabs(v[1]), fabs(v[2]));
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
// Filename: eggMesherEdge.cxx
|
||||
// Created by: drose (13Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "eggMesherEdge.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesherEdge::remove
|
||||
// Access: Public
|
||||
// Description: Removes an edge from a particular strip.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggMesherEdge::
|
||||
remove(EggMesherStrip *strip) {
|
||||
strip->_edges.remove(this);
|
||||
strip->_edges.remove(_opposite);
|
||||
|
||||
_strips.remove(strip);
|
||||
_opposite->_strips.remove(strip);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesherEdge::change_strip
|
||||
// Access: Public
|
||||
// Description: Reparents the edge from strip "from" to strip "to".
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggMesherEdge::
|
||||
change_strip(EggMesherStrip *from, EggMesherStrip *to) {
|
||||
Strips::iterator si;
|
||||
|
||||
for (si = _strips.begin(); si != _strips.end(); ++si) {
|
||||
if (*si == from) {
|
||||
*si = to;
|
||||
}
|
||||
}
|
||||
|
||||
for (si = _opposite->_strips.begin();
|
||||
si != _opposite->_strips.end();
|
||||
++si) {
|
||||
if (*si == from) {
|
||||
*si = to;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesherEdge::output
|
||||
// Access: Public
|
||||
// Description: Formats the edge for output in some sensible way.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggMesherEdge::
|
||||
output(ostream &out) const {
|
||||
out << "Edge [" << _vi_a << " to " << _vi_b << "], "
|
||||
<< _strips.size() << " strips:";
|
||||
|
||||
Strips::const_iterator si;
|
||||
for (si = _strips.begin(); si != _strips.end(); ++si) {
|
||||
out << " " << (*si)->_index;
|
||||
}
|
||||
|
||||
if (_opposite!=NULL) {
|
||||
out << " opposite "
|
||||
<< _opposite->_strips.size() << " strips:";
|
||||
|
||||
for (si = _opposite->_strips.begin();
|
||||
si != _opposite->_strips.end();
|
||||
++si) {
|
||||
out << " " << (*si)->_index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
// Filename: eggMesherEdge.h
|
||||
// Created by: drose (13Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef EGGMESHEREDGE_H
|
||||
#define EGGMESHEREDGE_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "eggVertexPool.h"
|
||||
#include "eggVertex.h"
|
||||
#include "plist.h"
|
||||
|
||||
class EggMesherStrip;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Class : EggMesherEdge
|
||||
// Description : Represents one edge of a triangle, as used by the
|
||||
// EggMesher to discover connected triangles. The edge
|
||||
// is actually represented as a pair of vertex indices
|
||||
// into the same vertex pool.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EggMesherEdge {
|
||||
public:
|
||||
INLINE EggMesherEdge(int vi_a, int vi_b);
|
||||
INLINE EggMesherEdge(const EggMesherEdge ©);
|
||||
|
||||
void remove(EggMesherStrip *strip);
|
||||
void change_strip(EggMesherStrip *from, EggMesherStrip *to);
|
||||
|
||||
INLINE bool contains_vertex(int vi) const;
|
||||
|
||||
INLINE bool matches(const EggMesherEdge &other) const;
|
||||
|
||||
INLINE EggMesherEdge *common_ptr();
|
||||
|
||||
INLINE bool operator == (const EggMesherEdge &other) const;
|
||||
INLINE bool operator != (const EggMesherEdge &other) const;
|
||||
INLINE bool operator < (const EggMesherEdge &other) const;
|
||||
|
||||
INLINE double compute_length(const EggVertexPool *vertex_pool) const;
|
||||
INLINE LVecBase3d compute_box(const EggVertexPool *vertex_pool) const;
|
||||
|
||||
void output(ostream &out) const;
|
||||
|
||||
int _vi_a, _vi_b;
|
||||
|
||||
typedef plist<EggMesherStrip *> Strips;
|
||||
Strips _strips;
|
||||
EggMesherEdge *_opposite;
|
||||
};
|
||||
|
||||
INLINE ostream &
|
||||
operator << (ostream &out, const EggMesherEdge &edge) {
|
||||
edge.output(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
#include "eggMesherEdge.I"
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,182 @@
|
|||
// Filename: eggMesherStrip.I
|
||||
// Created by: drose (13Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesherStrip::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE EggMesherStrip::
|
||||
EggMesherStrip() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesherStrip::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE EggMesherStrip::
|
||||
EggMesherStrip(const EggMesherStrip ©) :
|
||||
_prims(copy._prims),
|
||||
_edges(copy._edges),
|
||||
_verts(copy._verts),
|
||||
_type(copy._type),
|
||||
_index(copy._index),
|
||||
_status(copy._status),
|
||||
_planar(copy._planar),
|
||||
_plane_normal(copy._plane_normal),
|
||||
_plane_offset(copy._plane_offset),
|
||||
_row_id(copy._row_id)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesherStrip::is_coplanar_with
|
||||
// Access: Public
|
||||
// Description: Returns true if the strip and the other strip are
|
||||
// coplanar, within the indicated threshold. See
|
||||
// coplanarity().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool EggMesherStrip::
|
||||
is_coplanar_with(const EggMesherStrip &other, float threshold) const {
|
||||
return (coplanarity(other) <= threshold);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesherStrip::coplanarity
|
||||
// Access: Public
|
||||
// Description: Returns the degree to which the two strips are
|
||||
// coplanar. 0.0 is exactly coplanar; numbers somewhat
|
||||
// larger than zero indicate less coplanar. 1.0 is
|
||||
// at right angles; 2.0 is exactly backfacing. If
|
||||
// either strip is not itself planar, 3.0 is returned.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float EggMesherStrip::
|
||||
coplanarity(const EggMesherStrip &other) const {
|
||||
if (_planar && other._planar) {
|
||||
return 1.0 - dot(_plane_normal, other._plane_normal);
|
||||
} else {
|
||||
return 3.0;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesherStrip::type_category
|
||||
// Access: Public
|
||||
// Description: Returns an integer which gives a heuristic about the
|
||||
// similarity of different strip types. In general,
|
||||
// closer numbers are more similar.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int EggMesherStrip::
|
||||
type_category() const {
|
||||
switch (_type) {
|
||||
case PT_tri:
|
||||
return 1;
|
||||
|
||||
case PT_tristrip:
|
||||
return 2;
|
||||
|
||||
case PT_quad:
|
||||
case PT_quadstrip:
|
||||
return 5;
|
||||
|
||||
default:
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesherStrip::rotate_forward
|
||||
// Access: Public
|
||||
// Description: Rotates a triangle or quad by bringing its first
|
||||
// vertex to the back.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void EggMesherStrip::
|
||||
rotate_forward() {
|
||||
_verts.push_back(_verts.front());
|
||||
_verts.pop_front();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesherStrip::rotate_back
|
||||
// Access: Public
|
||||
// Description: Rotates a triangle or quad by bringing its last
|
||||
// vertex to the front.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void EggMesherStrip::
|
||||
rotate_back() {
|
||||
_verts.push_front(_verts.back());
|
||||
_verts.pop_back();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesherStrip::get_head_edge
|
||||
// Access: Public
|
||||
// Description: Returns an EggMesherEdge which represents the leading
|
||||
// edge in the quadstrip or tristrip. This
|
||||
// EggMesherEdge will not have pointer equality with any
|
||||
// shared EggMesherEdge.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE EggMesherEdge EggMesherStrip::
|
||||
get_head_edge() const {
|
||||
Verts::const_iterator vi = _verts.begin();
|
||||
nassertr(vi != _verts.end(), EggMesherEdge(0, 0));
|
||||
++vi;
|
||||
return EggMesherEdge(_verts.front(), *vi);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesherStrip::get_tail_edge
|
||||
// Access: Public
|
||||
// Description: Returns an EggMesherEdge which represents the
|
||||
// trailing edge in the quadstrip or tristrip. This
|
||||
// EggMesherEdge will not have pointer equality with any
|
||||
// shared EggMesherEdge.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE EggMesherEdge EggMesherStrip::
|
||||
get_tail_edge() const {
|
||||
Verts::const_reverse_iterator vi = _verts.rbegin();
|
||||
nassertr(vi != _verts.rend(), EggMesherEdge(0, 0));
|
||||
++vi;
|
||||
return EggMesherEdge(*vi, _verts.back());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesherStrip::operator ==
|
||||
// Access: Public
|
||||
// Description: Defines equality for strips. This actually tests
|
||||
// only pointer equality; it's used only when removing a
|
||||
// strip from the list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool EggMesherStrip::
|
||||
operator == (const EggMesherStrip &other) const {
|
||||
return this == &other;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesherStrip::operator !=
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool EggMesherStrip::
|
||||
operator != (const EggMesherStrip &other) const {
|
||||
return !operator == (other);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,158 @@
|
|||
// Filename: eggMesherStrip.h
|
||||
// Created by: drose (13Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef EGGMESHERSTRIP_H
|
||||
#define EGGMESHERSTRIP_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "eggVertexPool.h"
|
||||
#include "plist.h"
|
||||
|
||||
class EggMesherEdge;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Class : EggMesherStrip
|
||||
// Description : Represents a triangle strip in progress, as assembled
|
||||
// by the mesher. It might also represent a single
|
||||
// polygon such as a triangle or quad, since that's how
|
||||
// all triangle strips start out.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EggMesherStrip {
|
||||
public:
|
||||
enum PrimType {
|
||||
PT_poly,
|
||||
PT_point,
|
||||
PT_line,
|
||||
PT_tri,
|
||||
PT_tristrip,
|
||||
PT_trifan,
|
||||
PT_quad,
|
||||
PT_quadstrip,
|
||||
PT_linestrip,
|
||||
};
|
||||
|
||||
enum MesherOrigin {
|
||||
MO_unknown,
|
||||
MO_user,
|
||||
MO_firstquad,
|
||||
MO_fanpoly,
|
||||
MO_mate
|
||||
};
|
||||
|
||||
INLINE EggMesherStrip();
|
||||
EggMesherStrip(const EggPrimitive *prim, int index, const EggVertexPool *vertex_pool);
|
||||
INLINE EggMesherStrip(const EggMesherStrip ©);
|
||||
|
||||
PT(EggPrimitive) make_prim(const EggVertexPool *vertex_pool);
|
||||
|
||||
void measure_sheet(const EggMesherEdge *edge, int new_row,
|
||||
int &num_prims, int &num_rows,
|
||||
int first_row_id, int this_row_id,
|
||||
int this_row_distance);
|
||||
void cut_sheet(int first_row_id, int do_mate,
|
||||
const EggVertexPool *vertex_pool);
|
||||
|
||||
bool mate(const EggVertexPool *vertex_pool);
|
||||
bool find_ideal_mate(EggMesherStrip *&mate, EggMesherEdge *&common_edge,
|
||||
const EggVertexPool *vertex_pool);
|
||||
static bool mate_pieces(EggMesherEdge *common_edge, EggMesherStrip &front,
|
||||
EggMesherStrip &back, const EggVertexPool *vertex_pool);
|
||||
static bool mate_strips(EggMesherEdge *common_edge, EggMesherStrip &front,
|
||||
EggMesherStrip &back, PrimType type);
|
||||
static bool must_invert(const EggMesherStrip &front, const EggMesherStrip &back,
|
||||
bool will_reverse_back, PrimType type);
|
||||
static bool convex_quad(EggMesherEdge *common_edge, EggMesherStrip &front,
|
||||
EggMesherStrip &back, const EggVertexPool *vertex_pool);
|
||||
|
||||
int count_neighbors() const;
|
||||
void output_neighbors(ostream &out) const;
|
||||
|
||||
INLINE bool is_coplanar_with(const EggMesherStrip &other, float threshold) const;
|
||||
INLINE float coplanarity(const EggMesherStrip &other) const;
|
||||
INLINE int type_category() const;
|
||||
|
||||
int find_uncommon_vertex(const EggMesherEdge *edge) const;
|
||||
const EggMesherEdge *find_opposite_edge(int vi) const;
|
||||
const EggMesherEdge *find_opposite_edge(const EggMesherEdge *edge) const;
|
||||
const EggMesherEdge *find_adjacent_edge(const EggMesherEdge *edge) const;
|
||||
|
||||
INLINE void rotate_forward();
|
||||
INLINE void rotate_back();
|
||||
void rotate_to_front(const EggMesherEdge *edge);
|
||||
void rotate_to_back(const EggMesherEdge *edge);
|
||||
bool can_invert() const;
|
||||
bool invert();
|
||||
|
||||
INLINE EggMesherEdge get_head_edge() const;
|
||||
INLINE EggMesherEdge get_tail_edge() const;
|
||||
|
||||
bool is_odd() const;
|
||||
bool would_reverse_tail(PrimType want_type) const;
|
||||
void convert_to_type(PrimType want_type);
|
||||
|
||||
void combine_edges(EggMesherStrip &other, int remove_sides);
|
||||
void remove_all_edges();
|
||||
|
||||
// ptr equality
|
||||
INLINE bool operator == (const EggMesherStrip &other) const;
|
||||
INLINE bool operator != (const EggMesherStrip &other) const;
|
||||
|
||||
bool pick_mate(const EggMesherStrip &a_strip, const EggMesherStrip &b_strip,
|
||||
const EggMesherEdge &a_edge, const EggMesherEdge &b_edge,
|
||||
const EggVertexPool *vertex_pool) const;
|
||||
|
||||
bool pick_sheet_mate(const EggMesherStrip &a_strip,
|
||||
const EggMesherStrip &b_strip) const;
|
||||
|
||||
void output(ostream &out) const;
|
||||
|
||||
typedef plist<CPT(EggPrimitive) > Prims;
|
||||
typedef plist<EggMesherEdge *> Edges;
|
||||
typedef plist<int> Verts;
|
||||
|
||||
Prims _prims;
|
||||
Edges _edges;
|
||||
Verts _verts;
|
||||
|
||||
enum MesherStatus {
|
||||
MS_alive,
|
||||
MS_dead,
|
||||
MS_done,
|
||||
MS_paired
|
||||
};
|
||||
|
||||
PrimType _type;
|
||||
int _index;
|
||||
MesherStatus _status;
|
||||
|
||||
int _planar;
|
||||
Normald _plane_normal;
|
||||
float _plane_offset;
|
||||
int _row_id, _row_distance;
|
||||
MesherOrigin _origin;
|
||||
};
|
||||
|
||||
INLINE ostream &
|
||||
operator << (ostream &out, const EggMesherStrip &strip) {
|
||||
strip.output(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
#include "eggMesherStrip.I"
|
||||
|
||||
#endif
|
||||
|
|
@ -88,6 +88,23 @@ operator != (const EggMorph<Parameter> &other) const {
|
|||
return !operator == (other);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMorph::compare_to
|
||||
// Access: Public
|
||||
// Description: compare_to() compares a different space than the
|
||||
// operator methods, which only check the name.
|
||||
// compare_to() compares the name and the value as well.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class Parameter>
|
||||
INLINE int EggMorph<Parameter>::
|
||||
compare_to(const EggMorph<Parameter> &other) const {
|
||||
int compare = strcmp(get_name().c_str(), other.get_name().c_str());
|
||||
if (compare != 0) {
|
||||
return compare;
|
||||
}
|
||||
return _offset.compare_to(other._offset);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMorphVertex output operator
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@ public:
|
|||
INLINE bool operator == (const EggMorph<Parameter> &other) const;
|
||||
INLINE bool operator != (const EggMorph<Parameter> &other) const;
|
||||
|
||||
INLINE int compare_to(const EggMorph<Parameter> &other) const;
|
||||
|
||||
private:
|
||||
Parameter _offset;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ INLINE EggMorphList<MorphType>::
|
|||
template<class MorphType>
|
||||
INLINE bool EggMorphList<MorphType>::
|
||||
operator == (const EggMorphList<MorphType> &other) const {
|
||||
return (_morphs == other._morphs);
|
||||
return compare_to(other) == 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -79,7 +79,7 @@ operator == (const EggMorphList<MorphType> &other) const {
|
|||
template<class MorphType>
|
||||
INLINE bool EggMorphList<MorphType>::
|
||||
operator != (const EggMorphList<MorphType> &other) const {
|
||||
return (_morphs != other._morphs);
|
||||
return compare_to(other) != 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -90,7 +90,27 @@ operator != (const EggMorphList<MorphType> &other) const {
|
|||
template<class MorphType>
|
||||
INLINE bool EggMorphList<MorphType>::
|
||||
operator < (const EggMorphList<MorphType> &other) const {
|
||||
return (_morphs < other._morphs);
|
||||
return compare_to(other) < 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMorphList::compare_to
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class MorphType>
|
||||
int EggMorphList<MorphType>::
|
||||
compare_to(const EggMorphList<MorphType> &other) const {
|
||||
if (_morphs.size() < other._morphs.size()) {
|
||||
return (int)_morphs.size() - (int)other._morphs.size();
|
||||
}
|
||||
for (size_t i = 0; i < _morphs.size(); i++) {
|
||||
int compare = _morphs[i].compare_to(other._morphs[i]);
|
||||
if (compare < 0) {
|
||||
return compare;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ public:
|
|||
INLINE bool operator == (const EggMorphList<MorphType> &other) const;
|
||||
INLINE bool operator != (const EggMorphList<MorphType> &other) const;
|
||||
INLINE bool operator < (const EggMorphList<MorphType> &other) const;
|
||||
int compare_to(const EggMorphList<MorphType> &other) const;
|
||||
|
||||
INLINE iterator begin();
|
||||
INLINE const_iterator begin() const;
|
||||
|
|
|
|||
|
|
@ -17,10 +17,9 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggPolygon::Constructor
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE EggPolygon::
|
||||
|
|
@ -29,7 +28,7 @@ EggPolygon(const string &name) : EggPrimitive(name) {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggPolygon::Copy constructor
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE EggPolygon::
|
||||
|
|
@ -38,7 +37,7 @@ EggPolygon(const EggPolygon ©) : EggPrimitive(copy) {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggPolygon::Copy assignment operator
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE EggPolygon &EggPolygon::
|
||||
|
|
@ -49,7 +48,7 @@ operator = (const EggPolygon ©) {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggPolygon::recompute_polygon_normal
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description: Recalculates the normal according to the order of the
|
||||
// vertices, and sets it. Returns true if the normal is
|
||||
// computed correctly, or false if the polygon is
|
||||
|
|
@ -68,7 +67,7 @@ recompute_polygon_normal(CoordinateSystem cs) {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggPolygon::triangulate_into
|
||||
// Access: Public
|
||||
// Access: Published
|
||||
// Description: Subdivides the polygon into triangles and adds each
|
||||
// one to the indicated container. If the polygon is
|
||||
// already a triangle, adds an exact copy of the polygon
|
||||
|
|
|
|||
|
|
@ -326,7 +326,7 @@ operator [] (int index) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE EggPrimitive::iterator EggPrimitive::
|
||||
insert(iterator position, EggVertex *x) {
|
||||
prepare_add_vertex(x);
|
||||
prepare_add_vertex(x, position - _vertices.begin(), _vertices.size() + 1);
|
||||
iterator i = _vertices.insert((Vertices::iterator &)position, x);
|
||||
x->test_pref_integrity();
|
||||
test_vref_integrity();
|
||||
|
|
@ -340,7 +340,7 @@ insert(iterator position, EggVertex *x) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE EggPrimitive::iterator EggPrimitive::
|
||||
erase(iterator position) {
|
||||
prepare_remove_vertex(*position);
|
||||
prepare_remove_vertex(*position, position - _vertices.begin(), _vertices.size());
|
||||
iterator i = _vertices.erase((Vertices::iterator &)position);
|
||||
test_vref_integrity();
|
||||
return i;
|
||||
|
|
@ -357,8 +357,10 @@ INLINE void EggPrimitive::
|
|||
replace(iterator position, EggVertex *x) {
|
||||
nassertv(position != end());
|
||||
|
||||
prepare_remove_vertex(*position);
|
||||
prepare_add_vertex(x);
|
||||
// We pass -1 for i and n so that EggCompositePrimitive won't try to
|
||||
// adjust its _components list.
|
||||
prepare_remove_vertex(*position, -1, -1);
|
||||
prepare_add_vertex(x, -1, -1);
|
||||
*(Vertices::iterator &)position = x;
|
||||
|
||||
x->test_pref_integrity();
|
||||
|
|
|
|||
|
|
@ -190,6 +190,17 @@ determine_bin() {
|
|||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggPrimitive::copy_attributes
|
||||
// Access: Published
|
||||
// Description: Copies the rendering attributes from the indicated
|
||||
// primitive.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggPrimitive::
|
||||
copy_attributes(const EggAttributes &other) {
|
||||
EggAttributes::operator = (other);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggPrimitive::copy_attributes
|
||||
// Access: Published
|
||||
|
|
@ -292,6 +303,7 @@ remove_doubled_verts(bool closed) {
|
|||
Vertices::iterator vi, vlast;
|
||||
vi = _vertices.begin();
|
||||
new_vertices.push_back(*vi);
|
||||
int num_removed = 0;
|
||||
|
||||
vlast = vi;
|
||||
++vi;
|
||||
|
|
@ -299,7 +311,9 @@ remove_doubled_verts(bool closed) {
|
|||
if ((*vi) != (*vlast)) {
|
||||
new_vertices.push_back(*vi);
|
||||
} else {
|
||||
prepare_remove_vertex(*vi);
|
||||
prepare_remove_vertex(*vi, vi - _vertices.begin() - num_removed,
|
||||
_vertices.size() - num_removed);
|
||||
num_removed++;
|
||||
}
|
||||
vlast = vi;
|
||||
++vi;
|
||||
|
|
@ -312,7 +326,8 @@ remove_doubled_verts(bool closed) {
|
|||
// remove the vertex from the end if it's a repeat of the
|
||||
// beginning.
|
||||
while (_vertices.size() > 1 && _vertices.back() == _vertices.front()) {
|
||||
prepare_remove_vertex(_vertices.back());
|
||||
prepare_remove_vertex(_vertices.back(), _vertices.size() - 1,
|
||||
_vertices.size());
|
||||
_vertices.pop_back();
|
||||
}
|
||||
}
|
||||
|
|
@ -331,6 +346,7 @@ void EggPrimitive::
|
|||
remove_nonunique_verts() {
|
||||
Vertices::iterator vi, vj;
|
||||
Vertices new_vertices;
|
||||
int num_removed = 0;
|
||||
|
||||
for (vi = _vertices.begin(); vi != _vertices.end(); ++vi) {
|
||||
bool okflag = true;
|
||||
|
|
@ -340,7 +356,9 @@ remove_nonunique_verts() {
|
|||
if (okflag) {
|
||||
new_vertices.push_back(*vi);
|
||||
} else {
|
||||
prepare_remove_vertex(*vi);
|
||||
prepare_remove_vertex(*vi, vi - _vertices.begin() - num_removed,
|
||||
_vertices.size() - num_removed);
|
||||
num_removed++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -405,8 +423,11 @@ has_normals() const {
|
|||
EggPrimitive::iterator EggPrimitive::
|
||||
erase(iterator first, iterator last) {
|
||||
iterator i;
|
||||
int num_removed = 0;
|
||||
for (i = first; i != last; ++i) {
|
||||
prepare_remove_vertex(*i);
|
||||
prepare_remove_vertex(*i, first - _vertices.begin(),
|
||||
_vertices.size() - num_removed);
|
||||
num_removed++;
|
||||
}
|
||||
iterator result = _vertices.erase((Vertices::iterator &)first,
|
||||
(Vertices::iterator &)last);
|
||||
|
|
@ -423,7 +444,7 @@ erase(iterator first, iterator last) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
EggVertex *EggPrimitive::
|
||||
add_vertex(EggVertex *vertex) {
|
||||
prepare_add_vertex(vertex);
|
||||
prepare_add_vertex(vertex, _vertices.size(), _vertices.size() + 1);
|
||||
_vertices.push_back(vertex);
|
||||
|
||||
vertex->test_pref_integrity();
|
||||
|
|
@ -528,14 +549,18 @@ test_vref_integrity() const {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggPrimitive::prepare_add_vertex
|
||||
// Access: Private
|
||||
// Access: Protected, Virtual
|
||||
// Description: Marks the vertex as belonging to the primitive. This
|
||||
// is an internal function called by the STL-like
|
||||
// functions push_back() and insert(), in preparation
|
||||
// for actually adding the vertex.
|
||||
//
|
||||
// i indicates the new position of the vertex in the
|
||||
// list; n indicates the new number of vertices after
|
||||
// the operation has completed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggPrimitive::
|
||||
prepare_add_vertex(EggVertex *vertex) {
|
||||
prepare_add_vertex(EggVertex *vertex, int i, int n) {
|
||||
// We can't test integrity within this function, because it might be
|
||||
// called when the primitive is in an incomplete state.
|
||||
|
||||
|
|
@ -554,17 +579,21 @@ prepare_add_vertex(EggVertex *vertex) {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggPrimitive::prepare_remove_vertex
|
||||
// Access: Private
|
||||
// Access: Protected, Virtual
|
||||
// Description: Marks the vertex as removed from the primitive. This
|
||||
// is an internal function called by the STL-like
|
||||
// functions pop_back() and erase(), in preparation for
|
||||
// actually doing the removal.
|
||||
//
|
||||
// i indicates the former position of the vertex in the
|
||||
// list; n indicates the current number of vertices
|
||||
// before the operation has completed.
|
||||
//
|
||||
// It is an error to attempt to remove a vertex that is
|
||||
// not already a vertex of this primitive.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggPrimitive::
|
||||
prepare_remove_vertex(EggVertex *vertex) {
|
||||
prepare_remove_vertex(EggVertex *vertex, int i, int n) {
|
||||
// We can't test integrity within this function, because it might be
|
||||
// called when the primitive is in an incomplete state.
|
||||
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ PUBLISHED:
|
|||
INLINE void set_bface_flag(bool flag);
|
||||
INLINE bool get_bface_flag() const;
|
||||
|
||||
void copy_attributes(const EggAttributes &other);
|
||||
void copy_attributes(const EggPrimitive &other);
|
||||
|
||||
bool has_vertex_normal() const;
|
||||
|
|
@ -166,14 +167,14 @@ PUBLISHED:
|
|||
void test_vref_integrity() const { }
|
||||
#endif // NDEBUG
|
||||
|
||||
private:
|
||||
protected:
|
||||
Vertices _vertices;
|
||||
|
||||
// Don't try to use these private functions. User code should add
|
||||
// and remove vertices via add_vertex()/remove_vertex(), or via the
|
||||
// STL-like push_back()/pop_back() or insert()/erase(), above.
|
||||
void prepare_add_vertex(EggVertex *vertex);
|
||||
void prepare_remove_vertex(EggVertex *vertex);
|
||||
virtual void prepare_add_vertex(EggVertex *vertex, int i, int n);
|
||||
virtual void prepare_remove_vertex(EggVertex *vertex, int i, int n);
|
||||
|
||||
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
// Filename: eggTriangleStrip.I
|
||||
// Created by: drose (13Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggTriangleStrip::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE EggTriangleStrip::
|
||||
EggTriangleStrip(const string &name) : EggCompositePrimitive(name) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggTriangleStrip::Copy constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE EggTriangleStrip::
|
||||
EggTriangleStrip(const EggTriangleStrip ©) : EggCompositePrimitive(copy) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggTriangleStrip::Copy assignment operator
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE EggTriangleStrip &EggTriangleStrip::
|
||||
operator = (const EggTriangleStrip ©) {
|
||||
EggCompositePrimitive::operator = (copy);
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
// Filename: eggTriangleStrip.cxx
|
||||
// Created by: drose (13Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "eggTriangleStrip.h"
|
||||
#include "eggGroupNode.h"
|
||||
#include "eggPolygon.h"
|
||||
#include "plane.h"
|
||||
|
||||
#include "indent.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
TypeHandle EggTriangleStrip::_type_handle;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggTriangleStrip::cleanup
|
||||
// Access: Published, Virtual
|
||||
// Description: Cleans up modeling errors in whatever context this
|
||||
// makes sense. For instance, for a polygon, this calls
|
||||
// remove_doubled_verts(true). For a point, it calls
|
||||
// remove_nonunique_verts(). Returns true if the
|
||||
// primitive is valid, or false if it is degenerate.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool EggTriangleStrip::
|
||||
cleanup() {
|
||||
return size() >= 3;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggTriangleStrip::write
|
||||
// Access: Published, Virtual
|
||||
// Description: Writes the triangle strip to the indicated output
|
||||
// stream in Egg format.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggTriangleStrip::
|
||||
write(ostream &out, int indent_level) const {
|
||||
write_header(out, indent_level, "<TriangleStrip>");
|
||||
write_body(out, indent_level+2);
|
||||
indent(out, indent_level) << "}\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggTriangleStrip::triangulate_poly
|
||||
// Access: Protected, Virtual
|
||||
// Description: Fills the container up with EggPolygons that
|
||||
// represent the component triangles of this triangle
|
||||
// strip.
|
||||
//
|
||||
// It is assumed that the EggTriangleStrip is not
|
||||
// already a child of any other group when this function
|
||||
// is called.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggTriangleStrip::
|
||||
do_triangulate(EggGroupNode *container) {
|
||||
if (size() < 3) {
|
||||
return;
|
||||
}
|
||||
iterator vi = begin();
|
||||
EggVertex *v0 = (*vi);
|
||||
++vi;
|
||||
EggVertex *v1 = (*vi);
|
||||
++vi;
|
||||
bool reversed = false;
|
||||
|
||||
for (int i = 0; i < (int)size() - 2; i++) {
|
||||
PT(EggPolygon) poly = new EggPolygon;
|
||||
poly->copy_attributes(*this);
|
||||
const EggAttributes *attrib = get_component(i);
|
||||
if (attrib->has_color()) {
|
||||
poly->set_color(attrib->get_color());
|
||||
}
|
||||
if (attrib->has_normal()) {
|
||||
poly->set_normal(attrib->get_normal());
|
||||
}
|
||||
|
||||
if (reversed) {
|
||||
poly->add_vertex(v1);
|
||||
poly->add_vertex(v0);
|
||||
reversed = false;
|
||||
} else {
|
||||
poly->add_vertex(v0);
|
||||
poly->add_vertex(v1);
|
||||
reversed = true;
|
||||
}
|
||||
poly->add_vertex(*vi);
|
||||
v0 = v1;
|
||||
v1 = *vi;
|
||||
container->add_child(poly);
|
||||
++vi;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
// Filename: eggTriangleStrip.h
|
||||
// Created by: drose (13Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef EGGTRIANGLESTRIP_H
|
||||
#define EGGTRIANGLESTRIP_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "eggCompositePrimitive.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : EggTriangleStrip
|
||||
// Description : A connected strip of triangles. This does not
|
||||
// normally appear in an egg file; it is typically
|
||||
// generated as a result of meshing.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDAEGG EggTriangleStrip : public EggCompositePrimitive {
|
||||
PUBLISHED:
|
||||
INLINE EggTriangleStrip(const string &name = "");
|
||||
INLINE EggTriangleStrip(const EggTriangleStrip ©);
|
||||
INLINE EggTriangleStrip &operator = (const EggTriangleStrip ©);
|
||||
|
||||
virtual bool cleanup();
|
||||
|
||||
virtual void write(ostream &out, int indent_level) const;
|
||||
|
||||
protected:
|
||||
virtual void do_triangulate(EggGroupNode *container);
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
EggCompositePrimitive::init_type();
|
||||
register_type(_type_handle, "EggTriangleStrip",
|
||||
EggCompositePrimitive::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#include "eggTriangleStrip.I"
|
||||
|
||||
#endif
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
#include "eggBin.cxx"
|
||||
#include "eggBinMaker.cxx"
|
||||
#include "eggComment.cxx"
|
||||
#include "eggCompositePrimitive.cxx"
|
||||
#include "eggCoordinateSystem.cxx"
|
||||
#include "eggCurve.cxx"
|
||||
#include "eggData.cxx"
|
||||
|
|
@ -15,6 +16,9 @@
|
|||
#include "eggLine.cxx"
|
||||
#include "eggMaterial.cxx"
|
||||
#include "eggMaterialCollection.cxx"
|
||||
#include "eggMesher.cxx"
|
||||
#include "eggMesherEdge.cxx"
|
||||
#include "eggMesherStrip.cxx"
|
||||
#include "eggMiscFuncs.cxx"
|
||||
#include "eggMorphList.cxx"
|
||||
#include "eggNamedObject.cxx"
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include "eggTexture.cxx"
|
||||
#include "eggTextureCollection.cxx"
|
||||
#include "eggTransform3d.cxx"
|
||||
#include "eggTriangleStrip.cxx"
|
||||
#include "eggUserData.cxx"
|
||||
#include "eggUtilities.cxx"
|
||||
#include "eggVertex.cxx"
|
||||
|
|
|
|||
|
|
@ -371,6 +371,10 @@ NUMERIC ([+-]?(([0-9]+[.]?)|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
|
|||
accept();
|
||||
return COMMENT;
|
||||
}
|
||||
"<COMPONENT>" {
|
||||
accept();
|
||||
return COMPONENT;
|
||||
}
|
||||
"<COORDINATESYSTEM>" {
|
||||
accept();
|
||||
return COORDSYSTEM;
|
||||
|
|
@ -599,6 +603,14 @@ NUMERIC ([+-]?(([0-9]+[.]?)|([0-9]*[.][0-9]+))([eE][+-]?[0-9]+)?)
|
|||
accept();
|
||||
return TREF;
|
||||
}
|
||||
"<TRIANGLEFAN>" {
|
||||
accept();
|
||||
return TRIANGLEFAN;
|
||||
}
|
||||
"<TRIANGLESTRIP>" {
|
||||
accept();
|
||||
return TRIANGLESTRIP;
|
||||
}
|
||||
"<TRIM>" {
|
||||
accept();
|
||||
return TRIM;
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@
|
|||
#include "eggVertexPool.h"
|
||||
#include "eggVertexUV.h"
|
||||
#include "eggPolygon.h"
|
||||
#include "eggCompositePrimitive.h"
|
||||
#include "eggTriangleStrip.h"
|
||||
#include "eggPoint.h"
|
||||
#include "eggLine.h"
|
||||
#include "eggNurbsSurface.h"
|
||||
|
|
@ -144,7 +146,7 @@ egg_cleanup_parser() {
|
|||
%token <_string> STRING
|
||||
|
||||
%token BEZIERCURVE BFACE BILLBOARD BILLBOARDCENTER BUNDLE CLOSED
|
||||
%token COLLIDE COMMENT
|
||||
%token COLLIDE COMMENT COMPONENT
|
||||
%token COORDSYSTEM CV DART
|
||||
%token DNORMAL DRGBA DUV DXYZ DCS DISTANCE DTREF
|
||||
%token DYNAMICVERTEXPOOL EXTERNAL_FILE
|
||||
|
|
@ -155,7 +157,8 @@ egg_cleanup_parser() {
|
|||
%token OUTTANGENT POINTLIGHT POLYGON REF RGBA ROTATE ROTX ROTY ROTZ
|
||||
%token SANIM SCALAR SCALE SEQUENCE SHADING SWITCH SWITCHCONDITION
|
||||
%token TABLE TABLE_V TAG TEXLIST TEXTURE TLENGTHS TRANSFORM TRANSLATE
|
||||
%token TREF TRIM TXT UKNOTS UV VKNOTS VERTEX VERTEXANIM
|
||||
%token TREF TRIANGLEFAN TRIANGLESTRIP
|
||||
%token TRIM TXT UKNOTS UV VKNOTS VERTEX VERTEXANIM
|
||||
%token VERTEXPOOL VERTEXREF
|
||||
%token XFMANIM XFMSANIM
|
||||
|
||||
|
|
@ -179,6 +182,7 @@ egg_cleanup_parser() {
|
|||
%type <_egg> joint
|
||||
%type <_egg> line
|
||||
%type <_egg> polygon
|
||||
%type <_egg> trianglestrip
|
||||
%type <_egg> point_light
|
||||
%type <_egg> nurbs_surface
|
||||
%type <_egg> nurbs_curve
|
||||
|
|
@ -247,6 +251,7 @@ node:
|
|||
| joint
|
||||
| instance
|
||||
| polygon
|
||||
| trianglestrip
|
||||
| point_light
|
||||
| line
|
||||
| nurbs_surface
|
||||
|
|
@ -1590,6 +1595,25 @@ polygon:
|
|||
}
|
||||
;
|
||||
|
||||
/*
|
||||
* trianglestrip
|
||||
*
|
||||
* enter:
|
||||
* exit: returns a new EggTriangleStrip.
|
||||
*
|
||||
*/
|
||||
trianglestrip:
|
||||
TRIANGLESTRIP optional_name
|
||||
{
|
||||
egg_stack.push_back(new EggTriangleStrip($2));
|
||||
}
|
||||
'{' primitive_body '}'
|
||||
{
|
||||
$$ = egg_stack.back();
|
||||
egg_stack.pop_back();
|
||||
}
|
||||
;
|
||||
|
||||
/*
|
||||
* point_light
|
||||
*
|
||||
|
|
@ -1667,6 +1691,19 @@ nurbs_curve:
|
|||
;
|
||||
|
||||
|
||||
/*
|
||||
* primitive_component_body
|
||||
*
|
||||
* enter: TOS is EggPrimitive.
|
||||
* exit: primitive attributes and vertices have been filled.
|
||||
*
|
||||
*/
|
||||
primitive_component_body:
|
||||
empty
|
||||
| primitive_component_body NORMAL '{' primitive_normal_body '}'
|
||||
| primitive_component_body RGBA '{' primitive_color_body '}'
|
||||
;
|
||||
|
||||
/*
|
||||
* primitive_body
|
||||
*
|
||||
|
|
@ -1676,6 +1713,28 @@ nurbs_curve:
|
|||
*/
|
||||
primitive_body:
|
||||
empty
|
||||
| primitive_body COMPONENT '{' primitive_component_body '}'
|
||||
| primitive_body COMPONENT integer '{'
|
||||
{
|
||||
if (!egg_stack.back()->is_of_type(EggCompositePrimitive::get_class_type())) {
|
||||
eggyyerror("Not a composite primitive; components are not allowed here.");
|
||||
} else {
|
||||
PT(EggCompositePrimitive) comp = DCAST(EggCompositePrimitive, egg_stack.back());
|
||||
if ($3 < 0 || $3 >= comp->get_num_components()) {
|
||||
eggyyerror("Invalid component number");
|
||||
}
|
||||
// We temporarily add an EggPolygon to the stack, just to receive
|
||||
// the component attributes.
|
||||
egg_stack.push_back(new EggPolygon);
|
||||
}
|
||||
}
|
||||
primitive_component_body '}'
|
||||
{
|
||||
PT(EggPrimitive) prim = DCAST(EggPrimitive, egg_stack.back());
|
||||
egg_stack.pop_back();
|
||||
PT(EggCompositePrimitive) comp = DCAST(EggCompositePrimitive, egg_stack.back());
|
||||
comp->set_component($3, prim);
|
||||
}
|
||||
| primitive_body TREF '{' primitive_tref_body '}'
|
||||
| primitive_body TEXTURE '{' primitive_texture_body '}'
|
||||
| primitive_body MREF '{' primitive_material_body '}'
|
||||
|
|
|
|||
|
|
@ -28,32 +28,10 @@
|
|||
ConfigureDef(config_egg2pg);
|
||||
NotifyCategoryDef(egg2pg, "");
|
||||
|
||||
ConfigVariableBool egg_mesh
|
||||
("egg-mesh", true);
|
||||
ConfigVariableBool egg_retesselate_coplanar
|
||||
("egg-retesselate-coplanar", true);
|
||||
ConfigVariableBool egg_unroll_fans
|
||||
("egg-unroll-fans", true);
|
||||
ConfigVariableBool egg_show_tstrips
|
||||
("egg-show-tstrips", false);
|
||||
ConfigVariableBool egg_show_qsheets
|
||||
("egg-show-qsheets", false);
|
||||
ConfigVariableBool egg_show_quads
|
||||
("egg-show-quads", false);
|
||||
ConfigVariableBool egg_show_normals
|
||||
("egg-show-normals", false);
|
||||
ConfigVariableDouble egg_normal_scale
|
||||
("egg-normal-scale", 1.0);
|
||||
ConfigVariableBool egg_subdivide_polys
|
||||
("egg-subdivide-polys", true);
|
||||
ConfigVariableBool egg_consider_fans
|
||||
("egg-consider-fans", true);
|
||||
ConfigVariableDouble egg_max_tfan_angle
|
||||
("egg-max-tfan-angle", 40.0);
|
||||
ConfigVariableInt egg_min_tfan_tris
|
||||
("egg-min-tfan-tris", 4);
|
||||
ConfigVariableDouble egg_coplanar_threshold
|
||||
("egg-coplanar-threshold", 0.01);
|
||||
ConfigVariableBool egg_show_normals
|
||||
("egg-show-normals", false);
|
||||
|
||||
ConfigVariableEnum<CoordinateSystem> egg_coordinate_system
|
||||
("egg-coordinate-system", CS_default);
|
||||
|
|
|
|||
|
|
@ -33,20 +33,8 @@
|
|||
ConfigureDecl(config_egg2pg, EXPCL_PANDAEGG, EXPTP_PANDAEGG);
|
||||
NotifyCategoryDecl(egg2pg, EXPCL_PANDAEGG, EXPTP_PANDAEGG);
|
||||
|
||||
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_show_normals;
|
||||
extern EXPCL_PANDAEGG ConfigVariableDouble egg_normal_scale;
|
||||
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 ConfigVariableBool egg_show_normals;
|
||||
extern EXPCL_PANDAEGG ConfigVariableEnum<CoordinateSystem> egg_coordinate_system;
|
||||
extern EXPCL_PANDAEGG ConfigVariableBool egg_ignore_mipmaps;
|
||||
extern EXPCL_PANDAEGG ConfigVariableBool egg_ignore_filters;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include "eggRenderState.h"
|
||||
#include "egg_parametrics.h"
|
||||
#include "config_egg2pg.h"
|
||||
#include "config_egg.h"
|
||||
#include "nodePath.h"
|
||||
#include "renderState.h"
|
||||
#include "transformState.h"
|
||||
|
|
@ -38,6 +39,7 @@
|
|||
#include "qpgeomVertexIterator.h"
|
||||
#include "qpgeom.h"
|
||||
#include "qpgeomTriangles.h"
|
||||
#include "qpgeomTristrips.h"
|
||||
#include "sequenceNode.h"
|
||||
#include "switchNode.h"
|
||||
#include "portalNode.h"
|
||||
|
|
@ -55,6 +57,7 @@
|
|||
#include "eggGroupNode.h"
|
||||
#include "eggGroup.h"
|
||||
#include "eggPolygon.h"
|
||||
#include "eggTriangleStrip.h"
|
||||
#include "eggBin.h"
|
||||
#include "eggTable.h"
|
||||
#include "eggBinner.h"
|
||||
|
|
@ -1442,8 +1445,16 @@ make_polyset(EggBin *egg_bin, PandaNode *parent) {
|
|||
PT(qpGeom) geom = new qpGeom;
|
||||
geom->set_vertex_data(vertex_data);
|
||||
|
||||
// Automatically triangulate any higher-order polygons we might have.
|
||||
egg_bin->triangulate_polygons(true);
|
||||
if (egg_mesh) {
|
||||
// If we're using the mesher, mesh now.
|
||||
egg_bin->mesh_triangles(0);
|
||||
egg_bin->write(cerr, 0);
|
||||
|
||||
} else {
|
||||
// If we're not using the mesher, at least triangulate any
|
||||
// higher-order polygons we might have.
|
||||
egg_bin->triangulate_polygons(EggGroupNode::T_convex);
|
||||
}
|
||||
|
||||
// Now create a handful of GeomPrimitives corresponding to the
|
||||
// various types of primitives we have.
|
||||
|
|
@ -1461,6 +1472,8 @@ make_polyset(EggBin *egg_bin, PandaNode *parent) {
|
|||
qpGeomPrimitive *primitive = (*pi).second;
|
||||
geom->add_primitive(primitive);
|
||||
}
|
||||
|
||||
geom->write(cerr);
|
||||
|
||||
// Now, is our parent node a GeomNode, or just an ordinary
|
||||
// PandaNode? If it's a GeomNode, we can add the new Geom directly
|
||||
|
|
@ -1940,6 +1953,8 @@ make_primitive(EggPrimitive *egg_prim, EggLoader::Primitives &primitives) {
|
|||
if (egg_prim->size() == 3) {
|
||||
primitive = new qpGeomTriangles;
|
||||
}
|
||||
} else if (egg_prim->is_of_type(EggTriangleStrip::get_class_type())) {
|
||||
primitive = new qpGeomTristrips;
|
||||
}
|
||||
|
||||
if (primitive == NULL) {
|
||||
|
|
|
|||
|
|
@ -196,7 +196,7 @@ write(ostream &out, int indent_level) const {
|
|||
for (pi = cdata->_primitives.begin();
|
||||
pi != cdata->_primitives.end();
|
||||
++pi) {
|
||||
(*pi)->write(out, cdata->_data, indent_level);
|
||||
(*pi)->write(out, indent_level);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -412,7 +412,7 @@ decompose() {
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomPrimitive::
|
||||
output(ostream &out, const qpGeomVertexData *vertex_data) const {
|
||||
output(ostream &out) const {
|
||||
out << get_type() << ", " << get_num_primitives()
|
||||
<< ", " << get_num_vertices();
|
||||
}
|
||||
|
|
@ -423,8 +423,7 @@ output(ostream &out, const qpGeomVertexData *vertex_data) const {
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomPrimitive::
|
||||
write(ostream &out, const qpGeomVertexData *vertex_data,
|
||||
int indent_level) const {
|
||||
write(ostream &out, int indent_level) const {
|
||||
indent(out, indent_level)
|
||||
<< get_type() << ":\n";
|
||||
int num_primitives = get_num_primitives();
|
||||
|
|
|
|||
|
|
@ -91,9 +91,8 @@ PUBLISHED:
|
|||
|
||||
PT(qpGeomPrimitive) decompose();
|
||||
|
||||
virtual void output(ostream &out, const qpGeomVertexData *vertex_data) const;
|
||||
virtual void write(ostream &out, const qpGeomVertexData *vertex_data,
|
||||
int indent_level) const;
|
||||
virtual void output(ostream &out) const;
|
||||
virtual void write(ostream &out, int indent_level) const;
|
||||
|
||||
void clear_cache();
|
||||
|
||||
|
|
|
|||
|
|
@ -113,6 +113,8 @@ decompose_impl() {
|
|||
}
|
||||
}
|
||||
|
||||
triangles->write(cerr, 0);
|
||||
|
||||
return triangles.p();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -63,6 +63,16 @@ EggTrans() {
|
|||
"Clean out higher-order polygons by subdividing into triangles.",
|
||||
&EggTrans::dispatch_none, &_triangulate_polygons);
|
||||
|
||||
add_option
|
||||
("mesh", "", 0,
|
||||
"Mesh triangles into triangle strips. This is mainly useful as a "
|
||||
"tool to visualize the work that the mesher will do, since triangles "
|
||||
"are automatically meshed whenever an egg file is loaded. Note that, "
|
||||
"unlike the automatic meshing at load time, you are must ensure that "
|
||||
"you do not start out with multiple triangles with different attributes "
|
||||
"(e.g. texture) together in the same group.",
|
||||
&EggTrans::dispatch_none, &_mesh_triangles);
|
||||
|
||||
add_option
|
||||
("N", "", 0,
|
||||
"Standardize and uniquify group names.",
|
||||
|
|
@ -86,10 +96,15 @@ run() {
|
|||
|
||||
if (_triangulate_polygons) {
|
||||
nout << "Triangulating polygons.\n";
|
||||
int num_produced = _data.triangulate_polygons(true);
|
||||
int num_produced = _data.triangulate_polygons(~0);
|
||||
nout << " (" << num_produced << " triangles produced.)\n";
|
||||
}
|
||||
|
||||
if (_mesh_triangles) {
|
||||
nout << "Meshing triangles.\n";
|
||||
_data.mesh_triangles(~0);
|
||||
}
|
||||
|
||||
if (_apply_texmats) {
|
||||
nout << "Applying texture matrices.\n";
|
||||
_data.apply_texmats();
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ public:
|
|||
bool _collapse_equivalent_textures;
|
||||
bool _remove_invalid_primitives;
|
||||
bool _triangulate_polygons;
|
||||
bool _mesh_triangles;
|
||||
bool _standardize_names;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue