Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (2.94 MB, 633 trang )

12.3 Holes, Cracks, Gaps, and T-junctions

485

t-junction

crack

gap

t-vertex

(a)

(b)

(c)

Figure 12.9 (a) A (nonhole) crack. (b) A gap. (c) A t-junction (and its corresponding t-vertex).

Several methods can be employed for detecting the presence of t-junctions. A

straightforward approach is to loop over all vertices of the mesh and for each vertex

test its connected edges, pairwise, for (near) collinearity. If two collinear edges are

found, the edges are part of a crack. The crack can be resolved by merging the endpoint

of one edge onto the other edge. Because vertices may be visited in any order, for

this approach to correctly resolve cracks that involve an arbitrary number of vertices

it is important that the endpoint vertices of the two merged edges be recursively

revisited after the merge to locate all vertices on the edge-chain of the crack. If the

mesh under repair is known to be 2-manifold, it is possible to limit the process

to examining only those edges that have exactly one face connected to them. This

method is simple to implement and it deals with all cracks correctly. However, it does

not address gaps, in that gaps by deﬁnition cannot be found by a local examination

of the geometry.

Resolving gaps correctly requires a more sophisticated, global method. Given an

edge, this method must be able to ﬁnd all mesh vertices lying on or nearly on the

edge. Alternatively, given a vertex the method must be able to locate all edges the

vertex is near. A practical solution is to insert all mesh edges into a hierarchical

structure like an hgrid or a loose octree, which can then be queried for each vertex

of the mesh.

As crack- or gap-induced t-junctions are found, they must be resolved. There are

three main approaches to resolving t-junctions (illustrated in Figure 12.10).

●

Vertex collapse. The t-vertex is displaced along the edge opposing it, toward either

endpoint of the edge, and collapsed with that endpoint.

●

Edge cracking. A more general solution is to split the edge opposing the t-vertex

in half and connect the two new endpoints to the t-vertex. This increases the

vertex count of all faces connected to the opposing edge by one.

486

Chapter 12 Geometrical Robustness

(a)

(b)

(c)

Figure 12.10 Three alternative methods for resolving a t-junction. (a) Collapsing the t-vertex

with a neighboring vertex on the opposing edge. (b) Cracking the opposing edge in two,

connecting the two new edge endpoints to the t-vertex. (c) Snapping the vertex onto the

opposing edge and inserting it, by edge cracking, into the edge.

●

Vertex snapping. Similar to edge cracking, this approach ﬁrst snaps the t-vertex

to lie on the opposing edge, after which the edge is cracked as in the previous

alternative.

Vertex collapsing is not applicable in all situations, but when it is it is often preferable

because it reduces the vertex count by one. It also effectively removes one edge from

one of the faces connected to the t-vertex and the vertex into which the t-vertex is

collapsed. When this face is a triangle, it becomes degenerate and can be removed.

Note that all three approaches can create nonplanar or nonconvex faces. Subsequent

triangulation of the involved faces may therefore be required.

When working with nonmanifold geometry, gaps may also appear as one face sits

slightly above another face; for example, a small face upright in the middle of a large

horizontal face (as shown in Figure 12.11). To resolve this, the second larger face must

be split up to incorporate the edge of the ﬁrst face. This face cracking can be handled

by the same hierarchical data structure used for edge cracking if mesh faces instead

of mesh edges are inserted into the data structure.

For some intersection queries, such as ray-versus-mesh tests, interpenetrating

surfaces do not pose a problem to the queries. If this is the case, the face cracking

12.4 Merging Co-planar Faces

(a)

487

(b)

Figure 12.11 (a) A face meeting another face edge-on, forming a gap. (b) The gap resolved

by face cracking.

does not have to be performed when the vertices of the edge lie in the negative

halfspace of the supporting plane of the other face.

12.4 Merging Co-planar Faces

Edge and face cracking may introduce a fair number of extra faces to the collision.

Because collision detection speed decreases as the number of faces increases, it is

worthwhile incorporating an optimization step into the generation of robust collision

geometry to help reduce the number of faces.

Many methods have been suggested for model simpliﬁcation. Thorough reviews

of the ﬁeld are given in [Luebke02] and [Puppo97]. For collision detection, it is

very important to preserve both shape and volume to prevent the collision geometry

from “shrinking”inside the visual representation, allowing objects to interpenetrate

visually even though they may not actually be touching in a collision sense. Out

of the huge library of simpliﬁcation methods, one approach particularly suitable for

collision detection geometry is that of merging (near) co-planar faces. Face merging also helps to remove sliver-like and other degenerate faces, which are usually a

source of robustness problems (see Chapter 11).

In addition to two faces being co-planar up to some given tolerance, some other

criteria generally must be fulﬁlled for two faces to be mergeable. Speciﬁcally, the faces

must:

●

both be either double or single sided, and face in the same general direction

when single sided,

●

have the same associated surface properties (footstep sounds, friction attributes,

or similar attributes), and

●

share one or more boundary edges.

488

Chapter 12 Geometrical Robustness

In this text, when two or more faces are said to be co-planar it is assumed that the

faces are mergeable under these criteria.

Because the result of preprocessing is likely a triangle or quad mesh, one alternative

is to merge two or more co-planar faces as long as the resulting face is a triangle or

a quad. This straightforward approach is simple to implement. However, for it to

produce a near-optimal result large clusters of faces would have to be considered for

simultaneous merging. For example, for the spiral-like mesh given in Figure 12.12 no

combination of faces other than all nine faces together form a convex face. Thus, a

combinatorial number of face combinations would have to be tested for merging in

the worst case, which is impractical.

A more involved method, but which promises much better results, is to merge all

co-planar neighboring faces into a single (concave) polygon in a ﬁrst pass. In a subsequent second pass, these polygons are then triangulated or otherwise decomposed

into the type of convex pieces desired for the end result.

If adjacency information is available, it is straightforward to merge neighboring

co-planar faces simply by visiting neighboring faces through the provided adjacency

links. For example, given an edge-face table the merging process is linear in the

number of edges, proceeding by looping over the edges and merging the faces connected to the edge if co-planar. If no adjacency information is available, instead of

ﬁrst computing adjacency information and then proceeding as described previously

an alternative option is to ﬁnd nearly co-planar faces through a scheme similar to

environment cube mapping [Akenine-Möller02].

Figure 12.12 If two (or more) faces are only considered for merging when the resulting face

is convex, no merging can be done for this spiral-like mesh. If concave faces are allowed

during merging, this mesh can be merged into a single (quadrilateral) face.

12.4 Merging Co-planar Faces

489

c

c1

c2

n

n±e

(a)

(b)

Figure 12.13 (a) The normal n hits cell c (dashed) on the top face of the cube inscribed in

the unit sphere. (b) The perturbed normal n ± e hits cells c1 and c2 . The contents of these

cells must be tested for co-planarity with the polygon having the normal n.

Each polygon normal can be seen as describing a position of the surface of the

unit sphere. Let a cube be inscribed in the unit sphere, each cube face divided into a

number of cells of a ﬁxed uniform size. Each polygon normal will intersect some cube

face cell (Figure 12.13a). Let polygons be associated with the face cell their normals

intersect.

Near co-planar polygons will now largely map to the same cell, allowing them to

be further processed after their co-planarity has been veriﬁed. However, due to the

arbitrary discretization into cells, two plane normals arbitrarily close may still end up

in different cells. A simple solution to this problem is to test all eight neighboring

face cells of the cell the polygon normal intersected. Some care must be taken near

the cube edges to make sure the correct cells are visited.

To cut down on the number of neighboring cells to test, the polygon normal n can

be perturbed slightly in the plane of the intersected face, giving a rectangular region

in the face, describing the area for which normals would be considered coplanar to

n. All cells overlapped by the rectangular region would then be tested, similar to

before (Figure 12.13b). Typically, the number of cells overlapped by this region would

be smaller than eight. Again, care must be taken to visit the correct cells when the

rectangular region extends over a cube edge.

The presented method has an expected complexity of O(n). An alternative but

less efﬁcient O(n log n) tree-based sorting method is given in [Salesin92]. Alternative solutions to the problem of merging (near) co-planar faces are presented in

[Hinker93] and [Kalvin96].

12.4.1 Testing Co-planarity of Two Polygons

One approach to testing if two polygons are co-planar is to compute the angle

between their plane normals. If the angle is less than some given tolerance, the

490

Chapter 12 Geometrical Robustness

polygons are considered co-planar and can be merged. This method works for many

applications, such as general model simpliﬁcation [Hinker93]. However, for collision

detection purposes this approach is fundamentally ﬂawed. Consider two polygons,

A1 and B1 , at a ﬁxed angle θ to each other, requiring a plane thickness of d1 of

a representative plane for all vertices to be included in the plane, as illustrated in

Figure 12.14. Let the polygons be scaled up in size, giving A2 and B2 . Even though θ

remains constant, the required thickness d2 of the new representative plane increases

without bound as the polygons are scaled up in size.

Clearly, the angle between the polygon normals is only a relative measurement of

the co-planarity of the polygons. For an absolute error measurement, the thickness

of the representative plane must be considered. A better solution to testing two

polygons for co-planarity is therefore to perform the merging of the two polygons,

conceptually, and see if the resulting polygon is considered planar by a polygon

planarity test (presented in the next section). This approach directly extends to the

merging of an arbitrary number of polygons.

To use a relative measurement of co-planarity for controlling merging of polygons

for use with a collision detection system, the vertices of the merged polygons must be

snapped to the representative plane of the merged polygon. This bounds the deviation

of the polygon vertices from the plane, allowing the distance error to remain less than

the tolerance value used to enforce thickness of the polygon for robust intersection

tests.

However, with welded vertices snapping the vertices of one or more polygons to a

representative plane inevitably introduces nonplanarity errors in faces sharing vertices

with these polygons. Trying to address this would likely cause a ripple effect involving

all vertices of the object. A reasonable solution is to let a subsequent triangulation

pass take care of triangulating any faces that have been made more nonplanar than

the given tolerance allows. Unfortunately, nothing guarantees that there are not more

faces created during this triangulation than are removed through the initial merging

process!

A1

A2

B1

d1

B2

d2

Figure 12.14 Testing the angle between the normals of the planes of two polygons is a

relative measurement of their co-planarity, unaffected by scaling up the polygons. Testing

the thickness required for the best-ﬁt plane to contain all polygon vertices is an absolute

measurement of the co-planarity of the polygons.

12.4 Merging Co-planar Faces

491

Figure 12.15 The upper illustration shows how an absolute merging tolerance smaller than

the plane thickness tolerance (in gray) avoids cracks from appearing between neighboring

faces. The lower illustration shows how a crack may appear when the merging tolerance

exceeds the plane thickness tolerance.

Worse, if vertices are unwelded and are allowed to move during merging cracks can

appear at the edges between neighboring faces unless the absolute merging tolerance

is kept smaller than the plane thickness tolerance. Figure 12.15 illustrates how a crack

may appear between a face and a merged face when the merging tolerance exceeds

the plane thickness tolerance. To avoid tolerance issues that would cause robustness

problems and to guarantee the reduction of faces due to merging, it is important

to use an absolute error measurement for merging geometry for use with collision

detection.

12.4.2 Testing Polygon Planarity

A polygon is deﬁned by a set of vertices in the plane. Testing the polygon for planarity

then involves making sure all deﬁning vertices lie in a plane. This can be done by

computing a plane equation for the supporting plane of the polygon and then testing

all vertices to make sure they are within some tolerance of the plane. The plane

equation for the supporting plane is obtained through computing a polygon normal

and selecting a reference point on the polygon.

This sounds simple enough, but there is a hidden subtlety: how to compute the

polygon normal n = (nx , ny , nz ). A ﬁrst approach to computing the polygon normal might involve computing the cross product of two coincident polygon edges.

However, this is not robust because the edges may be (near) collinear, causing the

492

Chapter 12 Geometrical Robustness

cross product result to be the zero vector (and making the computation suffer large

cancellation errors well before becoming zero).

Even if the angle between the edges is large, there is still a problem. Assume all

vertices lie on a plane, except for the vertex V shared by the two edges. Let V deviate

from the plane by some distance d. If the polygon is scaled up in the plane, V will

remain at a distance d from the plane and the absolute planarity of the polygon

should not be affected. However, because the cross product of those two edges was

chosen as the representative plane normal, all vertices but the three coincident with

the two edges will move arbitrarily far from the chosen plane as the polygon is

scaled up.

It seems clear that all vertices should somehow be involved in the normal computation. One common approach is to compute the normal ni at each vertex Vi

(as the cross product of the edges incident at the vertex) and then average the

normals:

n=

1

n

ni ,

where ni = (Vi+1 − Vi ) × (Vi−1 − Vi ).

0≤i

It is here assumed that Vn = V0 and V−1 = Vn−1 . Because the magnitude of n is

unimportant, the normals can be summed rather than averaged.

Although this works well for convex polygons, it is unfortunately ﬂawed for nonconvex polygons. Normals computed at concave vertices will point in the opposite

direction of those computed at convex vertices. For example, consider the class of

star-shaped polygons shown in Figure 12.16. The normals at the even-numbered

vertices point out of the page, whereas the normals of the odd-numbered vertices

point into the page.

K=1

K=4

V0 = (1, 1, 1)

V1 = (6, 6 – K, 1)

V2 = (11, 1, 1)

V3 = (6 + K, 6, 1)

V4 = (11, 11, 1)

V5 = (6, 6 + K, 1)

V6 = (1, 11, 1)

V7 = (6 – K, 6, 1)

Figure 12.16 A class of star-shaped polygons, parameterized by K, 0 < K < 5.

12.4 Merging Co-planar Faces

493

When normals of opposing direction are summed, the result may point in either

direction, depending on the relative magnitudes of the inputs. Speciﬁcally, in this case

the following (unnormalized) normals are obtained for a few different values of K:

K

n

1

(0, 0, −124)

2

(0, 0, −56)

3

(0, 0, 4)

4

(0, 0, 56)

As the table indicates, the normal changes direction between K = 2 and K = 3.

In fact, at about K = 2. 928932 the normal becomes the zero vector and the method

fails catastrophically!

It turns out that a much better and robust approach to computing normals is one

commonly known as Newell’s method [Tampieri92]. Newell’s method uses the fact

that the components of a polygon normal are proportional to the signed areas of

the projections of the polygon onto the yz, xz, and xy planes. n can therefore be

computed as:

nx =

(Vi,y − Vi+1,y )(Vi,z + Vi+1,z )

0≤i

ny =

(Vi,z − Vi+1,z )(Vi,x + Vi+1,x )

0≤i

nz =

(Vi,x − Vi+1,x )(Vi,y + Vi+1,y )

0≤i

The terms being summed correspond to twice the signed area of the trapezoids

formed, in each principal plane, by the current polygon edge and its projection onto

the corresponding axis. The ﬁrst term is the width of the trapezoid; the second term

is twice its height. By rearranging terms, it can be seen that Newell’s method is

equivalent to computing the normal through the sum:

n=

mi ,

0≤i

where mi = Vi × Vi+1 .

494

Chapter 12 Geometrical Robustness

For the star-shaped polygon used earlier, Newell’s method consistently produces

the expected normal (pointing out of the page):

K

n

1

(0, 0, 40)

2

(0, 0, 80)

3

(0, 0, 120)

4

(0, 0, 160)

The following code illustrates how Newell’s method can be implemented to compute a robust representative plane for a polygon. Here, the polygon centroid — that

is, the average of all vertices — is used as the representative point on the plane when

computing the plane equation.

// Given n-gon specified by points v[], compute a good representative plane p

void NewellPlane(int n, Point v[], Plane *p)

{

// Compute normal as being proportional to projected areas of polygon onto the yz,

// xz, and xy planes. Also compute centroid as representative point on the plane

Vector centroid(0.0f, 0.0f, 0.0f), normal(0.0f, 0.0f, 0.0f);

for (int i = n - 1, j = 0; j < n; i = j, j++) {

normal.x += (v[i].y - v[j].y) * (v[i].z + v[j].z); // projection on yz

normal.y += (v[i].z - v[j].z) * (v[i].x + v[j].x); // projection on xz

normal.z += (v[i].x - v[j].x) * (v[i].y + v[j].y); // projection on xy

centroid += v[j];

}

// Normalize normal and fill in the plane equation fields

p->n = Normalize(normal);

p->d = Dot(centroid, p->n) / n; // “centroid / n” is the true centroid point

}

Newell’s method can be seen as computing a “best-ﬁt” plane, using all vertices.

Yet another alternative approach is to ﬁt a plane to the polygon vertices using the

method of least-squares ﬁt (see [Eberly01] for details).

Computing plane equations using Newell’s method is clearly more expensive than

just taking the cross product of two coincident edges. Storing plane equations with

the polygons is one option, but this is unattractive memory-wise. A compromise is

still computing normals and plane equations at runtime using a cross product, but

after having made sure the polygon is output so that the ﬁrst three stored vertices of

12.5 Triangulation and Convex Partitioning

495

the polygon give the best representative result. It is also possible to simplify Newell’s

method for speciﬁc primitives. For example, given a quadrilateral ABCD the normal

obtained by Newell’s method can be reduced to that of computing the cross product

of the two diagonals AC and DB because

2(AC × DB) = (AB × AD) + (BC × BA) + (CD × CB) + (DA × DC).

The right-hand side of the expression corresponds to the summing of the cross

product normals at each vertex. Interestingly, it is thus actually cheaper to compute

a robust normal for a quadrilateral than it is to do the same for a triangle!

After having computed a good representative plane for a polygon, it is ﬁnally

possible to test the planarity of the polygon by putting each of its vertices, in turn,

through the computed plane equation to see by how much each vertex deviates from

the plane. If they are all within a preset tolerance distance from the plane, the polygon

is considered planar. An implementation of this test follows.

// Test if n-gon specified by vertices v[] is planar

int IsPlanar(int n, Point v[])

{

// Compute a representative plane for the polygon

Plane p;

NewellPlane(n, v, &p);

// Test each vertex to see if it is farther from plane than allowed max distance

for (int i = 0; i < n; i++) {

float dist = Dot(p.n, v[i]) - p.d;

if (Abs(dist) > PLANARITY_EPSILON) return 0;

}

// All points passed distance test, so polygon is considered planar

return 1;

}

In [Sunday02], the author addresses how to reduce the number of arithmetic

operations needed to compute Newell normals and polygon areas.

12.5 Triangulation and Convex Partitioning

Although it would be possible to perform collision detection directly against the

merged faces, tests involving convex faces only are often simpler, faster, and more

robust. It therefore makes sense to decompose nonconvex faces into two or more

convex pieces, a process known as convex partitioning. One alternative is simply to

Tải bản đầy đủ (.pdf) (633 trang)