forked from microsoft/DirectXMath
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDirectXCollision.h
341 lines (264 loc) · 16.5 KB
/
DirectXCollision.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
//-------------------------------------------------------------------------------------
// DirectXCollision.h -- C++ Collision Math library
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// http://go.microsoft.com/fwlink/?LinkID=615560
//-------------------------------------------------------------------------------------
#pragma once
#include "DirectXMath.h"
namespace DirectX
{
enum ContainmentType
{
DISJOINT = 0,
INTERSECTS = 1,
CONTAINS = 2,
};
enum PlaneIntersectionType
{
FRONT = 0,
INTERSECTING = 1,
BACK = 2,
};
struct BoundingBox;
struct BoundingOrientedBox;
struct BoundingFrustum;
#pragma warning(push)
#pragma warning(disable:4324 4820)
// C4324: alignment padding warnings
// C4820: Off by default noise
//-------------------------------------------------------------------------------------
// Bounding sphere
//-------------------------------------------------------------------------------------
struct BoundingSphere
{
XMFLOAT3 Center; // Center of the sphere.
float Radius; // Radius of the sphere.
// Creators
BoundingSphere() : Center(0,0,0), Radius( 1.f ) {}
XM_CONSTEXPR BoundingSphere( _In_ const XMFLOAT3& center, _In_ float radius )
: Center(center), Radius(radius) {}
BoundingSphere( _In_ const BoundingSphere& sp )
: Center(sp.Center), Radius(sp.Radius) {}
// Methods
BoundingSphere& operator=( _In_ const BoundingSphere& sp ) { Center = sp.Center; Radius = sp.Radius; return *this; }
void XM_CALLCONV Transform( _Out_ BoundingSphere& Out, _In_ FXMMATRIX M ) const;
void XM_CALLCONV Transform( _Out_ BoundingSphere& Out, _In_ float Scale, _In_ FXMVECTOR Rotation, _In_ FXMVECTOR Translation ) const;
// Transform the sphere
ContainmentType XM_CALLCONV Contains( _In_ FXMVECTOR Point ) const;
ContainmentType XM_CALLCONV Contains( _In_ FXMVECTOR V0, _In_ FXMVECTOR V1, _In_ FXMVECTOR V2 ) const;
ContainmentType Contains( _In_ const BoundingSphere& sh ) const;
ContainmentType Contains( _In_ const BoundingBox& box ) const;
ContainmentType Contains( _In_ const BoundingOrientedBox& box ) const;
ContainmentType Contains( _In_ const BoundingFrustum& fr ) const;
bool Intersects( _In_ const BoundingSphere& sh ) const;
bool Intersects( _In_ const BoundingBox& box ) const;
bool Intersects( _In_ const BoundingOrientedBox& box ) const;
bool Intersects( _In_ const BoundingFrustum& fr ) const;
bool XM_CALLCONV Intersects( _In_ FXMVECTOR V0, _In_ FXMVECTOR V1, _In_ FXMVECTOR V2 ) const;
// Triangle-sphere test
PlaneIntersectionType XM_CALLCONV Intersects( _In_ FXMVECTOR Plane ) const;
// Plane-sphere test
bool XM_CALLCONV Intersects( _In_ FXMVECTOR Origin, _In_ FXMVECTOR Direction, _Out_ float& Dist ) const;
// Ray-sphere test
ContainmentType XM_CALLCONV ContainedBy( _In_ FXMVECTOR Plane0, _In_ FXMVECTOR Plane1, _In_ FXMVECTOR Plane2,
_In_ GXMVECTOR Plane3, _In_ HXMVECTOR Plane4, _In_ HXMVECTOR Plane5 ) const;
// Test sphere against six planes (see BoundingFrustum::GetPlanes)
// Static methods
static void CreateMerged( _Out_ BoundingSphere& Out, _In_ const BoundingSphere& S1, _In_ const BoundingSphere& S2 );
static void CreateFromBoundingBox( _Out_ BoundingSphere& Out, _In_ const BoundingBox& box );
static void CreateFromBoundingBox( _Out_ BoundingSphere& Out, _In_ const BoundingOrientedBox& box );
static void CreateFromPoints( _Out_ BoundingSphere& Out, _In_ size_t Count,
_In_reads_bytes_(sizeof(XMFLOAT3)+Stride*(Count-1)) const XMFLOAT3* pPoints, _In_ size_t Stride );
static void CreateFromFrustum( _Out_ BoundingSphere& Out, _In_ const BoundingFrustum& fr );
};
//-------------------------------------------------------------------------------------
// Axis-aligned bounding box
//-------------------------------------------------------------------------------------
struct BoundingBox
{
static const size_t CORNER_COUNT = 8;
XMFLOAT3 Center; // Center of the box.
XMFLOAT3 Extents; // Distance from the center to each side.
// Creators
BoundingBox() : Center(0,0,0), Extents( 1.f, 1.f, 1.f ) {}
XM_CONSTEXPR BoundingBox( _In_ const XMFLOAT3& center, _In_ const XMFLOAT3& extents )
: Center(center), Extents(extents) {}
BoundingBox( _In_ const BoundingBox& box ) : Center(box.Center), Extents(box.Extents) {}
// Methods
BoundingBox& operator=( _In_ const BoundingBox& box) { Center = box.Center; Extents = box.Extents; return *this; }
void XM_CALLCONV Transform( _Out_ BoundingBox& Out, _In_ FXMMATRIX M ) const;
void XM_CALLCONV Transform( _Out_ BoundingBox& Out, _In_ float Scale, _In_ FXMVECTOR Rotation, _In_ FXMVECTOR Translation ) const;
void GetCorners( _Out_writes_(8) XMFLOAT3* Corners ) const;
// Gets the 8 corners of the box
ContainmentType XM_CALLCONV Contains( _In_ FXMVECTOR Point ) const;
ContainmentType XM_CALLCONV Contains( _In_ FXMVECTOR V0, _In_ FXMVECTOR V1, _In_ FXMVECTOR V2 ) const;
ContainmentType Contains( _In_ const BoundingSphere& sh ) const;
ContainmentType Contains( _In_ const BoundingBox& box ) const;
ContainmentType Contains( _In_ const BoundingOrientedBox& box ) const;
ContainmentType Contains( _In_ const BoundingFrustum& fr ) const;
bool Intersects( _In_ const BoundingSphere& sh ) const;
bool Intersects( _In_ const BoundingBox& box ) const;
bool Intersects( _In_ const BoundingOrientedBox& box ) const;
bool Intersects( _In_ const BoundingFrustum& fr ) const;
bool XM_CALLCONV Intersects( _In_ FXMVECTOR V0, _In_ FXMVECTOR V1, _In_ FXMVECTOR V2 ) const;
// Triangle-Box test
PlaneIntersectionType XM_CALLCONV Intersects( _In_ FXMVECTOR Plane ) const;
// Plane-box test
bool XM_CALLCONV Intersects( _In_ FXMVECTOR Origin, _In_ FXMVECTOR Direction, _Out_ float& Dist ) const;
// Ray-Box test
ContainmentType XM_CALLCONV ContainedBy( _In_ FXMVECTOR Plane0, _In_ FXMVECTOR Plane1, _In_ FXMVECTOR Plane2,
_In_ GXMVECTOR Plane3, _In_ HXMVECTOR Plane4, _In_ HXMVECTOR Plane5 ) const;
// Test box against six planes (see BoundingFrustum::GetPlanes)
// Static methods
static void CreateMerged( _Out_ BoundingBox& Out, _In_ const BoundingBox& b1, _In_ const BoundingBox& b2 );
static void CreateFromSphere( _Out_ BoundingBox& Out, _In_ const BoundingSphere& sh );
static void XM_CALLCONV CreateFromPoints( _Out_ BoundingBox& Out, _In_ FXMVECTOR pt1, _In_ FXMVECTOR pt2 );
static void CreateFromPoints( _Out_ BoundingBox& Out, _In_ size_t Count,
_In_reads_bytes_(sizeof(XMFLOAT3)+Stride*(Count-1)) const XMFLOAT3* pPoints, _In_ size_t Stride );
};
//-------------------------------------------------------------------------------------
// Oriented bounding box
//-------------------------------------------------------------------------------------
struct BoundingOrientedBox
{
static const size_t CORNER_COUNT = 8;
XMFLOAT3 Center; // Center of the box.
XMFLOAT3 Extents; // Distance from the center to each side.
XMFLOAT4 Orientation; // Unit quaternion representing rotation (box -> world).
// Creators
BoundingOrientedBox() : Center(0,0,0), Extents( 1.f, 1.f, 1.f ), Orientation(0,0,0, 1.f ) {}
XM_CONSTEXPR BoundingOrientedBox( _In_ const XMFLOAT3& _Center, _In_ const XMFLOAT3& _Extents, _In_ const XMFLOAT4& _Orientation )
: Center(_Center), Extents(_Extents), Orientation(_Orientation) {}
BoundingOrientedBox( _In_ const BoundingOrientedBox& box )
: Center(box.Center), Extents(box.Extents), Orientation(box.Orientation) {}
// Methods
BoundingOrientedBox& operator=( _In_ const BoundingOrientedBox& box ) { Center = box.Center; Extents = box.Extents; Orientation = box.Orientation; return *this; }
void XM_CALLCONV Transform( _Out_ BoundingOrientedBox& Out, _In_ FXMMATRIX M ) const;
void XM_CALLCONV Transform( _Out_ BoundingOrientedBox& Out, _In_ float Scale, _In_ FXMVECTOR Rotation, _In_ FXMVECTOR Translation ) const;
void GetCorners( _Out_writes_(8) XMFLOAT3* Corners ) const;
// Gets the 8 corners of the box
ContainmentType XM_CALLCONV Contains( _In_ FXMVECTOR Point ) const;
ContainmentType XM_CALLCONV Contains( _In_ FXMVECTOR V0, _In_ FXMVECTOR V1, _In_ FXMVECTOR V2 ) const;
ContainmentType Contains( _In_ const BoundingSphere& sh ) const;
ContainmentType Contains( _In_ const BoundingBox& box ) const;
ContainmentType Contains( _In_ const BoundingOrientedBox& box ) const;
ContainmentType Contains( _In_ const BoundingFrustum& fr ) const;
bool Intersects( _In_ const BoundingSphere& sh ) const;
bool Intersects( _In_ const BoundingBox& box ) const;
bool Intersects( _In_ const BoundingOrientedBox& box ) const;
bool Intersects( _In_ const BoundingFrustum& fr ) const;
bool XM_CALLCONV Intersects( _In_ FXMVECTOR V0, _In_ FXMVECTOR V1, _In_ FXMVECTOR V2 ) const;
// Triangle-OrientedBox test
PlaneIntersectionType XM_CALLCONV Intersects( _In_ FXMVECTOR Plane ) const;
// Plane-OrientedBox test
bool XM_CALLCONV Intersects( _In_ FXMVECTOR Origin, _In_ FXMVECTOR Direction, _Out_ float& Dist ) const;
// Ray-OrientedBox test
ContainmentType XM_CALLCONV ContainedBy( _In_ FXMVECTOR Plane0, _In_ FXMVECTOR Plane1, _In_ FXMVECTOR Plane2,
_In_ GXMVECTOR Plane3, _In_ HXMVECTOR Plane4, _In_ HXMVECTOR Plane5 ) const;
// Test OrientedBox against six planes (see BoundingFrustum::GetPlanes)
// Static methods
static void CreateFromBoundingBox( _Out_ BoundingOrientedBox& Out, _In_ const BoundingBox& box );
static void CreateFromPoints( _Out_ BoundingOrientedBox& Out, _In_ size_t Count,
_In_reads_bytes_(sizeof(XMFLOAT3)+Stride*(Count-1)) const XMFLOAT3* pPoints, _In_ size_t Stride );
};
//-------------------------------------------------------------------------------------
// Bounding frustum
//-------------------------------------------------------------------------------------
struct BoundingFrustum
{
static const size_t CORNER_COUNT = 8;
XMFLOAT3 Origin; // Origin of the frustum (and projection).
XMFLOAT4 Orientation; // Quaternion representing rotation.
float RightSlope; // Positive X slope (X/Z).
float LeftSlope; // Negative X slope.
float TopSlope; // Positive Y slope (Y/Z).
float BottomSlope; // Negative Y slope.
float Near, Far; // Z of the near plane and far plane.
// Creators
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( _In_ const XMFLOAT3& _Origin, _In_ const XMFLOAT4& _Orientation,
_In_ float _RightSlope, _In_ float _LeftSlope, _In_ float _TopSlope, _In_ float _BottomSlope,
_In_ float _Near, _In_ float _Far )
: Origin(_Origin), Orientation(_Orientation),
RightSlope(_RightSlope), LeftSlope(_LeftSlope), TopSlope(_TopSlope), BottomSlope(_BottomSlope),
Near(_Near), Far(_Far) {}
BoundingFrustum( _In_ 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( _In_ CXMMATRIX Projection ) { CreateFromMatrix( *this, Projection ); }
// Methods
BoundingFrustum& operator=( _In_ 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; return *this; }
void XM_CALLCONV Transform( _Out_ BoundingFrustum& Out, _In_ FXMMATRIX M ) const;
void XM_CALLCONV Transform( _Out_ BoundingFrustum& Out, _In_ float Scale, _In_ FXMVECTOR Rotation, _In_ FXMVECTOR Translation ) const;
void GetCorners( _Out_writes_(8) XMFLOAT3* Corners ) const;
// Gets the 8 corners of the frustum
ContainmentType XM_CALLCONV Contains( _In_ FXMVECTOR Point ) const;
ContainmentType XM_CALLCONV Contains( _In_ FXMVECTOR V0, _In_ FXMVECTOR V1, _In_ FXMVECTOR V2 ) const;
ContainmentType Contains( _In_ const BoundingSphere& sp ) const;
ContainmentType Contains( _In_ const BoundingBox& box ) const;
ContainmentType Contains( _In_ const BoundingOrientedBox& box ) const;
ContainmentType Contains( _In_ const BoundingFrustum& fr ) const;
// Frustum-Frustum test
bool Intersects( _In_ const BoundingSphere& sh ) const;
bool Intersects( _In_ const BoundingBox& box ) const;
bool Intersects( _In_ const BoundingOrientedBox& box ) const;
bool Intersects( _In_ const BoundingFrustum& fr ) const;
bool XM_CALLCONV Intersects( _In_ FXMVECTOR V0, _In_ FXMVECTOR V1, _In_ FXMVECTOR V2 ) const;
// Triangle-Frustum test
PlaneIntersectionType XM_CALLCONV Intersects( _In_ FXMVECTOR Plane ) const;
// Plane-Frustum test
bool XM_CALLCONV Intersects( _In_ FXMVECTOR rayOrigin, _In_ FXMVECTOR Direction, _Out_ float& Dist ) const;
// Ray-Frustum test
ContainmentType XM_CALLCONV ContainedBy( _In_ FXMVECTOR Plane0, _In_ FXMVECTOR Plane1, _In_ FXMVECTOR Plane2,
_In_ GXMVECTOR Plane3, _In_ HXMVECTOR Plane4, _In_ HXMVECTOR Plane5 ) const;
// Test frustum against six planes (see BoundingFrustum::GetPlanes)
void GetPlanes( _Out_opt_ XMVECTOR* NearPlane, _Out_opt_ XMVECTOR* FarPlane, _Out_opt_ XMVECTOR* RightPlane,
_Out_opt_ XMVECTOR* LeftPlane, _Out_opt_ XMVECTOR* TopPlane, _Out_opt_ XMVECTOR* BottomPlane ) const;
// Create 6 Planes representation of Frustum
// Static methods
static void XM_CALLCONV CreateFromMatrix( _Out_ BoundingFrustum& Out, _In_ FXMMATRIX Projection );
};
//-----------------------------------------------------------------------------
// Triangle intersection testing routines.
//-----------------------------------------------------------------------------
namespace TriangleTests
{
bool XM_CALLCONV Intersects( _In_ FXMVECTOR Origin, _In_ FXMVECTOR Direction, _In_ FXMVECTOR V0, _In_ GXMVECTOR V1, _In_ HXMVECTOR V2, _Out_ float& Dist );
// Ray-Triangle
bool XM_CALLCONV Intersects( _In_ FXMVECTOR A0, _In_ FXMVECTOR A1, _In_ FXMVECTOR A2, _In_ GXMVECTOR B0, _In_ HXMVECTOR B1, _In_ HXMVECTOR B2 );
// Triangle-Triangle
PlaneIntersectionType XM_CALLCONV Intersects( _In_ FXMVECTOR V0, _In_ FXMVECTOR V1, _In_ FXMVECTOR V2, _In_ GXMVECTOR Plane );
// Plane-Triangle
ContainmentType XM_CALLCONV ContainedBy( _In_ FXMVECTOR V0, _In_ FXMVECTOR V1, _In_ FXMVECTOR V2,
_In_ GXMVECTOR Plane0, _In_ HXMVECTOR Plane1, _In_ HXMVECTOR Plane2,
_In_ CXMVECTOR Plane3, _In_ CXMVECTOR Plane4, _In_ CXMVECTOR Plane5 );
// Test a triangle against six planes at once (see BoundingFrustum::GetPlanes)
};
#pragma warning(pop)
/****************************************************************************
*
* Implementation
*
****************************************************************************/
#pragma warning(push)
#pragma warning(disable : 4068 4365 4616 6001)
// C4068/4616: ignore unknown pragmas
// C4365: Off by default noise
// C6001: False positives
#pragma prefast(push)
#pragma prefast(disable : 25000, "FXMVECTOR is 16 bytes")
#include "DirectXCollision.inl"
#pragma prefast(pop)
#pragma warning(pop)
}; // namespace DirectX