OBB OBB test
This commit is contained in:
parent
00acab154b
commit
55a319a6ac
4 changed files with 137 additions and 35 deletions
|
|
@ -19,6 +19,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
export module Crafter.Math:Intersection;
|
||||
import :Vector;
|
||||
import :MatrixRowMajor;
|
||||
import std;
|
||||
|
||||
namespace Crafter {
|
||||
|
|
@ -67,7 +68,7 @@ namespace Crafter {
|
|||
|
||||
d = std::sqrt(d);
|
||||
|
||||
float t = (T(-0.5)) * (b + d) / a;
|
||||
T t = (T(-0.5)) * (b + d) / a;
|
||||
if (t > T(0)) {
|
||||
return t;
|
||||
} else {
|
||||
|
|
@ -121,4 +122,74 @@ namespace Crafter {
|
|||
|
||||
return (tMin >= T(0)) ? tMin : tMax;
|
||||
}
|
||||
|
||||
|
||||
export template<typename T>
|
||||
std::vector<Vector<T, 3, 0>> getOBBCorners(Vector<T, 3, 0> size, MatrixRowMajor<T, 4, 3, 1> matrix) {
|
||||
std::vector<Vector<T, 3, 0>> localCorners = {
|
||||
Vector<T, 3, 0>(-size.x, -size.y, -size.z),
|
||||
Vector<T, 3, 0>( size.x, -size.y, -size.z),
|
||||
Vector<T, 3, 0>(-size.x, size.y, -size.z),
|
||||
Vector<T, 3, 0>( size.x, size.y, -size.z),
|
||||
Vector<T, 3, 0>(-size.x, -size.y, size.z),
|
||||
Vector<T, 3, 0>( size.x, -size.y, size.z),
|
||||
Vector<T, 3, 0>(-size.x, size.y, size.z),
|
||||
Vector<T, 3, 0>( size.x, size.y, size.z)
|
||||
};
|
||||
|
||||
std::vector<Vector<T, 3, 0>> worldCorners;
|
||||
|
||||
for (Vector<T, 3, 0> localCorner : localCorners) {
|
||||
Vector<T, 3, 0> rotatedCorner = matrix * localCorner;
|
||||
worldCorners.push_back(rotatedCorner);
|
||||
}
|
||||
|
||||
return worldCorners;
|
||||
}
|
||||
|
||||
export template<typename T>
|
||||
constexpr T IntersectionTestOrientedBoxOrientedBox(Vector<T, 3, 0> sizeA, MatrixRowMajor<T, 4, 3, 1> boxA, Vector<T, 3, 0> sizeB, MatrixRowMajor<T, 4, 3, 1> boxB) {
|
||||
std::vector<Vector<T, 3, 0>> axes;
|
||||
|
||||
std::vector<Vector<T, 3, 0>> box1Corners = getOBBCorners(sizeA, boxA);
|
||||
std::vector<Vector<T, 3, 0>> box2Corners = getOBBCorners(sizeB, boxB);
|
||||
|
||||
axes.push_back(Vector<T, 3, 0>(boxA.m[0][0], boxA.m[0][1], boxA.m[0][2]));
|
||||
axes.push_back(Vector<T, 3, 0>(boxA.m[1][0], boxA.m[1][1], boxA.m[1][2]));
|
||||
axes.push_back(Vector<T, 3, 0>(boxA.m[2][0], boxA.m[2][1], boxA.m[2][2]));
|
||||
|
||||
axes.push_back(Vector<T, 3, 0>(boxB.m[0][0], boxB.m[0][1], boxB.m[0][2]));
|
||||
axes.push_back(Vector<T, 3, 0>(boxB.m[1][0], boxB.m[1][1], boxB.m[1][2]));
|
||||
axes.push_back(Vector<T, 3, 0>(boxB.m[2][0], boxB.m[2][1], boxB.m[2][2]));
|
||||
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
for (int j = 0; j < 3; ++j) {
|
||||
axes.push_back(Vector<T, 3, 0>::Cross(Vector<T, 3, 0>(boxA.m[i][0], boxA.m[i][1], boxA.m[i][2]), Vector<T, 3, 0>(boxB.m[j][0], boxB.m[j][1], boxB.m[j][2])));
|
||||
}
|
||||
}
|
||||
|
||||
for (Vector<T, 3, 0> axis : axes) {
|
||||
T min1 = Vector<T, 3, 0>::Dot(box1Corners[0], axis);
|
||||
T max1 = min1;
|
||||
for (Vector<T, 3, 0> corner : box1Corners) {
|
||||
T projection = Vector<T, 3, 0>::Dot(corner, axis);
|
||||
min1 = std::min(min1, projection);
|
||||
max1 = std::max(max1, projection);
|
||||
}
|
||||
|
||||
T min2 = Vector<T, 3, 0>::Dot(box2Corners[0], axis);
|
||||
T max2 = min2;
|
||||
for (Vector<T, 3, 0> corner : box2Corners) {
|
||||
T projection = Vector<T, 3, 0>::Dot(corner, axis);
|
||||
min2 = std::min(min2, projection);
|
||||
max2 = std::max(max2, projection);
|
||||
}
|
||||
|
||||
if (max1 < min2 || max2 < min1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue