egg triagle fans
This commit is contained in:
parent
18169d527e
commit
634a498588
|
|
@ -25,6 +25,7 @@
|
|||
eggMaterialCollection.h \
|
||||
eggMesher.h eggMesher.I \
|
||||
eggMesherEdge.h eggMesherEdge.I \
|
||||
eggMesherFanMaker.h eggMesherFanMaker.I \
|
||||
eggMesherStrip.h eggMesherStrip.I \
|
||||
eggMiscFuncs.I eggMiscFuncs.h \
|
||||
eggMorph.I eggMorph.h eggMorphList.I eggMorphList.h \
|
||||
|
|
@ -38,6 +39,7 @@
|
|||
eggSAnimData.I eggSAnimData.h eggSurface.I eggSurface.h \
|
||||
eggSwitchCondition.h eggTable.I eggTable.h eggTexture.I \
|
||||
eggTexture.h eggTextureCollection.I eggTextureCollection.h \
|
||||
eggTriangleFan.I eggTriangleFan.h \
|
||||
eggTriangleStrip.I eggTriangleStrip.h \
|
||||
eggTransform3d.I eggTransform3d.h \
|
||||
eggUserData.I eggUserData.h \
|
||||
|
|
@ -61,6 +63,7 @@
|
|||
eggMaterialCollection.cxx \
|
||||
eggMesher.cxx \
|
||||
eggMesherEdge.cxx \
|
||||
eggMesherFanMaker.cxx \
|
||||
eggMesherStrip.cxx \
|
||||
eggMiscFuncs.cxx eggMorphList.cxx \
|
||||
eggNamedObject.cxx eggNameUniquifier.cxx eggNode.cxx \
|
||||
|
|
@ -70,6 +73,7 @@
|
|||
eggSAnimData.cxx eggSurface.cxx eggSwitchCondition.cxx \
|
||||
eggTable.cxx eggTexture.cxx eggTextureCollection.cxx \
|
||||
eggTransform3d.cxx \
|
||||
eggTriangleFan.cxx \
|
||||
eggTriangleStrip.cxx \
|
||||
eggUserData.cxx \
|
||||
eggUtilities.cxx eggVertex.cxx eggVertexPool.cxx eggVertexUV.cxx \
|
||||
|
|
@ -101,6 +105,7 @@
|
|||
eggSwitchCondition.h eggTable.I eggTable.h eggTexture.I \
|
||||
eggTexture.h eggTextureCollection.I eggTextureCollection.h \
|
||||
eggTransform3d.I eggTransform3d.h \
|
||||
eggTriangleFan.I eggTriangleFan.h \
|
||||
eggTriangleStrip.I eggTriangleStrip.h \
|
||||
eggUserData.I eggUserData.h \
|
||||
eggUtilities.I eggUtilities.h eggVertex.I eggVertex.h \
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
#include "eggSwitchCondition.h"
|
||||
#include "eggTable.h"
|
||||
#include "eggTexture.h"
|
||||
#include "eggTriangleFan.h"
|
||||
#include "eggTriangleStrip.h"
|
||||
#include "eggUserData.h"
|
||||
#include "eggVertex.h"
|
||||
|
|
@ -75,27 +76,79 @@ ConfigVariableBool egg_support_old_anims
|
|||
"had the convention that the order \"phr\" implied a reversed roll."));
|
||||
|
||||
ConfigVariableBool egg_mesh
|
||||
("egg-mesh", true);
|
||||
("egg-mesh", true,
|
||||
PRC_DESC("Set this true to convert triangles and higher-order polygons "
|
||||
"into triangle strips and triangle fans when an egg file is "
|
||||
"loaded or converted to bam. Set this false just to triangulate "
|
||||
"everything into independent triangles."));
|
||||
|
||||
ConfigVariableBool egg_retesselate_coplanar
|
||||
("egg-retesselate-coplanar", true);
|
||||
("egg-retesselate-coplanar", true,
|
||||
PRC_DESC("If this is true, the egg loader may reverse the "
|
||||
"tesselation direction of a single pair of planar triangles that "
|
||||
"share the same properties, if that will help get a better "
|
||||
"triangle strip. In some rare cases, doing so can distort the "
|
||||
"UV's on a face; turning this off should eliminate that artifact "
|
||||
"(at the cost of less-effective triangle stripping)."));
|
||||
|
||||
ConfigVariableBool egg_unroll_fans
|
||||
("egg-unroll-fans", true);
|
||||
("egg-unroll-fans", true,
|
||||
PRC_DESC("Set this true to allow the egg loader to convert weak triangle "
|
||||
"fans--triangles that share the same vertex but aren't "
|
||||
"connected enough to justify making a triangle fan primitive "
|
||||
"from them--into a series of zig-zag triangles that can make "
|
||||
"a triangle strip that might connect better with its neighbors."));
|
||||
|
||||
ConfigVariableBool egg_show_tstrips
|
||||
("egg-show-tstrips", false);
|
||||
("egg-show-tstrips", false,
|
||||
PRC_DESC("Set this true to color each triangle strip a random color, with "
|
||||
"the leading triangle a little bit darker, so you can visually "
|
||||
"observe the quality of the triangle stripping algorithm."));
|
||||
|
||||
ConfigVariableBool egg_show_qsheets
|
||||
("egg-show-qsheets", false);
|
||||
("egg-show-qsheets", false,
|
||||
PRC_DESC("Set this true to color each quadsheet a random color, so you "
|
||||
"can visually observe the quadsheet algorithm."));
|
||||
|
||||
ConfigVariableBool egg_show_quads
|
||||
("egg-show-quads", false);
|
||||
("egg-show-quads", false,
|
||||
PRC_DESC("Set this true to color each detected quad a random color, so "
|
||||
"you can visually observe the algorithm that unifies pairs of "
|
||||
"triangles into quads (prior to generating triangle strips)."));
|
||||
|
||||
ConfigVariableBool egg_subdivide_polys
|
||||
("egg-subdivide-polys", true);
|
||||
("egg-subdivide-polys", true,
|
||||
PRC_DESC("This is obsolete. In the old Geom implementation, it used to "
|
||||
"be true to force higher-order polygons that were not otherwise "
|
||||
"meshed to be subdivided into triangles. In the new experimental "
|
||||
"Geom implementation, this happens anyway."));
|
||||
|
||||
ConfigVariableBool egg_consider_fans
|
||||
("egg-consider-fans", true);
|
||||
("egg-consider-fans", true,
|
||||
PRC_DESC("Set this true to enable the egg mesher to consider making "
|
||||
"triangle fans out of triangles that are connected at a common "
|
||||
"vertex. This may help if your scene involves lots of such "
|
||||
"connected triangles, but it can also make the overall stripping "
|
||||
"less effective (by interfering with triangle strips)."));
|
||||
|
||||
ConfigVariableDouble egg_max_tfan_angle
|
||||
("egg-max-tfan-angle", 40.0);
|
||||
("egg-max-tfan-angle", 40.0,
|
||||
PRC_DESC("The maximum average angle per triangle to allow in a triangle "
|
||||
"fan. If triangles are larger than this--that is, more loosely "
|
||||
"packed--then we figure a triangle strip is likely to do a "
|
||||
"more effective job than a triangle fan, and the fan maker leaves "
|
||||
"it alone."));
|
||||
|
||||
ConfigVariableInt egg_min_tfan_tris
|
||||
("egg-min-tfan-tris", 4);
|
||||
("egg-min-tfan-tris", 4,
|
||||
PRC_DESC("The minimum number of triangles that must be involved in order "
|
||||
"to generate a triangle fan. Fewer than this is just interrupting "
|
||||
"a triangle strip."));
|
||||
|
||||
ConfigVariableDouble egg_coplanar_threshold
|
||||
("egg-coplanar-threshold", 0.01);
|
||||
("egg-coplanar-threshold", 0.01,
|
||||
PRC_DESC("The numerical threshold below which polygons are considered "
|
||||
"to be coplanar. Determined empirically."));
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: init_libegg
|
||||
|
|
@ -145,6 +198,7 @@ init_libegg() {
|
|||
EggSwitchConditionDistance::init_type();
|
||||
EggTable::init_type();
|
||||
EggTexture::init_type();
|
||||
EggTriangleFan::init_type();
|
||||
EggTriangleStrip::init_type();
|
||||
EggUserData::init_type();
|
||||
EggVertex::init_type();
|
||||
|
|
|
|||
|
|
@ -157,15 +157,32 @@ unify_attributes(EggPrimitive::Shading shading) {
|
|||
shading = get_shading();
|
||||
}
|
||||
|
||||
// Not having a color is implicitly white.
|
||||
if (!has_color() && shading != S_overall) {
|
||||
set_color(Colorf(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
}
|
||||
|
||||
switch (shading) {
|
||||
case S_per_vertex:
|
||||
// Propagate everything to the vertices.
|
||||
{
|
||||
Components::iterator ci;
|
||||
for (ci = _components.begin(); ci != _components.end(); ++ci) {
|
||||
EggAttributes *component = (*ci);
|
||||
if (component->has_normal()) {
|
||||
if (!has_normal()) {
|
||||
copy_normal(*component);
|
||||
}
|
||||
component->clear_normal();
|
||||
}
|
||||
if (component->has_color()) {
|
||||
if (!has_color()) {
|
||||
copy_color(*component);
|
||||
}
|
||||
component->clear_color();
|
||||
}
|
||||
}
|
||||
|
||||
// Not having a color is implicitly white.
|
||||
if (!has_color()) {
|
||||
set_color(Colorf(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
}
|
||||
|
||||
iterator pi;
|
||||
for (pi = begin(); pi != end(); ++pi) {
|
||||
EggVertex *orig_vertex = (*pi);
|
||||
|
|
@ -182,11 +199,6 @@ unify_attributes(EggPrimitive::Shading shading) {
|
|||
vertex = vertex_pool->create_unique_vertex(*vertex);
|
||||
replace(pi, vertex);
|
||||
}
|
||||
Components::iterator ci;
|
||||
for (ci = _components.begin(); ci != _components.end(); ++ci) {
|
||||
(*ci)->clear_normal();
|
||||
(*ci)->clear_color();
|
||||
}
|
||||
clear_normal();
|
||||
clear_color();
|
||||
}
|
||||
|
|
@ -195,20 +207,17 @@ unify_attributes(EggPrimitive::Shading shading) {
|
|||
case S_per_face:
|
||||
// Propagate everything to the components.
|
||||
{
|
||||
Components::iterator ci;
|
||||
for (ci = _components.begin(); ci != _components.end(); ++ci) {
|
||||
EggAttributes *component = (*ci);
|
||||
if (!component->has_normal() && has_normal()) {
|
||||
component->copy_normal(*this);
|
||||
}
|
||||
if (!component->has_color() && has_color()) {
|
||||
component->copy_color(*this);
|
||||
}
|
||||
}
|
||||
iterator pi;
|
||||
for (pi = begin(); pi != end(); ++pi) {
|
||||
EggVertex *orig_vertex = (*pi);
|
||||
if (orig_vertex->has_normal() || orig_vertex->has_color()) {
|
||||
if (orig_vertex->has_normal() && !has_normal()) {
|
||||
copy_normal(*orig_vertex);
|
||||
}
|
||||
if (orig_vertex->has_color() && !has_color()) {
|
||||
copy_color(*orig_vertex);
|
||||
}
|
||||
|
||||
PT(EggVertex) vertex = new EggVertex(*orig_vertex);
|
||||
vertex->clear_normal();
|
||||
vertex->clear_color();
|
||||
|
|
@ -219,6 +228,22 @@ unify_attributes(EggPrimitive::Shading shading) {
|
|||
replace(pi, vertex);
|
||||
}
|
||||
}
|
||||
|
||||
// Not having a color is implicitly white.
|
||||
if (!has_color()) {
|
||||
set_color(Colorf(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
}
|
||||
|
||||
Components::iterator ci;
|
||||
for (ci = _components.begin(); ci != _components.end(); ++ci) {
|
||||
EggAttributes *component = (*ci);
|
||||
if (!component->has_normal() && has_normal()) {
|
||||
component->copy_normal(*this);
|
||||
}
|
||||
if (!component->has_color() && has_color()) {
|
||||
component->copy_color(*this);
|
||||
}
|
||||
}
|
||||
clear_normal();
|
||||
clear_color();
|
||||
}
|
||||
|
|
@ -259,16 +284,17 @@ unify_attributes(EggPrimitive::Shading shading) {
|
|||
component->clear_color();
|
||||
}
|
||||
}
|
||||
|
||||
// Not having a color is implicitly white.
|
||||
if (!has_color()) {
|
||||
set_color(Colorf(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case S_unknown:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!has_color() && shading == S_overall) {
|
||||
set_color(Colorf(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "eggMesher.h"
|
||||
#include "eggMesherFanMaker.h"
|
||||
#include "eggPolygon.h"
|
||||
#include "eggCompositePrimitive.h"
|
||||
#include "eggTriangleStrip.h"
|
||||
|
|
@ -80,7 +81,7 @@ mesh(EggGroupNode *group) {
|
|||
add_polygon(poly, EggMesherStrip::MO_user);
|
||||
|
||||
} else {
|
||||
// A different vertex pool; save this one for next pass.
|
||||
// A different vertex pool; save this one for the next pass.
|
||||
next_children->add_child(poly);
|
||||
}
|
||||
|
||||
|
|
@ -320,8 +321,8 @@ get_prim(EggMesherStrip &strip) {
|
|||
|
||||
Colorf color1, color2;
|
||||
|
||||
if (egg_prim->is_of_type(EggTriangleStrip::get_class_type()) /*||
|
||||
egg_prim->is_of_type(EggTriangleFan::get_class_type())*/) {
|
||||
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.
|
||||
|
||||
|
|
@ -621,8 +622,7 @@ build_sheets() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void EggMesher::
|
||||
find_fans() {
|
||||
#if 0
|
||||
pvector<Prim> unrolled_tris;
|
||||
PT(EggGroupNode) unrolled_tris = new EggGroup;
|
||||
|
||||
// Consider all vertices. Any vertex with over a certain number of
|
||||
// edges connected to it is eligible to become a fan.
|
||||
|
|
@ -639,22 +639,21 @@ find_fans() {
|
|||
// 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;
|
||||
int v = (*vi).first;
|
||||
|
||||
// Build up a list of far fan edges.
|
||||
typedef pvector<FanMaker> FanMakers;
|
||||
|
||||
typedef pvector<EggMesherFanMaker> FanMakers;
|
||||
FanMakers fans;
|
||||
|
||||
EdgePtrs::iterator ei;
|
||||
Edge::Strips::iterator si;
|
||||
EggMesherEdge::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);
|
||||
EggMesherFanMaker fan(v, strip, this);
|
||||
if (!fan._edges.empty()) {
|
||||
fans.push_back(fan);
|
||||
}
|
||||
|
|
@ -670,7 +669,7 @@ find_fans() {
|
|||
FanMakers::iterator fi, fi2;
|
||||
|
||||
// Now pull out connected edges.
|
||||
int joined_any;
|
||||
bool joined_any;
|
||||
do {
|
||||
joined_any = false;
|
||||
for (fi = fans.begin(); fi != fans.end(); ++fi) {
|
||||
|
|
@ -698,11 +697,10 @@ find_fans() {
|
|||
// 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);
|
||||
EggGroupNode::iterator ti;
|
||||
for (ti = unrolled_tris->begin(); ti != unrolled_tris->end(); ++ti) {
|
||||
add_polygon(DCAST(EggPolygon, (*ti)), EggMesherStrip::MO_fanpoly);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@
|
|||
#include "pandabase.h"
|
||||
#include "eggMesherEdge.h"
|
||||
#include "eggMesherStrip.h"
|
||||
//#include "eggMesherFanMaker.h"
|
||||
#include "eggPolygon.h"
|
||||
#include "pvector.h"
|
||||
#include "plist.h"
|
||||
|
|
@ -31,8 +30,6 @@
|
|||
|
||||
#include <algorithm>
|
||||
|
||||
class MesherFanMaker;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Class : EggMesher
|
||||
// Description : Collects together unrelated EggPrimitives, determines
|
||||
|
|
|
|||
|
|
@ -0,0 +1,93 @@
|
|||
// Filename: eggMesherFanMaker.I
|
||||
// Created by: drose (22Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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: EggMesherFanMaker::operator <
|
||||
// Access: Public
|
||||
// Description: Provides a unique ordering between different fan
|
||||
// makers based on the leading edge.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool EggMesherFanMaker::
|
||||
operator < (const EggMesherFanMaker &other) const {
|
||||
nassertr(!_edges.empty() && !other._edges.empty(), false);
|
||||
return _edges.front() < other._edges.front();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesherFanMaker::operator !=
|
||||
// Access: Public
|
||||
// Description: Provides a unique ordering between different fan
|
||||
// makers based on the leading edge.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool EggMesherFanMaker::
|
||||
operator != (const EggMesherFanMaker &other) const {
|
||||
return !operator == (other);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesherFanMaker::operator ==
|
||||
// Access: Public
|
||||
// Description: Provides a unique ordering between different fan
|
||||
// makers based on the leading edge.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool EggMesherFanMaker::
|
||||
operator == (const EggMesherFanMaker &other) const {
|
||||
return _edges.front() == other._edges.front();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesherFanMaker::is_empty
|
||||
// Access: Public
|
||||
// Description: Returns true if the fan maker has no edges, false
|
||||
// otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool EggMesherFanMaker::
|
||||
is_empty() const {
|
||||
return (_edges.empty());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesherFanMaker::is_valid
|
||||
// Access: Public
|
||||
// Description: Returns true if the fan maker has enough edges to
|
||||
// define at least one fan, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool EggMesherFanMaker::
|
||||
is_valid() const {
|
||||
return (_edges.size() > 2);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesherFanMaker::is_coplanar_with
|
||||
// Access: Public
|
||||
// Description: Returns true if the strip and the other strip are
|
||||
// coplanar.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool EggMesherFanMaker::
|
||||
is_coplanar_with(const EggMesherFanMaker &other) const {
|
||||
return _planar && other._planar &&
|
||||
_strips.front()->is_coplanar_with(*other._strips.front(),
|
||||
egg_coplanar_threshold);
|
||||
}
|
||||
|
||||
INLINE ostream &
|
||||
operator << (ostream &out, const EggMesherFanMaker &fm) {
|
||||
fm.output(out);
|
||||
return out;
|
||||
}
|
||||
|
|
@ -0,0 +1,371 @@
|
|||
// Filename: eggMesherFanMaker.cxx
|
||||
// Created by: drose (22Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "eggMesherFanMaker.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesherFanMaker::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
EggMesherFanMaker::
|
||||
EggMesherFanMaker(int vertex, EggMesherStrip *tri,
|
||||
EggMesher *mesher) {
|
||||
_vertex = vertex;
|
||||
const EggMesherEdge *edge = tri->find_opposite_edge(vertex);
|
||||
if (edge != (const EggMesherEdge *)NULL) {
|
||||
_edges.push_back(edge);
|
||||
}
|
||||
_strips.push_back(tri);
|
||||
_planar = tri->_planar;
|
||||
_mesher = mesher;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesherFanMaker::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
EggMesherFanMaker::
|
||||
EggMesherFanMaker(const EggMesherFanMaker ©) :
|
||||
_vertex(copy._vertex),
|
||||
_edges(copy._edges),
|
||||
_strips(copy._strips),
|
||||
_planar(copy._planar),
|
||||
_mesher(copy._mesher)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesherFanMaker::Copy Assignment Operator
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggMesherFanMaker::
|
||||
operator = (const EggMesherFanMaker ©) {
|
||||
_vertex = copy._vertex;
|
||||
_edges = copy._edges;
|
||||
_strips = copy._strips;
|
||||
_planar = copy._planar;
|
||||
_mesher = copy._mesher;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesherFanMaker::join
|
||||
// Access: Public
|
||||
// Description: Attempts to connect two fans end-to-end. They must
|
||||
// both share the same common vertex and a common edge.
|
||||
//
|
||||
// The return value is true if the fans were
|
||||
// successfully joined, or false if they could not be.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool EggMesherFanMaker::
|
||||
join(EggMesherFanMaker &other) {
|
||||
nassertr(_vertex == other._vertex, false);
|
||||
nassertr(_mesher == other._mesher, false);
|
||||
|
||||
nassertr(!_edges.empty() && !other._edges.empty(), false);
|
||||
|
||||
const EggMesherEdge *my_back = _edges.back();
|
||||
const EggMesherEdge *other_front = other._edges.front();
|
||||
nassertr(my_back != (EggMesherEdge *)NULL &&
|
||||
other_front != (EggMesherEdge *)NULL, false);
|
||||
|
||||
int my_back_b = my_back->_vi_b;
|
||||
int other_front_a = other_front->_vi_a;
|
||||
|
||||
if (my_back_b == other_front_a) {
|
||||
_planar = is_coplanar_with(other);
|
||||
_edges.splice(_edges.end(), other._edges);
|
||||
_strips.splice(_strips.end(), other._strips);
|
||||
return true;
|
||||
}
|
||||
|
||||
const EggMesherEdge *my_front = _edges.front();
|
||||
const EggMesherEdge *other_back = other._edges.back();
|
||||
nassertr(my_front != (EggMesherEdge *)NULL &&
|
||||
other_back != (EggMesherEdge *)NULL, false);
|
||||
|
||||
int my_front_a = my_front->_vi_a;
|
||||
int other_back_b = other_back->_vi_b;
|
||||
|
||||
if (my_front_a == other_back_b) {
|
||||
_planar = is_coplanar_with(other);
|
||||
_edges.splice(_edges.begin(), other._edges);
|
||||
_strips.splice(_strips.begin(), other._strips);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesherFanMaker::compute_angle
|
||||
// Access: Public
|
||||
// Description: Returns the overall angle subtended by the fan, from
|
||||
// the leading edge to the trailing edge, in degrees.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
double EggMesherFanMaker::
|
||||
compute_angle() const {
|
||||
// We sum up the angles of each triangle. This is more correct than
|
||||
// taking the net angle from the first edge to the last (since we
|
||||
// may not be in a plane).
|
||||
nassertr(is_valid(), 0.0);
|
||||
|
||||
EggVertexPool *vertex_pool = _mesher->_vertex_pool;
|
||||
|
||||
double angle = 0.0;
|
||||
LPoint3d v0 = vertex_pool->get_vertex(_vertex)->get_pos3();
|
||||
|
||||
Edges::const_iterator ei;
|
||||
for (ei = _edges.begin(); ei != _edges.end(); ++ei) {
|
||||
LVector3d v1 = vertex_pool->get_vertex((*ei)->_vi_a)->get_pos3() - v0;
|
||||
LVector3d v2 = vertex_pool->get_vertex((*ei)->_vi_b)->get_pos3() - v0;
|
||||
|
||||
v1 = normalize(v1);
|
||||
v2 = normalize(v2);
|
||||
angle += acos(dot(v1, v2));
|
||||
}
|
||||
|
||||
return rad_2_deg(angle);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesherFanMaker::build
|
||||
// Access: Public
|
||||
// Description: Begins the fanning process. Searches for triangles
|
||||
// and connects them into a fan.
|
||||
//
|
||||
// In certain cases, if egg_unroll_fans is enabled, the
|
||||
// resulting fan may be retesselated into a series of
|
||||
// zig-zag triangles, which are stored in unrolled_tris.
|
||||
// Otherwise, an EggMesherStrip (representing the fan)
|
||||
// is created and added to the mesher.
|
||||
//
|
||||
// The return value is (loosely) the number of
|
||||
// primitives created.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int EggMesherFanMaker::
|
||||
build(EggGroupNode *unrolled_tris) {
|
||||
nassertr(_edges.size() == _strips.size(), 0);
|
||||
|
||||
int num_tris = _edges.size();
|
||||
double net_angle = compute_angle();
|
||||
double avg_angle = net_angle / (double)num_tris;
|
||||
|
||||
if (avg_angle > egg_max_tfan_angle) {
|
||||
// The triangles are too loose to justify making a fan; it'll
|
||||
// probably make a better quadsheet.
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (egg_min_tfan_tris == 0 || num_tris < egg_min_tfan_tris) {
|
||||
// Oops, not enough triangles to justify a fan.
|
||||
if (!egg_unroll_fans) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// However, we could (maybe) make it a few tristrips!
|
||||
|
||||
// Each section of the fan which is made up of coplanar tris, with
|
||||
// identical properties, may be retesselated into a tristrip.
|
||||
// What a sneaky trick! To do this, we must first identify each
|
||||
// such qualifying section.
|
||||
|
||||
// We define a seam as the edge between any two tris which are
|
||||
// noncoplanar or have different properties. Then we can send
|
||||
// each piece between the seams to unroll().
|
||||
|
||||
Strips::iterator si, last_si;
|
||||
Edges::iterator ei, last_ei;
|
||||
|
||||
// First, rotate the fan so it begins at a seam. We do this so we
|
||||
// won't be left out with part of one piece at the beginning and
|
||||
// also at the end.
|
||||
si = _strips.begin();
|
||||
last_si = si;
|
||||
ei = _edges.begin();
|
||||
last_ei = ei;
|
||||
int found_seam = false;
|
||||
|
||||
for (++si, ++ei; si != _strips.end() && !found_seam; ++si, ++ei) {
|
||||
nassertr(ei != _edges.end(), 0);
|
||||
if ( ((*si)->_prims.front()->compare_to(*(*last_si)->_prims.front()) != 0) ||
|
||||
!(*si)->is_coplanar_with(*(*last_si), egg_coplanar_threshold)) {
|
||||
// Here's a seam. Break the fan here.
|
||||
found_seam = true;
|
||||
_edges.splice(_edges.begin(), _edges, ei, _edges.end());
|
||||
_strips.splice(_strips.begin(), _strips, si, _strips.end());
|
||||
}
|
||||
}
|
||||
|
||||
// Now break the fan up along its seams and unroll each piece
|
||||
// separately.
|
||||
si = _strips.begin();
|
||||
last_si = si;
|
||||
ei = _edges.begin();
|
||||
last_ei = ei;
|
||||
|
||||
int count = 0;
|
||||
for (++si, ++ei; si != _strips.end(); ++si, ++ei) {
|
||||
nassertr(ei != _edges.end(), 0);
|
||||
if ( ((*si)->_prims.front()->compare_to(*(*last_si)->_prims.front()) != 0) ||
|
||||
!(*si)->is_coplanar_with(*(*last_si), egg_coplanar_threshold)) {
|
||||
// Here's the end of a run of matching pieces.
|
||||
count += unroll(last_si, si, last_ei, ei, unrolled_tris);
|
||||
last_si = si;
|
||||
last_ei = ei;
|
||||
}
|
||||
}
|
||||
count += unroll(last_si, si, last_ei, ei, unrolled_tris);
|
||||
|
||||
return count;
|
||||
|
||||
} else {
|
||||
EggMesherStrip new_fan;
|
||||
new_fan._type = EggMesherStrip::PT_trifan;
|
||||
new_fan._origin = EggMesherStrip::MO_fanpoly;
|
||||
new_fan._verts.push_back(_vertex);
|
||||
|
||||
new_fan._verts.push_back(_edges.front()->_vi_a);
|
||||
Edges::iterator ei;
|
||||
for (ei = _edges.begin(); ei != _edges.end(); ++ei) {
|
||||
new_fan._verts.push_back((*ei)->_vi_b);
|
||||
}
|
||||
|
||||
Strips::iterator si;
|
||||
for (si = _strips.begin(); si != _strips.end(); ++si) {
|
||||
new_fan._prims.splice(new_fan._prims.end(), (*si)->_prims);
|
||||
(*si)->remove_all_edges();
|
||||
(*si)->_verts.clear();
|
||||
(*si)->_status = EggMesherStrip::MS_dead;
|
||||
}
|
||||
|
||||
// If we'd built our list of edges and strips right, this sum should
|
||||
// come out so that there are two more vertices than triangles in
|
||||
// the new fan.
|
||||
nassertr(new_fan._verts.size() == new_fan._prims.size() + 2, 0);
|
||||
|
||||
// Now we've built a fan, and it won't be able to mate with
|
||||
// anything else, so add it to the done list.
|
||||
_mesher->_done.push_back(new_fan);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesherFanMaker::unroll
|
||||
// Access: Public
|
||||
// Description: Unrolls a planar subset of the current working fan,
|
||||
// defined by the given iterators, into a series of
|
||||
// triangles that zig-zag back and forth for better
|
||||
// tristripping properties. The new triangles are added
|
||||
// to unrolled_tris; the return value is 1 if
|
||||
// successful, or 0 otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int EggMesherFanMaker::
|
||||
unroll(Strips::iterator strip_begin, Strips::iterator strip_end,
|
||||
Edges::iterator edge_begin, Edges::iterator edge_end,
|
||||
EggGroupNode *unrolled_tris) {
|
||||
Edges::iterator ei;
|
||||
Strips::iterator si;
|
||||
|
||||
int num_tris = 0;
|
||||
for (ei = edge_begin; ei != edge_end; ++ei) {
|
||||
num_tris++;
|
||||
}
|
||||
|
||||
if (num_tris < 3) {
|
||||
// Don't even bother.
|
||||
return 0;
|
||||
}
|
||||
|
||||
PT(EggPolygon) poly = new EggPolygon;
|
||||
|
||||
// Now we build an n-sided polygon the same shape as the fan. We'll
|
||||
// decompose it into tris in a second.
|
||||
poly->copy_attributes(*(*strip_begin)->_prims.front());
|
||||
EggVertexPool *vertex_pool = _mesher->_vertex_pool;
|
||||
|
||||
ei = edge_end;
|
||||
--ei;
|
||||
if ((*ei)->_vi_b != (*edge_begin)->_vi_a) {
|
||||
// If the fan is less than a full circle, we need to keep the
|
||||
// hub vertex and initial vertex in the poly. Otherwise, we'll
|
||||
// discard them.
|
||||
poly->add_vertex(vertex_pool->get_vertex(_vertex));
|
||||
poly->add_vertex(vertex_pool->get_vertex((*edge_begin)->_vi_a));
|
||||
}
|
||||
|
||||
for (ei = edge_begin; ei != edge_end; ++ei) {
|
||||
poly->add_vertex(vertex_pool->get_vertex((*ei)->_vi_b));
|
||||
}
|
||||
|
||||
bool result = true;
|
||||
|
||||
if (egg_show_quads) {
|
||||
// If we're showing quads, also show retesselated triangles.
|
||||
|
||||
// We can't add it directly to the mesher, that's unsafe; instead,
|
||||
// we'll just add it to the end of the unrolled_tris list. This
|
||||
// does mean we won't be able to color it a fancy color, but too
|
||||
// bad.
|
||||
//_mesher->add_polygon(poly, EggMesherStrip::MO_fanpoly);
|
||||
unrolled_tris->add_child(poly);
|
||||
|
||||
} else {
|
||||
// Now decompose the new polygon into triangles.
|
||||
result = poly->triangulate_into(unrolled_tris, true);
|
||||
}
|
||||
|
||||
if (result) {
|
||||
// Now that we've created a new poly, kill off all the old ones.
|
||||
for (si = strip_begin; si != strip_end; ++si) {
|
||||
(*si)->remove_all_edges();
|
||||
(*si)->_verts.clear();
|
||||
(*si)->_prims.clear();
|
||||
(*si)->_status = EggMesherStrip::MS_dead;
|
||||
}
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggMesherFanMaker::output
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggMesherFanMaker::
|
||||
output(ostream &out) const {
|
||||
out << _vertex << ":[";
|
||||
if (!_edges.empty()) {
|
||||
Edges::const_iterator ei;
|
||||
for (ei = _edges.begin(); ei != _edges.end(); ++ei) {
|
||||
out << " " << (*ei)->_vi_a;
|
||||
}
|
||||
out << " " << _edges.back()->_vi_b;
|
||||
}
|
||||
out << " ]";
|
||||
|
||||
if (_planar) {
|
||||
out << " (planar)";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
// Filename: eggMesherFanMaker.h
|
||||
// Created by: drose (22Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 EGGMESHERFANMAKER_H
|
||||
#define EGGMESHERFANMAKER_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "eggMesherEdge.h"
|
||||
#include "eggMesherStrip.h"
|
||||
|
||||
#include "plist.h"
|
||||
#include "pvector.h"
|
||||
|
||||
#include "notify.h"
|
||||
#include "mathNumbers.h"
|
||||
|
||||
class EggMesher;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Class : EggMesherFanMaker
|
||||
// Description : This class is used by EggMesher::find_fans() to
|
||||
// attempt to make an EggTriangleFan out of the polygons
|
||||
// connected to the indicated vertex.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EggMesherFanMaker {
|
||||
public:
|
||||
typedef plist<const EggMesherEdge *> Edges;
|
||||
typedef plist<EggMesherStrip *> Strips;
|
||||
|
||||
EggMesherFanMaker(int vertex, EggMesherStrip *tri,
|
||||
EggMesher *mesher);
|
||||
EggMesherFanMaker(const EggMesherFanMaker ©);
|
||||
void operator = (const EggMesherFanMaker ©);
|
||||
|
||||
INLINE bool operator < (const EggMesherFanMaker &other) const;
|
||||
INLINE bool operator != (const EggMesherFanMaker &other) const;
|
||||
INLINE bool operator == (const EggMesherFanMaker &other) const;
|
||||
|
||||
INLINE bool is_empty() const;
|
||||
INLINE bool is_valid() const;
|
||||
INLINE bool is_coplanar_with(const EggMesherFanMaker &other) const;
|
||||
|
||||
bool join(EggMesherFanMaker &other);
|
||||
double compute_angle() const;
|
||||
|
||||
int build(EggGroupNode *unrolled_tris);
|
||||
int unroll(Strips::iterator strip_begin, Strips::iterator strip_end,
|
||||
Edges::iterator edge_begin, Edges::iterator edge_end,
|
||||
EggGroupNode *unrolled_tris);
|
||||
|
||||
void output(ostream &out) const;
|
||||
|
||||
int _vertex;
|
||||
Edges _edges;
|
||||
Strips _strips;
|
||||
bool _planar;
|
||||
EggMesher *_mesher;
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const EggMesherFanMaker &fm);
|
||||
|
||||
#include "eggMesherFanMaker.I"
|
||||
|
||||
#endif
|
||||
|
|
@ -19,6 +19,7 @@
|
|||
#include "eggMesherStrip.h"
|
||||
#include "eggMesherEdge.h"
|
||||
#include "eggPrimitive.h"
|
||||
#include "eggTriangleFan.h"
|
||||
#include "eggTriangleStrip.h"
|
||||
#include "eggPolygon.h"
|
||||
#include "dcast.h"
|
||||
|
|
@ -115,7 +116,11 @@ make_prim(const EggVertexPool *vertex_pool) {
|
|||
} else {
|
||||
// The harder case: a tristrip of some kind.
|
||||
convert_to_type(dest_type);
|
||||
prim = new EggTriangleStrip;
|
||||
if (dest_type == PT_trifan) {
|
||||
prim = new EggTriangleFan;
|
||||
} else {
|
||||
prim = new EggTriangleStrip;
|
||||
}
|
||||
prim->copy_attributes(*_prims.front());
|
||||
|
||||
// Now store all the vertices. Each individual triangle's
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ public:
|
|||
int _index;
|
||||
MesherStatus _status;
|
||||
|
||||
int _planar;
|
||||
bool _planar;
|
||||
Normald _plane_normal;
|
||||
float _plane_offset;
|
||||
int _row_id, _row_distance;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
// Filename: eggTriangleFan.I
|
||||
// Created by: drose (23Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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: EggTriangleFan::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE EggTriangleFan::
|
||||
EggTriangleFan(const string &name) : EggCompositePrimitive(name) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggTriangleFan::Copy constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE EggTriangleFan::
|
||||
EggTriangleFan(const EggTriangleFan ©) : EggCompositePrimitive(copy) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggTriangleFan::Copy assignment operator
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE EggTriangleFan &EggTriangleFan::
|
||||
operator = (const EggTriangleFan ©) {
|
||||
EggCompositePrimitive::operator = (copy);
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
// Filename: eggTriangleFan.cxx
|
||||
// Created by: drose (23Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "eggTriangleFan.h"
|
||||
#include "eggGroupNode.h"
|
||||
#include "eggPolygon.h"
|
||||
#include "indent.h"
|
||||
|
||||
TypeHandle EggTriangleFan::_type_handle;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggTriangleFan::Destructor
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
EggTriangleFan::
|
||||
~EggTriangleFan() {
|
||||
clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggTriangleFan::write
|
||||
// Access: Published, Virtual
|
||||
// Description: Writes the triangle fan to the indicated output
|
||||
// stream in Egg format.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggTriangleFan::
|
||||
write(ostream &out, int indent_level) const {
|
||||
write_header(out, indent_level, "<TriangleFan>");
|
||||
write_body(out, indent_level+2);
|
||||
indent(out, indent_level) << "}\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggTriangleFan::apply_first_attribute
|
||||
// Access: Published, Virtual
|
||||
// Description: Sets the first vertex of the triangle (or each
|
||||
// component) to the primitive normal and/or color, if
|
||||
// the primitive is flat-shaded. This reflects the
|
||||
// DirectX convention of storing flat-shaded properties
|
||||
// on the first vertex, although it is not usually a
|
||||
// convention in Egg.
|
||||
//
|
||||
// This may introduce redundant vertices to the vertex
|
||||
// pool.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggTriangleFan::
|
||||
apply_first_attribute() {
|
||||
// In the case of a triangle fan, the first vertex of the fan is the
|
||||
// common vertex, so we consider the second vertex to be the key
|
||||
// vertex of the first triangle, and move from there.
|
||||
for (int i = 0; i < get_num_components(); i++) {
|
||||
EggAttributes *component = get_component(i);
|
||||
do_apply_flat_attribute(i + 1, component);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggTriangleFan::get_num_lead_vertices
|
||||
// Access: Protected, Virtual
|
||||
// Description: Returns the number of initial vertices that are not
|
||||
// used in defining any component; the first component
|
||||
// is defined by the (n + 1)th vertex, and then a new
|
||||
// component at each vertex thereafter.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int EggTriangleFan::
|
||||
get_num_lead_vertices() const {
|
||||
return 2;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggTriangleFan::triangulate_poly
|
||||
// Access: Protected, Virtual
|
||||
// Description: Fills the container up with EggPolygons that
|
||||
// represent the component triangles of this triangle
|
||||
// fan.
|
||||
//
|
||||
// It is assumed that the EggTriangleFan is not
|
||||
// already a child of any other group when this function
|
||||
// is called.
|
||||
//
|
||||
// Returns true if the triangulation is successful, or
|
||||
// false if there was some error (in which case the
|
||||
// container may contain some partial triangulation).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool EggTriangleFan::
|
||||
do_triangulate(EggGroupNode *container) const {
|
||||
if (size() < 3) {
|
||||
return false;
|
||||
}
|
||||
const_iterator vi = begin();
|
||||
EggVertex *v0 = (*vi);
|
||||
++vi;
|
||||
EggVertex *v1 = (*vi);
|
||||
++vi;
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
poly->add_vertex(v0);
|
||||
poly->add_vertex(v1);
|
||||
poly->add_vertex(*vi);
|
||||
v1 = *vi;
|
||||
container->add_child(poly);
|
||||
++vi;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
// Filename: eggTriangleFan.h
|
||||
// Created by: drose (23Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 EGGTRIANGLEFAN_H
|
||||
#define EGGTRIANGLEFAN_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "eggCompositePrimitive.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : EggTriangleFan
|
||||
// Description : A connected fan of triangles. This does not
|
||||
// normally appear in an egg file; it is typically
|
||||
// generated as a result of meshing.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDAEGG EggTriangleFan : public EggCompositePrimitive {
|
||||
PUBLISHED:
|
||||
INLINE EggTriangleFan(const string &name = "");
|
||||
INLINE EggTriangleFan(const EggTriangleFan ©);
|
||||
INLINE EggTriangleFan &operator = (const EggTriangleFan ©);
|
||||
virtual ~EggTriangleFan();
|
||||
|
||||
virtual void write(ostream &out, int indent_level) const;
|
||||
virtual void apply_first_attribute();
|
||||
|
||||
protected:
|
||||
virtual int get_num_lead_vertices() const;
|
||||
virtual bool do_triangulate(EggGroupNode *container) const;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
EggCompositePrimitive::init_type();
|
||||
register_type(_type_handle, "EggTriangleFan",
|
||||
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 "eggTriangleFan.I"
|
||||
|
||||
#endif
|
||||
|
|
@ -19,12 +19,8 @@
|
|||
#include "eggTriangleStrip.h"
|
||||
#include "eggGroupNode.h"
|
||||
#include "eggPolygon.h"
|
||||
#include "plane.h"
|
||||
|
||||
#include "indent.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
TypeHandle EggTriangleStrip::_type_handle;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include "eggMaterialCollection.cxx"
|
||||
#include "eggMesher.cxx"
|
||||
#include "eggMesherEdge.cxx"
|
||||
#include "eggMesherFanMaker.cxx"
|
||||
#include "eggMesherStrip.cxx"
|
||||
#include "eggMiscFuncs.cxx"
|
||||
#include "eggMorphList.cxx"
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include "eggTexture.cxx"
|
||||
#include "eggTextureCollection.cxx"
|
||||
#include "eggTransform3d.cxx"
|
||||
#include "eggTriangleFan.cxx"
|
||||
#include "eggTriangleStrip.cxx"
|
||||
#include "eggUserData.cxx"
|
||||
#include "eggUtilities.cxx"
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#include "eggVertexUV.h"
|
||||
#include "eggPolygon.h"
|
||||
#include "eggCompositePrimitive.h"
|
||||
#include "eggTriangleFan.h"
|
||||
#include "eggTriangleStrip.h"
|
||||
#include "eggPoint.h"
|
||||
#include "eggLine.h"
|
||||
|
|
@ -182,6 +183,7 @@ egg_cleanup_parser() {
|
|||
%type <_egg> joint
|
||||
%type <_egg> line
|
||||
%type <_egg> polygon
|
||||
%type <_egg> trianglefan
|
||||
%type <_egg> trianglestrip
|
||||
%type <_egg> point_light
|
||||
%type <_egg> nurbs_surface
|
||||
|
|
@ -252,6 +254,7 @@ node:
|
|||
| joint
|
||||
| instance
|
||||
| polygon
|
||||
| trianglefan
|
||||
| trianglestrip
|
||||
| point_light
|
||||
| line
|
||||
|
|
@ -1596,6 +1599,25 @@ polygon:
|
|||
}
|
||||
;
|
||||
|
||||
/*
|
||||
* trianglefan
|
||||
*
|
||||
* enter:
|
||||
* exit: returns a new EggTriangleFan.
|
||||
*
|
||||
*/
|
||||
trianglefan:
|
||||
TRIANGLEFAN optional_name
|
||||
{
|
||||
egg_stack.push_back(new EggTriangleFan($2));
|
||||
}
|
||||
'{' primitive_body '}'
|
||||
{
|
||||
$$ = egg_stack.back();
|
||||
egg_stack.pop_back();
|
||||
}
|
||||
;
|
||||
|
||||
/*
|
||||
* trianglestrip
|
||||
*
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
#include "qpgeom.h"
|
||||
#include "qpgeomTriangles.h"
|
||||
#include "qpgeomTristrips.h"
|
||||
#include "qpgeomTrifans.h"
|
||||
#include "qpgeomLines.h"
|
||||
#include "qpgeomLinestrips.h"
|
||||
#include "qpgeomPoints.h"
|
||||
|
|
@ -61,6 +62,7 @@
|
|||
#include "eggGroup.h"
|
||||
#include "eggPolygon.h"
|
||||
#include "eggTriangleStrip.h"
|
||||
#include "eggTriangleFan.h"
|
||||
#include "eggBin.h"
|
||||
#include "eggTable.h"
|
||||
#include "eggBinner.h"
|
||||
|
|
@ -2000,6 +2002,9 @@ make_primitive(const EggRenderState *render_state, EggPrimitive *egg_prim,
|
|||
} else if (egg_prim->is_of_type(EggTriangleStrip::get_class_type())) {
|
||||
primitive = new qpGeomTristrips(qpGeomUsageHint::UH_static);
|
||||
|
||||
} else if (egg_prim->is_of_type(EggTriangleFan::get_class_type())) {
|
||||
primitive = new qpGeomTrifans(qpGeomUsageHint::UH_static);
|
||||
|
||||
} else if (egg_prim->is_of_type(EggLine::get_class_type())) {
|
||||
if (egg_prim->size() == 2) {
|
||||
primitive = new qpGeomLines(qpGeomUsageHint::UH_static);
|
||||
|
|
|
|||
|
|
@ -125,6 +125,8 @@ decompose_impl() const {
|
|||
triangles->add_vertex(v0);
|
||||
triangles->add_vertex(v1);
|
||||
triangles->add_vertex(vertices[vi]);
|
||||
nassertr(vi < (int)vertices.size(), this);
|
||||
v1 = vertices[vi];
|
||||
triangles->close_primitive();
|
||||
++vi;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue