Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/jolt_physics/Jolt/Geometry/OrientedBox.cpp
9913 views
1
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
2
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
3
// SPDX-License-Identifier: MIT
4
5
#include <Jolt/Jolt.h>
6
7
#include <Jolt/Geometry/OrientedBox.h>
8
#include <Jolt/Geometry/AABox.h>
9
10
JPH_NAMESPACE_BEGIN
11
12
bool OrientedBox::Overlaps(const AABox &inBox, float inEpsilon) const
13
{
14
// Taken from: Real Time Collision Detection - Christer Ericson
15
// Chapter 4.4.1, page 103-105.
16
// Note that the code is swapped around: A is the aabox and B is the oriented box (this saves us from having to invert the orientation of the oriented box)
17
18
// Convert AABox to center / extent representation
19
Vec3 a_center = inBox.GetCenter();
20
Vec3 a_half_extents = inBox.GetExtent();
21
22
// Compute rotation matrix expressing b in a's coordinate frame
23
Mat44 rot(mOrientation.GetColumn4(0), mOrientation.GetColumn4(1), mOrientation.GetColumn4(2), mOrientation.GetColumn4(3) - Vec4(a_center, 0));
24
25
// Compute common subexpressions. Add in an epsilon term to
26
// counteract arithmetic errors when two edges are parallel and
27
// their cross product is (near) null (see text for details)
28
Vec3 epsilon = Vec3::sReplicate(inEpsilon);
29
Vec3 abs_r[3] { rot.GetAxisX().Abs() + epsilon, rot.GetAxisY().Abs() + epsilon, rot.GetAxisZ().Abs() + epsilon };
30
31
// Test axes L = A0, L = A1, L = A2
32
float ra, rb;
33
for (int i = 0; i < 3; i++)
34
{
35
ra = a_half_extents[i];
36
rb = mHalfExtents[0] * abs_r[0][i] + mHalfExtents[1] * abs_r[1][i] + mHalfExtents[2] * abs_r[2][i];
37
if (abs(rot(i, 3)) > ra + rb) return false;
38
}
39
40
// Test axes L = B0, L = B1, L = B2
41
for (int i = 0; i < 3; i++)
42
{
43
ra = a_half_extents.Dot(abs_r[i]);
44
rb = mHalfExtents[i];
45
if (abs(rot.GetTranslation().Dot(rot.GetColumn3(i))) > ra + rb) return false;
46
}
47
48
// Test axis L = A0 x B0
49
ra = a_half_extents[1] * abs_r[0][2] + a_half_extents[2] * abs_r[0][1];
50
rb = mHalfExtents[1] * abs_r[2][0] + mHalfExtents[2] * abs_r[1][0];
51
if (abs(rot(2, 3) * rot(1, 0) - rot(1, 3) * rot(2, 0)) > ra + rb) return false;
52
53
// Test axis L = A0 x B1
54
ra = a_half_extents[1] * abs_r[1][2] + a_half_extents[2] * abs_r[1][1];
55
rb = mHalfExtents[0] * abs_r[2][0] + mHalfExtents[2] * abs_r[0][0];
56
if (abs(rot(2, 3) * rot(1, 1) - rot(1, 3) * rot(2, 1)) > ra + rb) return false;
57
58
// Test axis L = A0 x B2
59
ra = a_half_extents[1] * abs_r[2][2] + a_half_extents[2] * abs_r[2][1];
60
rb = mHalfExtents[0] * abs_r[1][0] + mHalfExtents[1] * abs_r[0][0];
61
if (abs(rot(2, 3) * rot(1, 2) - rot(1, 3) * rot(2, 2)) > ra + rb) return false;
62
63
// Test axis L = A1 x B0
64
ra = a_half_extents[0] * abs_r[0][2] + a_half_extents[2] * abs_r[0][0];
65
rb = mHalfExtents[1] * abs_r[2][1] + mHalfExtents[2] * abs_r[1][1];
66
if (abs(rot(0, 3) * rot(2, 0) - rot(2, 3) * rot(0, 0)) > ra + rb) return false;
67
68
// Test axis L = A1 x B1
69
ra = a_half_extents[0] * abs_r[1][2] + a_half_extents[2] * abs_r[1][0];
70
rb = mHalfExtents[0] * abs_r[2][1] + mHalfExtents[2] * abs_r[0][1];
71
if (abs(rot(0, 3) * rot(2, 1) - rot(2, 3) * rot(0, 1)) > ra + rb) return false;
72
73
// Test axis L = A1 x B2
74
ra = a_half_extents[0] * abs_r[2][2] + a_half_extents[2] * abs_r[2][0];
75
rb = mHalfExtents[0] * abs_r[1][1] + mHalfExtents[1] * abs_r[0][1];
76
if (abs(rot(0, 3) * rot(2, 2) - rot(2, 3) * rot(0, 2)) > ra + rb) return false;
77
78
// Test axis L = A2 x B0
79
ra = a_half_extents[0] * abs_r[0][1] + a_half_extents[1] * abs_r[0][0];
80
rb = mHalfExtents[1] * abs_r[2][2] + mHalfExtents[2] * abs_r[1][2];
81
if (abs(rot(1, 3) * rot(0, 0) - rot(0, 3) * rot(1, 0)) > ra + rb) return false;
82
83
// Test axis L = A2 x B1
84
ra = a_half_extents[0] * abs_r[1][1] + a_half_extents[1] * abs_r[1][0];
85
rb = mHalfExtents[0] * abs_r[2][2] + mHalfExtents[2] * abs_r[0][2];
86
if (abs(rot(1, 3) * rot(0, 1) - rot(0, 3) * rot(1, 1)) > ra + rb) return false;
87
88
// Test axis L = A2 x B2
89
ra = a_half_extents[0] * abs_r[2][1] + a_half_extents[1] * abs_r[2][0];
90
rb = mHalfExtents[0] * abs_r[1][2] + mHalfExtents[1] * abs_r[0][2];
91
if (abs(rot(1, 3) * rot(0, 2) - rot(0, 3) * rot(1, 2)) > ra + rb) return false;
92
93
// Since no separating axis is found, the OBB and AAB must be intersecting
94
return true;
95
}
96
97
bool OrientedBox::Overlaps(const OrientedBox &inBox, float inEpsilon) const
98
{
99
// Taken from: Real Time Collision Detection - Christer Ericson
100
// Chapter 4.4.1, page 103-105.
101
// Note that A is this, B is inBox
102
103
// Compute rotation matrix expressing b in a's coordinate frame
104
Mat44 rot = mOrientation.InversedRotationTranslation() * inBox.mOrientation;
105
106
// Compute common subexpressions. Add in an epsilon term to
107
// counteract arithmetic errors when two edges are parallel and
108
// their cross product is (near) null (see text for details)
109
Vec3 epsilon = Vec3::sReplicate(inEpsilon);
110
Vec3 abs_r[3] { rot.GetAxisX().Abs() + epsilon, rot.GetAxisY().Abs() + epsilon, rot.GetAxisZ().Abs() + epsilon };
111
112
// Test axes L = A0, L = A1, L = A2
113
float ra, rb;
114
for (int i = 0; i < 3; i++)
115
{
116
ra = mHalfExtents[i];
117
rb = inBox.mHalfExtents[0] * abs_r[0][i] + inBox.mHalfExtents[1] * abs_r[1][i] + inBox.mHalfExtents[2] * abs_r[2][i];
118
if (abs(rot(i, 3)) > ra + rb) return false;
119
}
120
121
// Test axes L = B0, L = B1, L = B2
122
for (int i = 0; i < 3; i++)
123
{
124
ra = mHalfExtents.Dot(abs_r[i]);
125
rb = inBox.mHalfExtents[i];
126
if (abs(rot.GetTranslation().Dot(rot.GetColumn3(i))) > ra + rb) return false;
127
}
128
129
// Test axis L = A0 x B0
130
ra = mHalfExtents[1] * abs_r[0][2] + mHalfExtents[2] * abs_r[0][1];
131
rb = inBox.mHalfExtents[1] * abs_r[2][0] + inBox.mHalfExtents[2] * abs_r[1][0];
132
if (abs(rot(2, 3) * rot(1, 0) - rot(1, 3) * rot(2, 0)) > ra + rb) return false;
133
134
// Test axis L = A0 x B1
135
ra = mHalfExtents[1] * abs_r[1][2] + mHalfExtents[2] * abs_r[1][1];
136
rb = inBox.mHalfExtents[0] * abs_r[2][0] + inBox.mHalfExtents[2] * abs_r[0][0];
137
if (abs(rot(2, 3) * rot(1, 1) - rot(1, 3) * rot(2, 1)) > ra + rb) return false;
138
139
// Test axis L = A0 x B2
140
ra = mHalfExtents[1] * abs_r[2][2] + mHalfExtents[2] * abs_r[2][1];
141
rb = inBox.mHalfExtents[0] * abs_r[1][0] + inBox.mHalfExtents[1] * abs_r[0][0];
142
if (abs(rot(2, 3) * rot(1, 2) - rot(1, 3) * rot(2, 2)) > ra + rb) return false;
143
144
// Test axis L = A1 x B0
145
ra = mHalfExtents[0] * abs_r[0][2] + mHalfExtents[2] * abs_r[0][0];
146
rb = inBox.mHalfExtents[1] * abs_r[2][1] + inBox.mHalfExtents[2] * abs_r[1][1];
147
if (abs(rot(0, 3) * rot(2, 0) - rot(2, 3) * rot(0, 0)) > ra + rb) return false;
148
149
// Test axis L = A1 x B1
150
ra = mHalfExtents[0] * abs_r[1][2] + mHalfExtents[2] * abs_r[1][0];
151
rb = inBox.mHalfExtents[0] * abs_r[2][1] + inBox.mHalfExtents[2] * abs_r[0][1];
152
if (abs(rot(0, 3) * rot(2, 1) - rot(2, 3) * rot(0, 1)) > ra + rb) return false;
153
154
// Test axis L = A1 x B2
155
ra = mHalfExtents[0] * abs_r[2][2] + mHalfExtents[2] * abs_r[2][0];
156
rb = inBox.mHalfExtents[0] * abs_r[1][1] + inBox.mHalfExtents[1] * abs_r[0][1];
157
if (abs(rot(0, 3) * rot(2, 2) - rot(2, 3) * rot(0, 2)) > ra + rb) return false;
158
159
// Test axis L = A2 x B0
160
ra = mHalfExtents[0] * abs_r[0][1] + mHalfExtents[1] * abs_r[0][0];
161
rb = inBox.mHalfExtents[1] * abs_r[2][2] + inBox.mHalfExtents[2] * abs_r[1][2];
162
if (abs(rot(1, 3) * rot(0, 0) - rot(0, 3) * rot(1, 0)) > ra + rb) return false;
163
164
// Test axis L = A2 x B1
165
ra = mHalfExtents[0] * abs_r[1][1] + mHalfExtents[1] * abs_r[1][0];
166
rb = inBox.mHalfExtents[0] * abs_r[2][2] + inBox.mHalfExtents[2] * abs_r[0][2];
167
if (abs(rot(1, 3) * rot(0, 1) - rot(0, 3) * rot(1, 1)) > ra + rb) return false;
168
169
// Test axis L = A2 x B2
170
ra = mHalfExtents[0] * abs_r[2][1] + mHalfExtents[1] * abs_r[2][0];
171
rb = inBox.mHalfExtents[0] * abs_r[1][2] + inBox.mHalfExtents[1] * abs_r[0][2];
172
if (abs(rot(1, 3) * rot(0, 2) - rot(0, 3) * rot(1, 2)) > ra + rb) return false;
173
174
// Since no separating axis is found, the OBBs must be intersecting
175
return true;
176
}
177
178
JPH_NAMESPACE_END
179
180