|
|
(世界场景中的碰撞检测---direct3d版)
一个函数就搞定了!!!
出自<Premier Press - Programming Role-Playing Games With Directx 8.0>
Colliding with the World
I don’t know about your games, but in mine, most of my characters are not superheroes,
so they can’t all go around walking through walls! For that reason, a 3-D
engine needs to know when to block the path of a character that is about to collide
with an object such as a wall.
Casting a Ray
In order to check whether a polygon blocks the path from one point to another,
you “cast” an imaginary ray between the two points and check to see whether it
intersects with a plane. Remember planes? I spoke of them in the section, “Planes
and Clipping.” A polygon is nothing more than a finitely sized plane. By constructing
a plane to represent the polygon, you can use algebra to determine the intersection
(refer to Figure 12.7).
(注:figure 12.7 我以附件形式上传)
In the earlier section “Checking for Visibility with the Plane,” you learned about
dot products and calculating distance from points to planes. Using the same calculations,
you can determine if, and where, a point intersects a plane as that point
moves in 3-D space. The point, as it moves, creates a line that represents the path
an object takes during some sort of movement.
Figure 12.8 illustrates these points. In the figure, you see a polygon and a line. The
line represents the ray cast from a starting point to an ending point. The ray intersects
with the polygon about halfway down the ray.abcabcabc
Remember that a plane is infinite in size, so a ray will always intersect with the
plane as long at it isn’t parallel with the plane. For that reason, you must be able to
tell whether the intersection is within the polygon’s edges, and that’s a little more
difficult to do.
Here comes D3DX to the rescue! A single function performs an intersection test,
ensures that the point of the ray-to-plane intersection lies within the polygon, gives
the exact coordinates of the intersection, and, as a bonus, reveals the distance from
the ray’s starting point to the intersection point. Talk about one useful function! So,
which function is it? It’s the D3DXIntersect function, which has the following prototype:
HRESULT D3DXIntersect(
LPD3DXBASEMESH pMesh, // Mesh to check intersection
CONST D3DXVECTOR3 *pRayPos, // Ray origin
CONST D3DXVECTOR3 *pRayDir, // Direction to cast ray
BOOL *pHit, // Flag if intersection occurs
DWORD *pFaceIndex, // Which face ray intersects
FLOAT *pU,
FLOAT *pV,
FLOAT *pDist); // Distance to intersection
Right off the bat, you can see that D3DXIntersect works with meshes (ID3DXBaseMesh),
which is a boon because mesh objects are just what you’re working with at this
point. Next, you can see that you need to specify the starting origin of the ray
(in pRayPos). For pRayPos (and pRayDir), you can use the D3DXVECTOR3 macro inline.
pRayDir represents a direction vector, much like a normal vector. For example, to
cast a ray upward, you use a value of -1.0 for the Y value. The only other argument
you need to deal with is pDist. pDist points to a FLOAT type variable that is filled with
the distance from the ray origin to the intersection point.
一个函数就搞定,简单吧!
|
-
|