*** empty log message ***
This commit is contained in:
parent
f4756996f4
commit
66e460dbaf
|
|
@ -493,9 +493,14 @@ strip_normals() {
|
|||
// the scene graph and below with triangles. Returns
|
||||
// the total number of new triangles produced, less
|
||||
// degenerate polygons removed.
|
||||
//
|
||||
// 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 largely unchanged.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int EggGroupNode::
|
||||
triangulate_polygons() {
|
||||
triangulate_polygons(bool convex_also) {
|
||||
int num_produced = 0;
|
||||
|
||||
Children children_copy = _children;
|
||||
|
|
@ -508,10 +513,10 @@ triangulate_polygons() {
|
|||
|
||||
if (child->is_of_type(EggPolygon::get_class_type())) {
|
||||
EggPolygon *poly = DCAST(EggPolygon, child);
|
||||
poly->triangulate_in_place();
|
||||
poly->triangulate_in_place(convex_also);
|
||||
|
||||
} else if (child->is_of_type(EggGroupNode::get_class_type())) {
|
||||
num_produced += DCAST(EggGroupNode, child)->triangulate_polygons();
|
||||
num_produced += DCAST(EggGroupNode, child)->triangulate_polygons(convex_also);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ public:
|
|||
void recompute_polygon_normals();
|
||||
void strip_normals();
|
||||
|
||||
int triangulate_polygons();
|
||||
int triangulate_polygons(bool convex_also);
|
||||
|
||||
int remove_unused_vertices();
|
||||
int remove_invalid_primitives();
|
||||
|
|
|
|||
|
|
@ -65,8 +65,15 @@ recompute_polygon_normal() {
|
|||
// Returns true if the triangulation is successful, or
|
||||
// false if there was some error (in which case the
|
||||
// container may contain some partial triangulation).
|
||||
//
|
||||
// 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.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool EggPolygon::
|
||||
triangulate_into(EggGroupNode *container) const {
|
||||
return triangulate_poly(container);
|
||||
triangulate_into(EggGroupNode *container, bool convex_also) const {
|
||||
EggPolygon *copy = new EggPolygon(*this);
|
||||
return copy->triangulate_poly(container, convex_also);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,18 +95,21 @@ calculate_normal(Normald &result) const {
|
|||
// triangles to the parent group node in place of the
|
||||
// original polygon. Returns a pointer to the original
|
||||
// polygon, 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(EggPolygon) EggPolygon::
|
||||
triangulate_in_place() {
|
||||
triangulate_in_place(bool convex_also) {
|
||||
EggGroupNode *parent = get_parent();
|
||||
nassertr(parent != (EggGroupNode *)NULL, this);
|
||||
|
||||
PT(EggPolygon) save_me = this;
|
||||
parent->remove_child(this);
|
||||
|
||||
if (cleanup()) {
|
||||
triangulate_into(parent);
|
||||
}
|
||||
triangulate_poly(parent, convex_also);
|
||||
|
||||
return save_me;
|
||||
}
|
||||
|
|
@ -253,13 +256,16 @@ decomp_concave(EggGroupNode *container, int asum, int x, int y) const {
|
|||
} else {
|
||||
|
||||
// Here's a triangle to output.
|
||||
EggPolygon *triangle = new EggPolygon(*this);
|
||||
container->add_child(triangle);
|
||||
PT(EggPolygon) triangle = new EggPolygon(*this);
|
||||
triangle->clear();
|
||||
triangle->add_vertex(get_vertex(p0->index));
|
||||
triangle->add_vertex(get_vertex(p1->index));
|
||||
triangle->add_vertex(get_vertex(p2->index));
|
||||
|
||||
if (triangle->cleanup()) {
|
||||
container->add_child(triangle.p());
|
||||
}
|
||||
|
||||
p0->next = p1->next;
|
||||
p1 = p2;
|
||||
p2 = p2->next;
|
||||
|
|
@ -273,13 +279,16 @@ decomp_concave(EggGroupNode *container, int asum, int x, int y) const {
|
|||
}
|
||||
|
||||
// One more triangle to output.
|
||||
EggPolygon *triangle = new EggPolygon(*this);
|
||||
container->add_child(triangle);
|
||||
PT(EggPolygon) triangle = new EggPolygon(*this);
|
||||
triangle->clear();
|
||||
triangle->add_vertex(get_vertex(p0->index));
|
||||
triangle->add_vertex(get_vertex(p1->index));
|
||||
triangle->add_vertex(get_vertex(p2->index));
|
||||
|
||||
if (triangle->cleanup()) {
|
||||
container->add_child(triangle.p());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -292,18 +301,27 @@ decomp_concave(EggGroupNode *container, int asum, int x, int y) const {
|
|||
// container up with EggPolygons that represent the
|
||||
// triangles. Returns true if successful, false on
|
||||
// failure.
|
||||
//
|
||||
// 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.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool EggPolygon::
|
||||
triangulate_poly(EggGroupNode *container) const {
|
||||
triangulate_poly(EggGroupNode *container, bool convex_also) {
|
||||
LPoint3d p0, p1, as;
|
||||
double dx1, dy1, dx2, dy2, max;
|
||||
int i, flag, asum, csum, index, x, y, v0, v1, v, even;
|
||||
|
||||
if (!cleanup()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// First see if the polygon is already a triangle
|
||||
int num_verts = size();
|
||||
if (num_verts == 3) {
|
||||
EggPolygon *triangle = new EggPolygon(*this);
|
||||
container->add_child(triangle);
|
||||
container->add_child(this);
|
||||
|
||||
return true;
|
||||
|
||||
|
|
@ -386,10 +404,18 @@ triangulate_poly(EggGroupNode *container) const {
|
|||
csum = ((dx1 * dy2 - dx2 * dy1 >= 0.0) ? 1 : 0);
|
||||
|
||||
if (csum ^ asum) {
|
||||
// It's a concave polygon. This is a little harder.
|
||||
return decomp_concave(container, flag, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
// It's a convex polygon.
|
||||
if (!convex_also) {
|
||||
container->add_child(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
v0 = 0;
|
||||
v1 = 1;
|
||||
v = num_verts - 1;
|
||||
|
|
@ -402,24 +428,30 @@ triangulate_poly(EggGroupNode *container) const {
|
|||
*/
|
||||
for (i = 0; i < num_verts - 2; i++) {
|
||||
if (even) {
|
||||
EggPolygon *triangle = new EggPolygon(*this);
|
||||
container->add_child(triangle);
|
||||
PT(EggPolygon) triangle = new EggPolygon(*this);
|
||||
triangle->clear();
|
||||
triangle->add_vertex(get_vertex(v0));
|
||||
triangle->add_vertex(get_vertex(v1));
|
||||
triangle->add_vertex(get_vertex(v));
|
||||
|
||||
if (triangle->cleanup()) {
|
||||
container->add_child(triangle.p());
|
||||
}
|
||||
|
||||
v0 = v1;
|
||||
v1 = v;
|
||||
v = v0 + 1;
|
||||
} else {
|
||||
EggPolygon *triangle = new EggPolygon(*this);
|
||||
container->add_child(triangle);
|
||||
PT(EggPolygon) triangle = new EggPolygon(*this);
|
||||
triangle->clear();
|
||||
triangle->add_vertex(get_vertex(v1));
|
||||
triangle->add_vertex(get_vertex(v0));
|
||||
triangle->add_vertex(get_vertex(v));
|
||||
|
||||
if (triangle->cleanup()) {
|
||||
container->add_child(triangle.p());
|
||||
}
|
||||
|
||||
v0 = v1;
|
||||
v1 = v;
|
||||
v = v0 - 1;
|
||||
|
|
|
|||
|
|
@ -25,14 +25,14 @@ public:
|
|||
bool calculate_normal(Normald &result) const;
|
||||
INLINE bool recompute_polygon_normal();
|
||||
|
||||
INLINE bool triangulate_into(EggGroupNode *container) const;
|
||||
PT(EggPolygon) triangulate_in_place();
|
||||
INLINE bool triangulate_into(EggGroupNode *container, bool convex_also) const;
|
||||
PT(EggPolygon) triangulate_in_place(bool convex_also);
|
||||
|
||||
virtual void write(ostream &out, int indent_level) const;
|
||||
|
||||
private:
|
||||
bool decomp_concave(EggGroupNode *container, int asum, int x, int y) const;
|
||||
bool triangulate_poly(EggGroupNode *container) const;
|
||||
bool triangulate_poly(EggGroupNode *container, bool convex_also);
|
||||
|
||||
public:
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,12 @@ bool egg_keep_texture_pathnames = config_egg2sg.GetBool("egg-keep-texture-pathna
|
|||
// actually a NurbsPPCurve object.
|
||||
bool egg_load_classic_nurbs_curves = config_egg2sg.GetBool("egg-load-classic-nurbs-curves", false);
|
||||
|
||||
// When this is true, certain kinds of recoverable errors (not syntax
|
||||
// errors) in an egg file will be allowed and ignored when an egg file
|
||||
// is loaded. When it is false, only perfectly pristine egg files may
|
||||
// be loaded.
|
||||
bool egg_accept_errors = config_egg2sg.GetBool("egg-accept-errors", true);
|
||||
|
||||
CoordinateSystem egg_coordinate_system;
|
||||
|
||||
ConfigureFn(config_egg2sg) {
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ extern EXPCL_PANDAEGG bool egg_flatten_siblings;
|
|||
extern EXPCL_PANDAEGG bool egg_show_collision_solids;
|
||||
extern EXPCL_PANDAEGG bool egg_keep_texture_pathnames;
|
||||
extern EXPCL_PANDAEGG bool egg_load_classic_nurbs_curves;
|
||||
extern EXPCL_PANDAEGG bool egg_accept_errors;
|
||||
|
||||
extern EXPCL_PANDAEGG void init_libegg2sg();
|
||||
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ EggLoader::
|
|||
EggLoader() {
|
||||
// We need to enforce whatever coordinate system the user asked for.
|
||||
_data.set_coordinate_system(egg_coordinate_system);
|
||||
_error = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -110,6 +111,7 @@ EggLoader::
|
|||
EggLoader(const EggData &data) :
|
||||
_data(data)
|
||||
{
|
||||
_error = false;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1578,7 +1580,7 @@ make_collision_plane(EggGroup *egg_group, CollisionNode *cnode,
|
|||
for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
|
||||
if ((*ci)->is_of_type(EggPolygon::get_class_type())) {
|
||||
CollisionPlane *csplane =
|
||||
create_collision_plane(DCAST(EggPolygon, *ci));
|
||||
create_collision_plane(DCAST(EggPolygon, *ci), egg_group);
|
||||
if (csplane != (CollisionPlane *)NULL) {
|
||||
apply_collision_flags(csplane, flags);
|
||||
cnode->add_solid(csplane);
|
||||
|
|
@ -1604,13 +1606,8 @@ make_collision_polygon(EggGroup *egg_group, CollisionNode *cnode,
|
|||
EggGroup::const_iterator ci;
|
||||
for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
|
||||
if ((*ci)->is_of_type(EggPolygon::get_class_type())) {
|
||||
CollisionPolygon *cspoly =
|
||||
create_collision_polygon(DCAST(EggPolygon, *ci));
|
||||
if (cspoly != (CollisionPolygon *)NULL) {
|
||||
apply_collision_flags(cspoly, flags);
|
||||
cnode->add_solid(cspoly);
|
||||
return;
|
||||
}
|
||||
create_collision_polygons(cnode, DCAST(EggPolygon, *ci),
|
||||
egg_group, flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1630,12 +1627,8 @@ make_collision_polyset(EggGroup *egg_group, CollisionNode *cnode,
|
|||
EggGroup::const_iterator ci;
|
||||
for (ci = geom_group->begin(); ci != geom_group->end(); ++ci) {
|
||||
if ((*ci)->is_of_type(EggPolygon::get_class_type())) {
|
||||
CollisionPolygon *cspoly =
|
||||
create_collision_polygon(DCAST(EggPolygon, *ci));
|
||||
if (cspoly != (CollisionPolygon *)NULL) {
|
||||
apply_collision_flags(cspoly, flags);
|
||||
cnode->add_solid(cspoly);
|
||||
}
|
||||
create_collision_polygons(cnode, DCAST(EggPolygon, *ci),
|
||||
egg_group, flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1775,8 +1768,12 @@ find_collision_geometry(EggGroup *egg_group) {
|
|||
// EggPolygon.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CollisionPlane *EggLoader::
|
||||
create_collision_plane(EggPolygon *egg_poly) {
|
||||
create_collision_plane(EggPolygon *egg_poly, EggGroup *parent_group) {
|
||||
if (!egg_poly->cleanup()) {
|
||||
egg2sg_cat.warning()
|
||||
<< "Degenerate collision plane in " << parent_group->get_name()
|
||||
<< "\n";
|
||||
_error = true;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -1809,44 +1806,68 @@ create_collision_plane(EggPolygon *egg_poly) {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggLoader::create_collision_polygon
|
||||
// Function: EggLoader::create_collision_polygons
|
||||
// Access: Private
|
||||
// Description: Creates a single CollisionPolygon from the indicated
|
||||
// EggPolygon.
|
||||
// Description: Creates one or more CollisionPolygons from the
|
||||
// indicated EggPolygon, and adds them to the indicated
|
||||
// CollisionNode.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CollisionPolygon *EggLoader::
|
||||
create_collision_polygon(EggPolygon *egg_poly) {
|
||||
if (!egg_poly->cleanup()) {
|
||||
return NULL;
|
||||
void EggLoader::
|
||||
create_collision_polygons(CollisionNode *cnode, EggPolygon *egg_poly,
|
||||
EggGroup *parent_group,
|
||||
EggGroup::CollideFlags flags) {
|
||||
|
||||
PT(EggGroup) group = new EggGroup;
|
||||
if (!egg_poly->triangulate_into(group, false)) {
|
||||
egg2sg_cat.warning()
|
||||
<< "Degenerate collision polygon in " << parent_group->get_name()
|
||||
<< "\n";
|
||||
_error = true;
|
||||
return;
|
||||
}
|
||||
|
||||
vector<Vertexf> vertices;
|
||||
if (!egg_poly->empty()) {
|
||||
EggPolygon::const_iterator vi;
|
||||
vi = egg_poly->begin();
|
||||
if (group->size() != 1) {
|
||||
egg2sg_cat.warning()
|
||||
<< "Concave collision polygon in " << parent_group->get_name()
|
||||
<< "\n";
|
||||
_error = true;
|
||||
}
|
||||
|
||||
Vertexd vert = (*vi)->get_pos3();
|
||||
vertices.push_back(LCAST(float, vert));
|
||||
|
||||
Vertexd last_vert = vert;
|
||||
++vi;
|
||||
while (vi != egg_poly->end()) {
|
||||
vert = (*vi)->get_pos3();
|
||||
if (!vert.almost_equal(last_vert)) {
|
||||
vertices.push_back(LCAST(float, vert));
|
||||
}
|
||||
EggGroup::iterator ci;
|
||||
for (ci = group->begin(); ci != group->end(); ++ci) {
|
||||
EggPolygon *poly = DCAST(EggPolygon, *ci);
|
||||
|
||||
last_vert = vert;
|
||||
vector<Vertexf> vertices;
|
||||
if (!poly->empty()) {
|
||||
EggPolygon::const_iterator vi;
|
||||
vi = poly->begin();
|
||||
|
||||
Vertexd vert = (*vi)->get_pos3();
|
||||
vertices.push_back(LCAST(float, vert));
|
||||
|
||||
Vertexd last_vert = vert;
|
||||
++vi;
|
||||
while (vi != poly->end()) {
|
||||
vert = (*vi)->get_pos3();
|
||||
if (!vert.almost_equal(last_vert)) {
|
||||
vertices.push_back(LCAST(float, vert));
|
||||
}
|
||||
|
||||
last_vert = vert;
|
||||
++vi;
|
||||
}
|
||||
}
|
||||
|
||||
if (vertices.size() >= 3) {
|
||||
CollisionPolygon *cspoly =
|
||||
new CollisionPolygon(vertices.begin(), vertices.end());
|
||||
apply_collision_flags(cspoly, flags);
|
||||
cnode->add_solid(cspoly);
|
||||
}
|
||||
}
|
||||
|
||||
if (vertices.size() < 3) {
|
||||
return NULL;
|
||||
}
|
||||
return new CollisionPolygon(vertices.begin(), vertices.end());
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggLoader::apply_deferred_arcs
|
||||
// Access: Private
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@ public:
|
|||
void reparent_decals();
|
||||
void reset_directs();
|
||||
|
||||
|
||||
void make_nonindexed_primitive(EggPrimitive *egg_prim, NamedNode *parent,
|
||||
const LMatrix4d *transform = NULL);
|
||||
|
||||
|
|
@ -100,8 +99,11 @@ private:
|
|||
void apply_collision_flags(CollisionSolid *solid,
|
||||
EggGroup::CollideFlags flags);
|
||||
EggGroup *find_collision_geometry(EggGroup *egg_group);
|
||||
CollisionPlane *create_collision_plane(EggPolygon *egg_poly);
|
||||
CollisionPolygon *create_collision_polygon(EggPolygon *egg_poly);
|
||||
CollisionPlane *create_collision_plane(EggPolygon *egg_poly,
|
||||
EggGroup *parent_group);
|
||||
void create_collision_polygons(CollisionNode *cnode, EggPolygon *egg_poly,
|
||||
EggGroup *parent_group,
|
||||
EggGroup::CollideFlags flags);
|
||||
|
||||
void apply_deferred_arcs(Node *root);
|
||||
|
||||
|
|
@ -125,6 +127,7 @@ private:
|
|||
public:
|
||||
PT_NamedNode _root;
|
||||
EggData _data;
|
||||
bool _error;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,12 @@ load_from_loader(EggLoader &loader) {
|
|||
|
||||
loader.build_graph();
|
||||
|
||||
if (loader._error && !egg_accept_errors) {
|
||||
egg2sg_cat.error()
|
||||
<< "Errors in egg file.\n";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (loader._root != (NamedNode *)NULL && egg_flatten) {
|
||||
SceneGraphReducer gr(RenderRelation::get_class_type());
|
||||
int num_reduced = gr.flatten(loader._root, egg_flatten_siblings);
|
||||
|
|
|
|||
|
|
@ -126,11 +126,12 @@ issue_transformed_color_gl(const Geom *geom, Geom::ColorIterator &citerator,
|
|||
const GLGraphicsStateGuardian *glgsg = DCAST(GLGraphicsStateGuardian, gsg);
|
||||
const Colorf &color = geom->get_next_color(citerator);
|
||||
|
||||
//This is a little cheat here just for a slight bit of
|
||||
//efficiency. We don't want/need to transform the alpha by the color
|
||||
//matrix, so use a Vertexf (which is only 3 component) and multiply
|
||||
//this by the matrix, that will by us 1 dot product
|
||||
Vertexf temp(color[0], color[1], color[2]);
|
||||
// To be truly general, we really need a 5x5 matrix to transform a
|
||||
// 4-component color. Rather than messing with that, we instead
|
||||
// treat the color as a 3-component RGB, which can be transformed by
|
||||
// the ordinary 4x4 matrix, and a separate alpha value, which can be
|
||||
// scaled and offsetted.
|
||||
LPoint3f temp(color[0], color[1], color[2]);
|
||||
temp = temp * glgsg->get_current_color_mat();
|
||||
float alpha = (color[3] * glgsg->get_current_alpha_scale()) +
|
||||
glgsg->get_current_alpha_offset();
|
||||
|
|
|
|||
|
|
@ -112,7 +112,9 @@ invert() const {
|
|||
if (_matrix.almost_equal(Matrix::ident_mat())) {
|
||||
return (MatrixTransition<Matrix> *)this;
|
||||
}
|
||||
return make_with_matrix(::invert(_matrix));
|
||||
Matrix inverted;
|
||||
inverted.invert_from(_matrix);
|
||||
return make_with_matrix(inverted);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -136,18 +136,7 @@ INLINE NodePath::
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool NodePath::
|
||||
operator == (const NodePath &other) const {
|
||||
// If either is a singleton, they must both be the same singleton.
|
||||
if (_head == (ArcComponent *)NULL ||
|
||||
other._head == (ArcComponent *)NULL) {
|
||||
if (_head != (ArcComponent *)NULL ||
|
||||
other._head != (ArcComponent *)NULL ||
|
||||
_top_node != other._top_node) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// If both has at least one arc, check the list of arcs.
|
||||
return r_equiv(_head, other._head);
|
||||
return compare_to(other) == 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -47,6 +47,27 @@ public:
|
|||
GraphicsStateGuardianBase *_gsg;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::compare_to
|
||||
// Access: Public
|
||||
// Description: Returns a number less than zero if this NodePath
|
||||
// sorts before the indicated NodePath in an arbitrary
|
||||
// lexicographical comparision, greater than zero if
|
||||
// this one sorts after the other one, or zero if the
|
||||
// two NodePaths are equivalent.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int NodePath::
|
||||
compare_to(const NodePath &other) const {
|
||||
if (_head == (ArcComponent *)NULL && other._head == (ArcComponent *)NULL) {
|
||||
// If both are singletons, compare the pointers.
|
||||
return _top_node - other._top_node;
|
||||
|
||||
} else {
|
||||
// Otherwise, compare the arc chains.
|
||||
return r_compare_to(_head, other._head);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::extend_by
|
||||
// Access: Public
|
||||
|
|
@ -2430,24 +2451,29 @@ write_bounds(ostream &out) const {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePath::r_equiv
|
||||
// Access: Private
|
||||
// Description: The recursive implementation of operator ==. Returns
|
||||
// true if the list of arcs is equivalent, false
|
||||
// otherwise.
|
||||
// Function: NodePath::r_compare_to
|
||||
// Access: Private, Static
|
||||
// Description: The recursive implementation of compare_to(). Returns
|
||||
// < 0 if a sorts before b, > 0 if b sorts before a, or
|
||||
// == 0 if they are equivalent.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool NodePath::
|
||||
r_equiv(const ArcComponent *next, const ArcComponent *other) const {
|
||||
if (next == (const ArcComponent *)NULL) {
|
||||
nassertr(other == (const ArcComponent *)NULL, false);
|
||||
return true;
|
||||
int NodePath::
|
||||
r_compare_to(const ArcComponent *a, const ArcComponent *b) {
|
||||
if (a == b) {
|
||||
return 0;
|
||||
|
||||
} else if (a == (const ArcComponent *)NULL) {
|
||||
return -1;
|
||||
|
||||
} else if (b == (const ArcComponent *)NULL) {
|
||||
return 1;
|
||||
|
||||
} else if (a->_arc != b->_arc) {
|
||||
return a->_arc - b->_arc;
|
||||
|
||||
} else {
|
||||
return r_compare_to(a->_next, b->_next);
|
||||
}
|
||||
|
||||
nassertr(next != (const ArcComponent *)NULL, false);
|
||||
nassertr(other != (const ArcComponent *)NULL, false);
|
||||
|
||||
return (next == other ||
|
||||
(next->_arc == other->_arc && r_equiv(next->_next, other->_next)));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@ PUBLISHED:
|
|||
|
||||
INLINE bool operator == (const NodePath &other) const;
|
||||
INLINE bool operator != (const NodePath &other) const;
|
||||
int compare_to(const NodePath &other) const;
|
||||
|
||||
INLINE void set_graph_type(TypeHandle graph_type);
|
||||
INLINE TypeHandle get_graph_type() const;
|
||||
|
|
@ -465,7 +466,7 @@ public:
|
|||
};
|
||||
|
||||
private:
|
||||
bool r_equiv(const ArcComponent *next, const ArcComponent *other) const;
|
||||
static int r_compare_to(const ArcComponent *a, const ArcComponent *v);
|
||||
bool r_extend_by(const ArcComponent *other);
|
||||
int r_as_string(const ArcComponent *comp, string &result,
|
||||
int skip_nodes) const;
|
||||
|
|
|
|||
|
|
@ -221,6 +221,20 @@ get_path(int index) const {
|
|||
return NodePath(_node_paths[index]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePathCollection::operator []
|
||||
// Access: Published
|
||||
// Description: Returns the nth NodePath in the collection. This is
|
||||
// the same as get_path(), but it may be a more
|
||||
// convenient way to access it.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
NodePath NodePathCollection::
|
||||
operator [] (int index) const {
|
||||
nassertr(index >= 0 && index < (int)_node_paths.size(), NodePath());
|
||||
|
||||
return NodePath(_node_paths[index]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: NodePathCollection::ls
|
||||
// Access: Published
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ PUBLISHED:
|
|||
bool is_empty() const;
|
||||
int get_num_paths() const;
|
||||
NodePath get_path(int index) const;
|
||||
NodePath operator [] (int index) const;
|
||||
|
||||
// Handy operations on many NodePaths at once.
|
||||
INLINE void ls() const;
|
||||
|
|
|
|||
Loading…
Reference in New Issue