@@ -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