inline bool BoundingOrientedBox::Intersects()

in Inc/DirectXCollision.inl [2279:2477]


inline bool BoundingOrientedBox::Intersects(const BoundingOrientedBox& box) const noexcept
{
    // Build the 3x3 rotation matrix that defines the orientation of B relative to A.
    XMVECTOR A_quat = XMLoadFloat4(&Orientation);
    XMVECTOR B_quat = XMLoadFloat4(&box.Orientation);

    assert(DirectX::Internal::XMQuaternionIsUnit(A_quat));
    assert(DirectX::Internal::XMQuaternionIsUnit(B_quat));

    XMVECTOR Q = XMQuaternionMultiply(A_quat, XMQuaternionConjugate(B_quat));
    XMMATRIX R = XMMatrixRotationQuaternion(Q);

    // Compute the translation of B relative to A.
    XMVECTOR A_cent = XMLoadFloat3(&Center);
    XMVECTOR B_cent = XMLoadFloat3(&box.Center);
    XMVECTOR t = XMVector3InverseRotate(XMVectorSubtract(B_cent, A_cent), A_quat);

    //
    // h(A) = extents of A.
    // h(B) = extents of B.
    //
    // a(u) = axes of A = (1,0,0), (0,1,0), (0,0,1)
    // b(u) = axes of B relative to A = (r00,r10,r20), (r01,r11,r21), (r02,r12,r22)
    //
    // For each possible separating axis l:
    //   d(A) = sum (for i = u,v,w) h(A)(i) * abs( a(i) dot l )
    //   d(B) = sum (for i = u,v,w) h(B)(i) * abs( b(i) dot l )
    //   if abs( t dot l ) > d(A) + d(B) then disjoint
    //

    // Load extents of A and B.
    XMVECTOR h_A = XMLoadFloat3(&Extents);
    XMVECTOR h_B = XMLoadFloat3(&box.Extents);

    // Rows. Note R[0,1,2]X.w = 0.
    XMVECTOR R0X = R.r[0];
    XMVECTOR R1X = R.r[1];
    XMVECTOR R2X = R.r[2];

    R = XMMatrixTranspose(R);

    // Columns. Note RX[0,1,2].w = 0.
    XMVECTOR RX0 = R.r[0];
    XMVECTOR RX1 = R.r[1];
    XMVECTOR RX2 = R.r[2];

    // Absolute value of rows.
    XMVECTOR AR0X = XMVectorAbs(R0X);
    XMVECTOR AR1X = XMVectorAbs(R1X);
    XMVECTOR AR2X = XMVectorAbs(R2X);

    // Absolute value of columns.
    XMVECTOR ARX0 = XMVectorAbs(RX0);
    XMVECTOR ARX1 = XMVectorAbs(RX1);
    XMVECTOR ARX2 = XMVectorAbs(RX2);

    // Test each of the 15 possible seperating axii.
    XMVECTOR d, d_A, d_B;

    // l = a(u) = (1, 0, 0)
    // t dot l = t.x
    // d(A) = h(A).x
    // d(B) = h(B) dot abs(r00, r01, r02)
    d = XMVectorSplatX(t);
    d_A = XMVectorSplatX(h_A);
    d_B = XMVector3Dot(h_B, AR0X);
    XMVECTOR NoIntersection = XMVectorGreater(XMVectorAbs(d), XMVectorAdd(d_A, d_B));

    // l = a(v) = (0, 1, 0)
    // t dot l = t.y
    // d(A) = h(A).y
    // d(B) = h(B) dot abs(r10, r11, r12)
    d = XMVectorSplatY(t);
    d_A = XMVectorSplatY(h_A);
    d_B = XMVector3Dot(h_B, AR1X);
    NoIntersection = XMVectorOrInt(NoIntersection,
        XMVectorGreater(XMVectorAbs(d), XMVectorAdd(d_A, d_B)));

    // l = a(w) = (0, 0, 1)
    // t dot l = t.z
    // d(A) = h(A).z
    // d(B) = h(B) dot abs(r20, r21, r22)
    d = XMVectorSplatZ(t);
    d_A = XMVectorSplatZ(h_A);
    d_B = XMVector3Dot(h_B, AR2X);
    NoIntersection = XMVectorOrInt(NoIntersection,
        XMVectorGreater(XMVectorAbs(d), XMVectorAdd(d_A, d_B)));

    // l = b(u) = (r00, r10, r20)
    // d(A) = h(A) dot abs(r00, r10, r20)
    // d(B) = h(B).x
    d = XMVector3Dot(t, RX0);
    d_A = XMVector3Dot(h_A, ARX0);
    d_B = XMVectorSplatX(h_B);
    NoIntersection = XMVectorOrInt(NoIntersection,
        XMVectorGreater(XMVectorAbs(d), XMVectorAdd(d_A, d_B)));

    // l = b(v) = (r01, r11, r21)
    // d(A) = h(A) dot abs(r01, r11, r21)
    // d(B) = h(B).y
    d = XMVector3Dot(t, RX1);
    d_A = XMVector3Dot(h_A, ARX1);
    d_B = XMVectorSplatY(h_B);
    NoIntersection = XMVectorOrInt(NoIntersection,
        XMVectorGreater(XMVectorAbs(d), XMVectorAdd(d_A, d_B)));

    // l = b(w) = (r02, r12, r22)
    // d(A) = h(A) dot abs(r02, r12, r22)
    // d(B) = h(B).z
    d = XMVector3Dot(t, RX2);
    d_A = XMVector3Dot(h_A, ARX2);
    d_B = XMVectorSplatZ(h_B);
    NoIntersection = XMVectorOrInt(NoIntersection,
        XMVectorGreater(XMVectorAbs(d), XMVectorAdd(d_A, d_B)));

    // l = a(u) x b(u) = (0, -r20, r10)
    // d(A) = h(A) dot abs(0, r20, r10)
    // d(B) = h(B) dot abs(0, r02, r01)
    d = XMVector3Dot(t, XMVectorPermute<XM_PERMUTE_0W, XM_PERMUTE_1Z, XM_PERMUTE_0Y, XM_PERMUTE_0X>(RX0, XMVectorNegate(RX0)));
    d_A = XMVector3Dot(h_A, XMVectorSwizzle<XM_SWIZZLE_W, XM_SWIZZLE_Z, XM_SWIZZLE_Y, XM_SWIZZLE_X>(ARX0));
    d_B = XMVector3Dot(h_B, XMVectorSwizzle<XM_SWIZZLE_W, XM_SWIZZLE_Z, XM_SWIZZLE_Y, XM_SWIZZLE_X>(AR0X));
    NoIntersection = XMVectorOrInt(NoIntersection,
        XMVectorGreater(XMVectorAbs(d), XMVectorAdd(d_A, d_B)));

    // l = a(u) x b(v) = (0, -r21, r11)
    // d(A) = h(A) dot abs(0, r21, r11)
    // d(B) = h(B) dot abs(r02, 0, r00)
    d = XMVector3Dot(t, XMVectorPermute<XM_PERMUTE_0W, XM_PERMUTE_1Z, XM_PERMUTE_0Y, XM_PERMUTE_0X>(RX1, XMVectorNegate(RX1)));
    d_A = XMVector3Dot(h_A, XMVectorSwizzle<XM_SWIZZLE_W, XM_SWIZZLE_Z, XM_SWIZZLE_Y, XM_SWIZZLE_X>(ARX1));
    d_B = XMVector3Dot(h_B, XMVectorSwizzle<XM_SWIZZLE_Z, XM_SWIZZLE_W, XM_SWIZZLE_X, XM_SWIZZLE_Y>(AR0X));
    NoIntersection = XMVectorOrInt(NoIntersection,
        XMVectorGreater(XMVectorAbs(d), XMVectorAdd(d_A, d_B)));

    // l = a(u) x b(w) = (0, -r22, r12)
    // d(A) = h(A) dot abs(0, r22, r12)
    // d(B) = h(B) dot abs(r01, r00, 0)
    d = XMVector3Dot(t, XMVectorPermute<XM_PERMUTE_0W, XM_PERMUTE_1Z, XM_PERMUTE_0Y, XM_PERMUTE_0X>(RX2, XMVectorNegate(RX2)));
    d_A = XMVector3Dot(h_A, XMVectorSwizzle<XM_SWIZZLE_W, XM_SWIZZLE_Z, XM_SWIZZLE_Y, XM_SWIZZLE_X>(ARX2));
    d_B = XMVector3Dot(h_B, XMVectorSwizzle<XM_SWIZZLE_Y, XM_SWIZZLE_X, XM_SWIZZLE_W, XM_SWIZZLE_Z>(AR0X));
    NoIntersection = XMVectorOrInt(NoIntersection,
        XMVectorGreater(XMVectorAbs(d), XMVectorAdd(d_A, d_B)));

    // l = a(v) x b(u) = (r20, 0, -r00)
    // d(A) = h(A) dot abs(r20, 0, r00)
    // d(B) = h(B) dot abs(0, r12, r11)
    d = XMVector3Dot(t, XMVectorPermute<XM_PERMUTE_0Z, XM_PERMUTE_0W, XM_PERMUTE_1X, XM_PERMUTE_0Y>(RX0, XMVectorNegate(RX0)));
    d_A = XMVector3Dot(h_A, XMVectorSwizzle<XM_SWIZZLE_Z, XM_SWIZZLE_W, XM_SWIZZLE_X, XM_SWIZZLE_Y>(ARX0));
    d_B = XMVector3Dot(h_B, XMVectorSwizzle<XM_SWIZZLE_W, XM_SWIZZLE_Z, XM_SWIZZLE_Y, XM_SWIZZLE_X>(AR1X));
    NoIntersection = XMVectorOrInt(NoIntersection,
        XMVectorGreater(XMVectorAbs(d), XMVectorAdd(d_A, d_B)));

    // l = a(v) x b(v) = (r21, 0, -r01)
    // d(A) = h(A) dot abs(r21, 0, r01)
    // d(B) = h(B) dot abs(r12, 0, r10)
    d = XMVector3Dot(t, XMVectorPermute<XM_PERMUTE_0Z, XM_PERMUTE_0W, XM_PERMUTE_1X, XM_PERMUTE_0Y>(RX1, XMVectorNegate(RX1)));
    d_A = XMVector3Dot(h_A, XMVectorSwizzle<XM_SWIZZLE_Z, XM_SWIZZLE_W, XM_SWIZZLE_X, XM_SWIZZLE_Y>(ARX1));
    d_B = XMVector3Dot(h_B, XMVectorSwizzle<XM_SWIZZLE_Z, XM_SWIZZLE_W, XM_SWIZZLE_X, XM_SWIZZLE_Y>(AR1X));
    NoIntersection = XMVectorOrInt(NoIntersection,
        XMVectorGreater(XMVectorAbs(d), XMVectorAdd(d_A, d_B)));

    // l = a(v) x b(w) = (r22, 0, -r02)
    // d(A) = h(A) dot abs(r22, 0, r02)
    // d(B) = h(B) dot abs(r11, r10, 0)
    d = XMVector3Dot(t, XMVectorPermute<XM_PERMUTE_0Z, XM_PERMUTE_0W, XM_PERMUTE_1X, XM_PERMUTE_0Y>(RX2, XMVectorNegate(RX2)));
    d_A = XMVector3Dot(h_A, XMVectorSwizzle<XM_SWIZZLE_Z, XM_SWIZZLE_W, XM_SWIZZLE_X, XM_SWIZZLE_Y>(ARX2));
    d_B = XMVector3Dot(h_B, XMVectorSwizzle<XM_SWIZZLE_Y, XM_SWIZZLE_X, XM_SWIZZLE_W, XM_SWIZZLE_Z>(AR1X));
    NoIntersection = XMVectorOrInt(NoIntersection,
        XMVectorGreater(XMVectorAbs(d), XMVectorAdd(d_A, d_B)));

    // l = a(w) x b(u) = (-r10, r00, 0)
    // d(A) = h(A) dot abs(r10, r00, 0)
    // d(B) = h(B) dot abs(0, r22, r21)
    d = XMVector3Dot(t, XMVectorPermute<XM_PERMUTE_1Y, XM_PERMUTE_0X, XM_PERMUTE_0W, XM_PERMUTE_0Z>(RX0, XMVectorNegate(RX0)));
    d_A = XMVector3Dot(h_A, XMVectorSwizzle<XM_SWIZZLE_Y, XM_SWIZZLE_X, XM_SWIZZLE_W, XM_SWIZZLE_Z>(ARX0));
    d_B = XMVector3Dot(h_B, XMVectorSwizzle<XM_SWIZZLE_W, XM_SWIZZLE_Z, XM_SWIZZLE_Y, XM_SWIZZLE_X>(AR2X));
    NoIntersection = XMVectorOrInt(NoIntersection,
        XMVectorGreater(XMVectorAbs(d), XMVectorAdd(d_A, d_B)));

    // l = a(w) x b(v) = (-r11, r01, 0)
    // d(A) = h(A) dot abs(r11, r01, 0)
    // d(B) = h(B) dot abs(r22, 0, r20)
    d = XMVector3Dot(t, XMVectorPermute<XM_PERMUTE_1Y, XM_PERMUTE_0X, XM_PERMUTE_0W, XM_PERMUTE_0Z>(RX1, XMVectorNegate(RX1)));
    d_A = XMVector3Dot(h_A, XMVectorSwizzle<XM_SWIZZLE_Y, XM_SWIZZLE_X, XM_SWIZZLE_W, XM_SWIZZLE_Z>(ARX1));
    d_B = XMVector3Dot(h_B, XMVectorSwizzle<XM_SWIZZLE_Z, XM_SWIZZLE_W, XM_SWIZZLE_X, XM_SWIZZLE_Y>(AR2X));
    NoIntersection = XMVectorOrInt(NoIntersection,
        XMVectorGreater(XMVectorAbs(d), XMVectorAdd(d_A, d_B)));

    // l = a(w) x b(w) = (-r12, r02, 0)
    // d(A) = h(A) dot abs(r12, r02, 0)
    // d(B) = h(B) dot abs(r21, r20, 0)
    d = XMVector3Dot(t, XMVectorPermute<XM_PERMUTE_1Y, XM_PERMUTE_0X, XM_PERMUTE_0W, XM_PERMUTE_0Z>(RX2, XMVectorNegate(RX2)));
    d_A = XMVector3Dot(h_A, XMVectorSwizzle<XM_SWIZZLE_Y, XM_SWIZZLE_X, XM_SWIZZLE_W, XM_SWIZZLE_Z>(ARX2));
    d_B = XMVector3Dot(h_B, XMVectorSwizzle<XM_SWIZZLE_Y, XM_SWIZZLE_X, XM_SWIZZLE_W, XM_SWIZZLE_Z>(AR2X));
    NoIntersection = XMVectorOrInt(NoIntersection,
        XMVectorGreater(XMVectorAbs(d), XMVectorAdd(d_A, d_B)));

    // No seperating axis found, boxes must intersect.
    return XMVector4NotEqualInt(NoIntersection, XMVectorTrueInt()) ? true : false;
}