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;
|
||||
}
|
||||
}
|
||||
|
|
@ -80,11 +80,11 @@ namespace Crafter {
|
|||
}
|
||||
|
||||
template <std::uint32_t VAligment>
|
||||
Vector<T, 3, VAligment> operator*(Vector<T, 3, VAligment> b) const requires(CollumSize == 4 && RowSize == 4 && Repeats == 1 && std::same_as<T, float>) {
|
||||
Vector<T, 3, VAligment> operator*(Vector<T, 3, VAligment> b) const requires(CollumSize == 4 && RowSize == 3 && Repeats == 1 && std::same_as<T, float>) {
|
||||
return Vector<T, 3, VAligment>(
|
||||
b.x * m[0][0] + b.y * m[1][0] + b.z * m[2][0] + m[3][0],
|
||||
b.x * m[0][1] + b.y * m[1][1] + b.z * m[2][1] + m[3][1],
|
||||
b.x * m[0][2] + b.y * m[1][2] + b.z * m[2][2] + m[3][2]
|
||||
b.x * m[0][0] + b.y * m[0][1] + b.z * m[0][2] + m[0][3],
|
||||
b.x * m[1][0] + b.y * m[1][1] + b.z * m[1][2] + m[1][3],
|
||||
b.x * m[2][0] + b.y * m[2][1] + b.z * m[2][2] + m[2][3]
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -238,7 +238,7 @@ namespace Crafter {
|
|||
}
|
||||
|
||||
template <typename BT>
|
||||
constexpr Vector<T, Len, Aligment> operator+(BT b) const {
|
||||
constexpr Vector<T, Len, Aligment> operator+(BT b) const requires std::is_arithmetic_v<BT> {
|
||||
Vector<T, Len, Aligment> resultVector;
|
||||
for(std::uint32_t i = 0; i < Len; i++) {
|
||||
resultVector.v[i] = this->v[i] + b;
|
||||
|
|
@ -246,7 +246,7 @@ namespace Crafter {
|
|||
return resultVector;
|
||||
}
|
||||
template <typename BT>
|
||||
constexpr Vector<T, Len, Aligment> operator-(BT b) const {
|
||||
constexpr Vector<T, Len, Aligment> operator-(BT b) const requires std::is_arithmetic_v<BT> {
|
||||
Vector<T, Len, Aligment> resultVector;
|
||||
for(std::uint32_t i = 0; i < Len; i++) {
|
||||
resultVector.v[i] = this->v[i] - b;
|
||||
|
|
@ -254,7 +254,7 @@ namespace Crafter {
|
|||
return resultVector;
|
||||
}
|
||||
template <typename BT>
|
||||
constexpr Vector<T, Len, Aligment> operator*(BT b) const {
|
||||
constexpr Vector<T, Len, Aligment> operator*(BT b) const requires std::is_arithmetic_v<BT> {
|
||||
Vector<T, Len, Aligment> resultVector;
|
||||
for(std::uint32_t i = 0; i < Len; i++) {
|
||||
resultVector.v[i] = this->v[i] * b;
|
||||
|
|
@ -262,7 +262,7 @@ namespace Crafter {
|
|||
return resultVector;
|
||||
}
|
||||
template <typename BT>
|
||||
constexpr Vector<T, Len, Aligment> operator/(BT b) const {
|
||||
constexpr Vector<T, Len, Aligment> operator/(BT b) const requires std::is_arithmetic_v<BT> {
|
||||
Vector<T, Len, Aligment> resultVector;
|
||||
for(std::uint32_t i = 0; i < Len; i++) {
|
||||
resultVector.v[i] = this->v[i] / b;
|
||||
|
|
@ -270,25 +270,25 @@ namespace Crafter {
|
|||
return resultVector;
|
||||
}
|
||||
template <typename BT>
|
||||
constexpr void operator+=(BT b){
|
||||
constexpr void operator+=(BT b) requires std::is_arithmetic_v<BT>{
|
||||
for(std::uint32_t i = 0; i < Len; i++) {
|
||||
this->v[i] += b;
|
||||
}
|
||||
}
|
||||
template <typename BT>
|
||||
constexpr void operator-=(BT b){
|
||||
constexpr void operator-=(BT b) requires std::is_arithmetic_v<BT>{
|
||||
for(std::uint32_t i = 0; i < Len; i++) {
|
||||
this->v[i] -= b;
|
||||
}
|
||||
}
|
||||
template <typename BT>
|
||||
constexpr void operator*=(BT b){
|
||||
constexpr void operator*=(BT b) requires std::is_arithmetic_v<BT>{
|
||||
for(std::uint32_t i = 0; i < Len; i++) {
|
||||
this->v[i] *= b;
|
||||
}
|
||||
}
|
||||
template <typename BT>
|
||||
constexpr void operator/=(BT b){
|
||||
constexpr void operator/=(BT b) requires std::is_arithmetic_v<BT>{
|
||||
for(std::uint32_t i = 0; i < Len; i++) {
|
||||
this->v[i] /= b;
|
||||
}
|
||||
|
|
@ -489,6 +489,6 @@ struct std::formatter<Crafter::Vector<T, 4, Aligment>> : std::formatter<std::str
|
|||
|
||||
|
||||
template <typename T, std::uint32_t Len, std::uint32_t Aligment, typename BT>
|
||||
constexpr Crafter::Vector<T, Len, Aligment> operator*(BT b, const Crafter::Vector<T, Len, Aligment>& v) {
|
||||
constexpr Crafter::Vector<T, Len, Aligment> operator*(BT b, const Crafter::Vector<T, Len, Aligment>& v) requires std::is_arithmetic_v<BT> {
|
||||
return v * b;
|
||||
}
|
||||
|
|
@ -4,25 +4,56 @@ import std;
|
|||
using namespace Crafter;
|
||||
|
||||
int main() {
|
||||
// // Test Ray-OrientedBox intersection
|
||||
// Vector<float, 3, 0> boxPos(0.0f, 0.0f, 0.0f);
|
||||
// Vector<float, 3, 0> boxSize(2.0f, 2.0f, 2.0f);
|
||||
// Vector<float, 3, 0> boxRot(0.0f, 0.0f, 0.0f); // No rotation
|
||||
// Vector<float, 3, 0> rayOrigin(0.0f, 0.0f, -5.0f);
|
||||
// Vector<float, 3, 0> rayDir(0.0f, 0.0f, 1.0f);
|
||||
|
||||
// float hitDistance = IntersectionTestRayOrientedBox(boxPos, boxSize, boxRot, rayOrigin, rayDir);
|
||||
|
||||
// if (hitDistance < std::numeric_limits<float>::max()) {
|
||||
// // Hit occurred
|
||||
// std::cout << "Ray-OrientedBox intersection at distance: " << hitDistance << std::endl;
|
||||
// } else {
|
||||
// // No hit
|
||||
// std::cout << "No intersection with Ray-OrientedBox" << std::endl;
|
||||
// }
|
||||
|
||||
// return 0;
|
||||
// Intersection Test
|
||||
|
||||
// Define Box A (size and matrix for transformation)
|
||||
Vector<float, 3, 0> sizeA(1.0f, 1.0f, 1.0f); // Box A size
|
||||
MatrixRowMajor<float, 4, 3, 1> boxA;
|
||||
boxA.m[0][0] = 1.0f; boxA.m[1][0] = 0.0f; boxA.m[2][0] = 0.0f;
|
||||
boxA.m[1][0] = 0.0f; boxA.m[1][1] = 1.0f; boxA.m[2][1] = 0.0f;
|
||||
boxA.m[2][0] = 0.0f; boxA.m[1][2] = 0.0f; boxA.m[2][2] = 1.0f;
|
||||
|
||||
// Define Box B (size and matrix for transformation)
|
||||
Vector<float, 3, 0> sizeB(1.0f, 1.0f, 1.0f); // Box B size
|
||||
MatrixRowMajor<float, 4, 3, 1> boxB;
|
||||
boxB.m[0][0] = 1.0f; boxB.m[1][0] = 0.0f; boxB.m[2][0] = 0.0f;
|
||||
boxB.m[1][0] = 0.0f; boxB.m[1][1] = 1.0f; boxB.m[2][1] = 0.0f;
|
||||
boxB.m[2][0] = 0.0f; boxB.m[1][2] = 0.0f; boxB.m[2][2] = 1.0f;
|
||||
|
||||
// Apply a small translation to box B (so that they overlap)
|
||||
boxB.m[0][3] = 0.5f;
|
||||
boxB.m[1][3] = 0.5f;
|
||||
boxB.m[2][3] = 0.0f;
|
||||
|
||||
// Check if the boxes intersect (they should, as they're overlapping)
|
||||
bool result = IntersectionTestOrientedBoxOrientedBox(sizeA, boxA, sizeB, boxB);
|
||||
std::cout << result << std::endl;
|
||||
|
||||
|
||||
std::cout << (Vector<float, 3, 0>(5, 0, 0) == Vector<float, 3, 0>(5,0,1)) << std::endl;
|
||||
// Miss Test
|
||||
|
||||
// Define Box A (size and matrix for transformation)
|
||||
Vector<float, 3, 0> sizeC(1.0f, 1.0f, 1.0f); // Box C size
|
||||
MatrixRowMajor<float, 4, 3, 1> boxC;
|
||||
boxC.m[0][0] = 1.0f; boxC.m[1][0] = 0.0f; boxC.m[2][0] = 0.0f;
|
||||
boxC.m[1][0] = 0.0f; boxC.m[1][1] = 1.0f; boxC.m[2][1] = 0.0f;
|
||||
boxC.m[2][0] = 0.0f; boxC.m[1][2] = 0.0f; boxC.m[2][2] = 1.0f;
|
||||
|
||||
// Define Box D (size and matrix for transformation)
|
||||
Vector<float, 3, 0> sizeD(1.0f, 1.0f, 1.0f); // Box D size
|
||||
MatrixRowMajor<float, 4, 3, 1> boxD;
|
||||
boxD.m[0][0] = 1.0f; boxD.m[1][0] = 0.0f; boxD.m[2][0] = 0.0f;
|
||||
boxD.m[1][0] = 0.0f; boxD.m[1][1] = 1.0f; boxD.m[2][1] = 0.0f;
|
||||
boxD.m[2][0] = 0.0f; boxD.m[1][2] = 0.0f; boxD.m[2][2] = 1.0f;
|
||||
|
||||
// Apply a large translation to box D (so that they do not intersect)
|
||||
boxD.m[0][3] = 3.0f;
|
||||
boxD.m[1][3] = 3.0f;
|
||||
boxD.m[2][3] = 0.0f;
|
||||
|
||||
// Check if the boxes do not intersect (they shouldn't, as they are far apart)
|
||||
bool missResult = IntersectionTestOrientedBoxOrientedBox(sizeC, boxC, sizeD, boxD);
|
||||
std::cout << missResult << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue