Skip to content

Commit ece3e17

Browse files
committed
Update PCGExGeo.cpp
1 parent e1e26f2 commit ece3e17

File tree

1 file changed

+49
-48
lines changed

1 file changed

+49
-48
lines changed

Source/PCGExtendedToolkit/Private/Geometry/PCGExGeo.cpp

Lines changed: 49 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -18,81 +18,82 @@ namespace PCGExGeo
1818
{
1919
bool IntersectOBB_OBB(const FBox& BoxA, const FTransform& TransformA, const FBox& BoxB, const FTransform& TransformB)
2020
{
21-
// Compute scaled extents for A in world/local units
21+
// Precompute scales once
2222
const FVector ScaleA = TransformA.GetScale3D();
23-
const FVector ExtentA = BoxA.GetExtent() * ScaleA.GetAbs();
23+
const FVector ScaleB = TransformB.GetScale3D();
2424

25-
// Bring B into A's local space (includes scale)
26-
const FTransform BInA = TransformB * TransformA.Inverse();
25+
// Apply scales directly to extents (avoid constructing new boxes)
26+
const FVector ExtentA = BoxA.GetExtent() * ScaleA;
27+
const FVector ExtentB = BoxB.GetExtent() * ScaleB;
2728

28-
// Center of B in A-space
29-
const FVector CenterB = BInA.GetLocation();
30-
31-
// Get full matrix of BInA (rotation * scale)
32-
const FMatrix MB = BInA.ToMatrixWithScale();
29+
// Strip scales from transforms
30+
FTransform TA = TransformA;
31+
FTransform TB = TransformB;
32+
TA.SetScale3D(FVector::OneVector);
33+
TB.SetScale3D(FVector::OneVector);
3334

34-
// Extract B's scaled axes (these include scale along each axis)
35-
const FVector ScaledAxisB[3] = {MB.GetScaledAxis(EAxis::X), MB.GetScaledAxis(EAxis::Y), MB.GetScaledAxis(EAxis::Z)};
36-
37-
// Per-axis scale magnitude (absolute)
38-
const double ScaleBComp[3] = {ScaledAxisB[0].Size(), ScaledAxisB[1].Size(), ScaledAxisB[2].Size()};
35+
// Transform B into A’s local space
36+
const FTransform BInA = TB * TA.Inverse();
37+
const FVector CenterB = BInA.GetLocation();
3938

40-
// Build unit axes for B and B extents in A-space
41-
FVector AxisB[3];
42-
FVector ExtentB = BoxB.GetExtent();
39+
// Rotation matrix R = Aᵀ * B
40+
FVector B_X = BInA.GetUnitAxis(EAxis::X);
41+
FVector B_Y = BInA.GetUnitAxis(EAxis::Y);
42+
FVector B_Z = BInA.GetUnitAxis(EAxis::Z);
4343

44+
double R[3][3], AbsR[3][3];
4445
for (int i = 0; i < 3; ++i)
4546
{
46-
// Avoid division by zero; if scale is nearly zero, axis direction doesn't matter
47-
if (ScaleBComp[i] > UE_SMALL_NUMBER) { AxisB[i] = ScaledAxisB[i] / ScaleBComp[i]; }
48-
else { AxisB[i] = FVector::ZeroVector; } // degenerate axis
49-
ExtentB[i] *= ScaleBComp[i]; // world/local extent along that local axis
47+
const double BX = B_X[i];
48+
const double BY = B_Y[i];
49+
const double BZ = B_Z[i];
50+
R[i][0] = BX;
51+
R[i][1] = BY;
52+
R[i][2] = BZ;
53+
AbsR[i][0] = FMath::Abs(BX) + UE_SMALL_NUMBER;
54+
AbsR[i][1] = FMath::Abs(BY) + UE_SMALL_NUMBER;
55+
AbsR[i][2] = FMath::Abs(BZ) + UE_SMALL_NUMBER;
5056
}
5157

52-
// Build rotation matrix R = A_axes^T * B_axes.
53-
// In A-local space A's axes = identity basis (1,0,0),(0,1,0),(0,0,1).
54-
double R[3][3];
55-
double AbsR[3][3];
56-
for (int i = 0; i < 3; ++i)
57-
{
58-
for (int j = 0; j < 3; ++j)
59-
{
60-
// Dot of A_i (unit axis along i) with B_j is just component i of B_j
61-
R[i][j] = AxisB[j][i];
62-
AbsR[i][j] = FMath::Abs(R[i][j]) + UE_SMALL_NUMBER;
63-
}
64-
}
58+
const double CX = CenterB.X, CY = CenterB.Y, CZ = CenterB.Z;
59+
double A, B, P;
6560

66-
// SAT tests
67-
double A;
68-
double B;
69-
70-
// A's axes (x,y,z)
61+
// A’s local axes
7162
for (int i = 0; i < 3; ++i)
7263
{
7364
A = ExtentA[i];
7465
B = ExtentB.X * AbsR[i][0] + ExtentB.Y * AbsR[i][1] + ExtentB.Z * AbsR[i][2];
75-
if (FMath::Abs(CenterB[i]) > A + B) { return false; }
66+
if (FMath::Abs(CenterB[i]) > A + B) return false;
7667
}
7768

78-
// B's axes
69+
// B’s local axes
7970
for (int i = 0; i < 3; ++i)
8071
{
8172
A = ExtentA.X * AbsR[0][i] + ExtentA.Y * AbsR[1][i] + ExtentA.Z * AbsR[2][i];
8273
B = ExtentB[i];
83-
const double P = FMath::Abs(CenterB.X * R[0][i] + CenterB.Y * R[1][i] + CenterB.Z * R[2][i]);
84-
if (P > A + B) { return false; }
74+
P = FMath::Abs(CX * R[0][i] + CY * R[1][i] + CZ * R[2][i]);
75+
if (P > A + B) return false;
8576
}
8677

87-
// Cross product axes
78+
// Cross products (9 tests)
8879
for (int i = 0; i < 3; ++i)
8980
{
81+
const int I1 = (i + 1) % 3;
82+
const int I2 = (i + 2) % 3;
83+
const double EA1 = ExtentA[I1];
84+
const double EA2 = ExtentA[I2];
85+
const double CA1 = CenterB[I1];
86+
const double CA2 = CenterB[I2];
87+
9088
for (int j = 0; j < 3; ++j)
9189
{
92-
A = ExtentA[(i + 1) % 3] * AbsR[(i + 2) % 3][j] + ExtentA[(i + 2) % 3] * AbsR[(i + 1) % 3][j];
93-
B = ExtentB[(j + 1) % 3] * AbsR[i][(j + 2) % 3] + ExtentB[(j + 2) % 3] * AbsR[i][(j + 1) % 3];
94-
const double P = FMath::Abs(CenterB[(i + 2) % 3] * R[(i + 1) % 3][j] - CenterB[(i + 1) % 3] * R[(i + 2) % 3][j]);
95-
if (P > A + B) { return false; }
90+
const int J1 = (j + 1) % 3;
91+
const int J2 = (j + 2) % 3;
92+
93+
A = EA1 * AbsR[I2][j] + EA2 * AbsR[I1][j];
94+
B = ExtentB[J1] * AbsR[i][J2] + ExtentB[J2] * AbsR[i][J1];
95+
P = FMath::Abs(CA2 * R[I1][j] - CA1 * R[I2][j]);
96+
if (P > A + B) return false;
9697
}
9798
}
9899

0 commit comments

Comments
 (0)