# 前言

1. BoundingSphere类--包围球(Bounding Box)
2. BoundingBox类--轴对齐包围盒(Axis-aligned bounding box)，又称AABB盒
3. BoundingOrientedBox类--有向包围盒(Oriented bounding box)，又称OBB盒
4. BoundingFrustum类--包围视锥体(Bounding Frustum)

DirectX11 With Windows SDK完整目录

Github项目源码

# 常见包围盒

## 包围球(Bounding Box)

struct BoundingSphere
{
XMFLOAT3 Center;            // 球体中心坐标
float Radius;               // 球体半径

// 构造函数
BoundingSphere() : Center(0,0,0), Radius( 1.f ) {}
XM_CONSTEXPR BoundingSphere(const XMFLOAT3& center, float radius )
BoundingSphere(const BoundingSphere& sp )

// ...

// 静态创建方法
static void CreateMerged(BoundingSphere& Out, const BoundingSphere& 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 );

};


BoundingSphere::CreateFromBoundingBox静态方法则是从AABB盒或OBB盒创建出外接包围球。

struct VertexPosNormalTex
{
XMFLOAT3 pos;
XMFLOAT3 normal;
XMFLOAT3 tex;
};

VertexPosNormalTex vertices[20];
// 省略初始化操作...
BoundingSphere sphere;
BoundingSphere::CreateFromPoints(sphere, 20, &vertices[0].pos, sizeof(VertexPosNormalTex));


## 轴对齐包围盒(Axis-aligned bounding box)

struct BoundingBox
{
static const size_t CORNER_COUNT = 8;   // 边界点数目

XMFLOAT3 Center;            // 盒中心点
XMFLOAT3 Extents;           // 中心点到每个面的距离

// 构造函数
BoundingBox() : Center(0,0,0), Extents( 1.f, 1.f, 1.f ) {}
XM_CONSTEXPR BoundingBox(const XMFLOAT3& center, const XMFLOAT3& extents)
: Center(center), Extents(extents) {}
BoundingBox(const BoundingBox& box) : Center(box.Center), Extents(box.Extents) {}

// ...

// 静态创建方法
static void 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静态方法创建一个最小的AABB盒，能够同时包含这两个AABB盒。

BoundingBox::CreateFromSphere静态方法给球体创建外接立方体包围盒。

BoundingBox::CreateFromPoints静态方法中的参数pt1pt2即可以为包围盒某一斜对角线上的两个顶点，也可以是一个包含所有点中xyz分量最大值和最小值的两个构造点。

## 有向包围盒(Oriented bounding box)

struct BoundingOrientedBox
{
static const size_t CORNER_COUNT = 8;   // 边界点数目

XMFLOAT3 Center;            // 盒中心点
XMFLOAT3 Extents;           // 中心点到每个面的距离
XMFLOAT4 Orientation;       // 单位旋转四元数(物体->世界)

// 构造函数
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 BoundingOrientedBox& box)
: Center(box.Center), Extents(box.Extents), Orientation(box.Orientation) {}

// ...

// 静态创建方法
static void CreateFromBoundingBox(BoundingOrientedBox& Out, const BoundingBox& box );

static void CreateFromPoints(BoundingOrientedBox& Out, size_t Count,
const XMFLOAT3* pPoints, size_t Stride );
};


## 包围视锥体(Bounding Frustum)

struct BoundingFrustum
{
static const size_t CORNER_COUNT = 8;

XMFLOAT3 Origin;            // 摄像机在世界中的位置，物体坐标系下默认会设为(0.0f, 0.0f, 0.0f)
XMFLOAT4 Orientation;       // 单位旋转四元数

float RightSlope;           // 右*面投影到zOx*面的直线斜率+X/Z
float LeftSlope;            // 左*面投影到zOx*面的直线斜率-X/Z
float TopSlope;             // 上*面投影到zOy*面的直线斜率+Y/Z
float BottomSlope;          // 下*面投影到zOy*面的直线斜率-Y/Z
float Near, Far;            // Z值对应*(远)*面到摄像机物体坐标系原点的距离

// 构造函数
BoundingFrustum() : Origin(0,0,0), Orientation(0,0,0, 1.f), RightSlope( 1.f ), LeftSlope( -1.f ),
TopSlope( 1.f ), BottomSlope( -1.f ), Near(0), Far( 1.f ) {}
XM_CONSTEXPR BoundingFrustum(const XMFLOAT3& _Origin, const XMFLOAT4& _Orientation,
float _RightSlope, float _LeftSlope, float _TopSlope, float _BottomSlope,
float _Near, float _Far)
: Origin(_Origin), Orientation(_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 void XM_CALLCONV CreateFromMatrix(BoundingFrustum& Out, FXMMATRIX Projection);

}


# 包围盒的相交、包含、碰撞检测及变换

## 包围盒与*面的相交检测

enum PlaneIntersectionType
{
FRONT = 0,              // 包围盒在*面的正面区域
INTERSECTING = 1,       // 包围盒与*面有相交
BACK = 2,               // 包围盒在*面的背面区域
};


PlaneIntersectionType XM_CALLCONV Intersects(FXMVECTOR Plane) const;


## 包围盒与包围盒的包含检测

enum ContainmentType
{
DISJOINT = 0,       // 两个包围盒相互分离
INTERSECTS = 1,     // 两个包围盒有相交
CONTAINS = 2,       // 两个包围盒存在包含关系
};


ContainmentType Contains(const BoundingSphere& sp) const;
ContainmentType Contains(const BoundingBox& box) const;
ContainmentType Contains(const BoundingOrientedBox& box) const;
ContainmentType Contains(const BoundingFrustum& fr) const;


## 包围盒与包围盒的碰撞检测

bool Intersects(const BoundingSphere& sh) const;
bool Intersects(const BoundingBox& box) const;
bool Intersects(const BoundingOrientedBox& box) const;
bool Intersects(const BoundingFrustum& fr) const;


## 包围盒的变换

void XM_CALLCONV Transform(BoundingVolume& Out, FXMMATRIX M ) const;
void XM_CALLCONV Transform(BoundingVolume& Out, float Scale, FXMVECTOR Rotation, FXMVECTOR Translation) const;


## 包围盒的其它方法

### 获取包围盒的八个顶点

void GetCorners(XMFLOAT3* Corners) const;


### 获取包围视锥体的六个*面

BoundingFrustum::GetPlanes方法可以获取视锥体六个*面的*面向量：

void GetPlanes(XMVECTOR* NearPlane, XMVECTOR* FarPlane, XMVECTOR* RightPlane,
XMVECTOR* LeftPlane, XMVECTOR* TopPlane, XMVECTOR* BottomPlane) const;


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)


# 三角形、射线

## 射线(三角形)与非包围盒的相交检测

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 );
// *面与三角形的相交检测

// 忽略...
};


## 射线(三角形)与包围盒的相交检测

bool XM_CALLCONV Intersects(FXMVECTOR Origin, FXMVECTOR Direction, float& Dist) const;
// 射线与包围盒的相交检测
bool XM_CALLCONV Intersects(FXMVECTOR V0, FXMVECTOR V1, FXMVECTOR V2) const;
// 三角形与包围盒的相交检测


# 演示程序

DirectX SDK Samples

DirectX11 With Windows SDK完整目录

Github项目源码

posted @ 2018-08-29 20:30  X_Jun  阅读(3350)  评论(2编辑  收藏  举报
levels of contents