Objective
In the DirectX SDK, the correlation function for collision detection is in xnacollision.h. Now, however, the previously implemented correlation functions have been transferred to the Windows SDK DirectXCollision.h and are in namespace DirectX. This consists mainly of four bounding boxes (bounding Volumes), and is implemented in the form of classes:
- Boundingsphere class-Surround ball (bounding Box)
- BoundingBox Class--axis aligned bounding box (axis-aligned bounding box), also known as AABB box
- Boundingorientedbox class--to the bounding box (oriented bounding box), also known as the Obb box
- Boundingfrustum class--bounding cones (bounding Frustum)
In addition, it also contains a triangle (Ray) and the rest of the collision detection of the object.
Subsequent projects will use the crash library.
DirectX11 with Windows SDK full catalog
GitHub Project Source
Common bounding box surround ball (bounding box)
A sphere can be represented only by using the center coordinate and radius. Part of the structure is as follows:
struct boundingsphere{XMFLOAT3 Center; Sphere Center coordinate float Radius; Sphere Radius//constructor Boundingsphere (): Center (0,0,0), radius (1.f) {} xm_constexpr boundingsphere (const XMFLOAT3 & Center, float radius): Center (center), radius (radius) {} boundingsphere (const boundingsphere& SP) : Center (sp. Center), Radius (sp. Radius) {}///////static method of Creation createmerged (boundingsphere& out, const BOUNDINGSPHERE&AM P S1, const boundingsphere& S2); static void Createfromboundingbox (boundingsphere& out, const boundingbox& box); static void Createfromboundingbox (boundingsphere& out, const boundingorientedbox& box); static void Createfrompoints (boundingsphere& out, size_t Count, const xmfloat3* ppoints, size_t Stride); static void Createfromfrustum (boundingsphere& out, const boundingfrustum& fr);};
The BoundingSphere::CreateMergerd
static method tightly encloses the two surrounding spheres in the scene with a larger bounding ball.
BoundingSphere::CreateFromBoundingBox
The static method is to create a bounding ball from the Aabb box or the Obb box.
It is then necessary to highlight the BoundingSphere::CreateFromPoints
use of static methods, because we typically use a custom struct to describe a vertex and then use a vertex array, so the method is also suitable for creating a bounding ball from a vertex array.
The parameters Count
describe the number of vertices.
The parameter pPoints
needs to be filled with the address of the position vector in the first element of the vertex array.
The parameter can be said to be the Stride
byte size of the vertex structure, or the number of bytes to be shifted to the position vector that jumps to the next element.
The following is an example of use:
struct VertexPosNormalTex{ XMFLOAT3 pos; XMFLOAT3 normal; XMFLOAT3 tex;};VertexPosNormalTex vertices[20];// 省略初始化操作...BoundingSphere sphere;BoundingSphere::CreateFromPoints(sphere, 20, &vertices[0].pos, sizeof(VertexPosNormalTex));
Shaft-aligned bounding box (axis-aligned bounding box)
If an object has a AABB box, the six sides of the Aabb box will be tightly attached to the object. It can be described in two points: Vmax and Vmin. The meaning of Vmax is to take the maximum value of x, Y, and z components in all vertices of an object to form the vertex respectively. The meaning of Vmin is to take the minimum value of the X, Y, and z components of all vertices of an object to form the vertex.
After acquiring these two points, we can use another expression: the meaning of each component of the center position C and a 3D vector e,e is the distance (the distance is equal) between the two faces of the corresponding axis of the component.
The collision Library uses the second representation, but it also supports building in the first way. Part of the structure is as follows:
struct boundingbox{static const size_t Corner_count = 8; Number of boundary points XMFLOAT3 Center; Box center point XMFLOAT3 extents; The distance from the center point to each polygon//constructor BoundingBox (): Center (0,0,0), extents (1.F, 1.F, 1.f) {} xm_constexpr BoundingBox (con St xmfloat3& Center, Const xmfloat3& extents): Center (center), extents (extents) {} boundingbox (const BO undingbox& box): Center (box. Center), Extents (box. Extents) {}//...//static method of Creation createmerged (boundingbox& out, const boundingbox& B1, const boundingbox& B2); static void Createfromsphere (boundingbox& out, const boundingsphere& SH); static void Xm_callconv createfrompoints (boundingbox& out, Fxmvector pt1, Fxmvector pt2); static void Createfrompoints (boundingbox& out, size_t Count, const xmfloat3* ppoints,size_t Stride);};
BoundingBox::CreateMerged
The static method creates a minimal AABB box that can contain these two aabb boxes simultaneously.
BoundingBox::CreateFromSphere
The static method creates an external cube bounding box for the sphere.
BoundingBox::CreateFromPoints
The parameters in a static pt1
method pt2
can be two vertices on a diagonal diagonal of the bounding box, or a two construction point that contains the maximum and minimum values of the XYZ component in all points.
bounding box with direction (oriented bounding box)
For some objects, the bounding box needs to change after a series of transformations. But for example, some objects, such as airplanes, books, and so on by default, whose width and depth are much larger than the height of the AABB, can become particularly large, exposing a lot of spare positions and thus not being able to wrap objects well.
Because the boundary of the AABB box is axis-aligned, there is no way to record the rotation property. At this time we can consider using the Obb box, in addition to the information that contains the AABB box should be recorded, it also records the rotation-related information. The structure section is as follows:
struct boundingorientedbox{static const size_t Corner_count = 8; Number of boundary points XMFLOAT3 Center; Box center point XMFLOAT3 extents; The distance from the center point to each face XMFLOAT4 Orientation; Unit rotation four yuan (object--world)//Constructor Boundingorientedbox (): Center (0,0,0), extents (1.F, 1.F, 1.f), Orientation (0,0,0, 1. f) {} xm_constexpr Boundingorientedbox (const xmfloat3& _center, const xmfloat3& _extents, const xmfloat4& _orientation): Center (_center), extents (_extents), Orientation (_orientation) {} boundingorientedbox (const Bound ingorientedbox& box): Center (box. Center), Extents (box. extents), Orientation (box. Orientation) {}//...//static method of Creation Createfromboundingbox (boundingorientedbox& out, const Boundi ngbox& box); static void Createfrompoints (boundingorientedbox& out, size_t Count, const xmfloat3* ppoints, size_t Stride);} ;
The BoundingOrientedBox::CreateFromBoundingBox
static method creates the same Obb box as the Aabb box, and the unit rotation of four yuan is the default (that is, no rotation is generated).
Bounding cones (bounding Frustum)
To describe a visual cone, one way is to specify the six boundary planes of the view cone in mathematical form: Left/right plane, top/bottom plane, near/far plane. This assumes that the six frustum planes are facing inward.
Although we can use six 4D planar vectors to store a cone of view, there is a more space-saving representation.
First, in the object coordinate system, take the camera position as the origin point, the forward direction is the Z axis, the right direction is the X axis, the upper direction is the Y axis, so you can get the right (left) plane projection to the Zox plane slope of x/z (-x/z), and the upper (lower) plane projection to the Zoy plane slope is y/z (-y/z). You can also get the distance from the near (far) plane to the origin, which is the corresponding z-value.
It then uses a 3D position vector and a unit rotation of four to represent the position and orientation of the cones in the world. So we can also describe a cone of sight.
The following shows some of the contents of the Cones bounding box structure:
struct boundingfrustum{static const size_t Corner_count = 8; XMFLOAT3 Origin; The location of the camera in the world, the object coordinate system by default will be set to (0.0f, 0.0f, 0.0f) XMFLOAT4 Orientation; Unit rotation of four yuan float rightslope; The straight slope of the right plane projection to the Zox plane +x/z float leftslope; The linear slope of the left plane projection to the Zox plane-x/z float topslope; The linear slope of the upper plane projection to the Zoy plane +y/z float bottomslope; The lower plane is projected to a straight line slope of the Zoy plane-y/z float near, far; The z-value corresponds to the distance from the near (far) plane to the camera object's coordinate system origin//constructor Boundingfrustum (): Origin (0,0,0), Orientation (0,0,0, 1.f), Rightslope (1.F), L Eftslope ( -1.F), Topslope (1.F), Bottomslope ( -1.F), near (0), far (1.f) {} xm_constexpr Boun Dingfrustum (const xmfloat3& _origin, const xmfloat4& _orientation, float _rightslope, float _le Ftslope, float _topslope, float _bottomslope, float _near, float _far): Origin (_origin), Orient ation (_orientation), Rightslope (_rightslope), Leftslope (_leftslope), TOpslope (_topslope), Bottomslope (_bottomslope), near (_near), far (_far) {} boundingfrustum (const boundingfrustum & FR): Origin (Fr. Origin), Orientation (Fr. Orientation), Rightslope (Fr. Rightslope), Leftslope (Fr. Leftslope), Topslope (Fr. Topslope), Bottomslope (Fr. Bottomslope), near (Fr. Near), far (Fr. FAR) {} boundingfrustum (Cxmmatrix Projection) {Createfrommatrix (*this, Projection);} ...///Static Creation Method Xm_callconv Createfrommatrix (boundingfrustum& out, Fxmmatrix Projection);}
Typically, we create a bounding cone by passing the projection matrix, rather than specifying the above information directly.
Intersection of bounding box, inclusion, collision detection and intersection detection of transformed bounding box and plane
For intersection detection of the bounding box and the plane, the return result uses the enumeration type PlaneIntersectionType
to describe the intersection situation:
enum PlaneIntersectionType{ FRONT = 0, // 包围盒在平面的正面区域 INTERSECTING = 1, // 包围盒与平面有相交 BACK = 2, // 包围盒在平面的背面区域};
The four bounding boxes mentioned above have an overloaded method intersects to detect the intersection of the bounding box with the plane:
PlaneIntersectionType XM_CALLCONV Intersects(FXMVECTOR Plane) const;
The positive/Reverse decision depends on the setting of the first plane normal vector. For example, a center at the origin, a square with a length of 2, and a plane-z+2=0 (corresponding to the 4D plane vector (0.0f,0.0f,-1.0f,2.0f), planar normal vector (0.0f,0.0f,-1.0f)) intersect the result: The object is in the frontal area of the plane.
Inclusion detection of bounding box and bounding box
For the inclusion detection of two bounding boxes, the returned result uses an enumeration type ContainmentType
to describe the containment situation:
enum ContainmentType{ DISJOINT = 0, // 两个包围盒相互分离 INTERSECTS = 1, // 两个包围盒有相交 CONTAINS = 2, // 两个包围盒存在包含关系};
These four bounding boxes have a corresponding method to test each other:
ContainmentType Contains(const BoundingSphere& sp) const;ContainmentType Contains(const BoundingBox& box) const;ContainmentType Contains(const BoundingOrientedBox& box) const;ContainmentType Contains(const BoundingFrustum& fr) const;
Collision detection of bounding box and bounding box
If we only need to check if there is a collision between the two bounding boxes (intersect and include), you can use these methods. Each of the four bounding boxes is capable of collision testing with each other:
bool Intersects(const BoundingSphere& sh) const;bool Intersects(const BoundingBox& box) const;bool Intersects(const BoundingOrientedBox& box) const;bool Intersects(const BoundingFrustum& fr) const;
The transformation of the bounding box
The four bounding boxes contain the following two methods, one is the transformation of any matrix and the other is the transformation of the constructed World matrix (this is used BoundingVolume
to refer to these four bounding boxes):
void XM_CALLCONV Transform(BoundingVolume& Out, FXMMATRIX M ) const;void XM_CALLCONV Transform(BoundingVolume& Out, float Scale, FXMVECTOR Rotation, FXMVECTOR Translation) const;
Note that the first parameter is for the bounding box after the output transformation, which is the Rotation
unit rotation of four.
Other methods of bounding box to get the eight vertices of a bounding box
In addition to enclosing the ball outside the bounding box has the method GetCorners
:
void GetCorners(XMFLOAT3* Corners) const;
The parameter that is passed here Corners
is an array that can hold at least 8 of the number of elements.
Get six planes that surround the view cone
BoundingFrustum::GetPlanes
method to obtain a planar vector of six planes of the cone of view:
void GetPlanes(XMVECTOR* NearPlane, XMVECTOR* FarPlane, XMVECTOR* RightPlane, XMVECTOR* LeftPlane, XMVECTOR* TopPlane, XMVECTOR* BottomPlane) const;
Surround cones when detecting whether a bounding box is included, the static overloaded method of the bounding box to be measured is called internally ContainedBy
, and the parameters are six planes provided by the cone. So the following methods are usually not used directly:
ContainmentType XM_CALLCONV ContainedBy(FXMVECTOR Plane0, FXMVECTOR Plane1, FXMVECTOR Plane2, GXMVECTOR Plane3, HXMVECTOR Plane4, HXMVECTOR Plane5 ) const;// Test frustum against six planes (see BoundingFrustum::GetPlanes)
Triangles, rays
The representation of a triangle requires a vector of three coordinate points, and the ray's representation requires a Origin
vector (the beginning of the Ray) and a Direction
vector (the ray direction).
Intersection detection of a ray (triangle) and a non-bounding box
The following three commonly used methods are in the namespace DirectX::TriangleTests
( ContainedBy
functions are not directly used and are not listed):
namespace TriangleTests{ bool XM_CALLCONV Intersects(FXMVECTOR Origin, FXMVECTOR Direction, FXMVECTOR V0, GXMVECTOR V1, HXMVECTOR V2, float& Dist ); // 射线与三角形的相交检测 bool XM_CALLCONV Intersects(FXMVECTOR A0, FXMVECTOR A1, FXMVECTOR A2, GXMVECTOR B0, HXMVECTOR B1, HXMVECTOR B2 ); // 三角形与三角形的相交检测 PlaneIntersectionType XM_CALLCONV Intersects(FXMVECTOR V0, FXMVECTOR V1, FXMVECTOR V2, GXMVECTOR Plane ); // 平面与三角形的相交检测 // 忽略...};
Where the Dist
distance from the beginning of the ray to the intersection is returned, if no intersection is detected, Dist
the value is0.0f
Intersection detection of a ray (triangle) and bounding box
The four bounding boxes contain the following two methods:
bool XM_CALLCONV Intersects(FXMVECTOR Origin, FXMVECTOR Direction, float& Dist) const;// 射线与包围盒的相交检测bool XM_CALLCONV Intersects(FXMVECTOR V0, FXMVECTOR V1, FXMVECTOR V2) const;// 三角形与包围盒的相交检测
Demo Program
A demo of the collision Detection library can be found in the link below, where there is no need to write a demo program:
DirectX SDK Samples
After downloading (cloning) to the local find the Collision folder, select the appropriate solution to open and compile and run. What I chose here is the Collision_desktop_2017_win10.sln. The results of successful operation are as follows:
DirectX11 with Windows SDK full catalog
GitHub Project Source
DirectX11 with Windows sdk--18 collision detection using the Directxcollision library