2

I am doing some physics and I am trying to find the info between a collision of a 2 oriented boxes in 3D space. I already did it for SphereSphere and SphereBox, but I cannot figure it out for BoxBox.

My boxes are: (I can easily get the transformation matrix so the axisXYZ of the box)

struct Box {
   Vector3 center;
   Vector3 size;
   Vector3 rotation;
}

And I want the info like this:

struct CollisionPoints {
    Vector3 pointA; // Collision point of box A
    Vector3 pointB; // Collision point of box B
    Vector3 Normal;
    float Depth; // would be (pointA - pointB)
    bool HasCollision;
};

But I have no idea how to do it and I do not find a lot of information on internet. There is a lot of help to find if there is a collision or not, but not to get the info.

Thank you in advance.

Hrothgor
  • 53
  • 5

1 Answers1

0

I found how to detect collision, but I am still looking for the info on the collision.

bool PhysicsAlgo::GetSeparatingPlane(
    const Vector3& relativePos, const Vector3& Plane, 
    const std::vector<Vector3>& aAxis, const Vector3& aSize,
    const std::vector<Vector3>& bAxis, const Vector3& bSize)
{
    float aProj = fabs(Vector3DotProduct((aAxis[0] * aSize.x), Plane)) +
                fabs(Vector3DotProduct((aAxis[1] * aSize.y), Plane)) +
                fabs(Vector3DotProduct((aAxis[2] * aSize.z), Plane));

    float bProj = fabs(Vector3DotProduct((bAxis[0] * bSize.x), Plane)) + 
                fabs(Vector3DotProduct((bAxis[1] * bSize.y), Plane)) +
                fabs(Vector3DotProduct((bAxis[2] * bSize.z), Plane));
    
    float rProj = fabs(Vector3DotProduct(relativePos, Plane));

    if (rProj > aProj + bProj)
        return true;
    return false;
}

CollisionPoints PhysicsAlgo::FindBoxBoxCollisionPoints(
    const BoxCollider *a, const Transform *aTransform,
    const BoxCollider *b, const Transform *bTransform)
{
    Vector3 A = aTransform->GetPositionWorld() + a->GetOffset();
    Vector3 B = bTransform->GetPositionWorld() + b->GetOffset();
    std::vector<Vector3> aAxis = aTransform->GetLocalAxis();
    std::vector<Vector3> bAxis = bTransform->GetLocalAxis();
    Vector3 aSize = a->GetSize();
    Vector3 bSize = b->GetSize();

    Vector3 rPos = B - A;

    // si 1 separatingPlane true pas de collision
    bool colliding = !(
        GetSeparatingPlane(rPos, aAxis[0], aAxis, aSize, bAxis, bSize) ||
        GetSeparatingPlane(rPos, aAxis[1], aAxis, aSize, bAxis, bSize) ||
        GetSeparatingPlane(rPos, aAxis[2], aAxis, aSize, bAxis, bSize) ||
        GetSeparatingPlane(rPos, bAxis[0], aAxis, aSize, bAxis, bSize) ||
        GetSeparatingPlane(rPos, bAxis[1], aAxis, aSize, bAxis, bSize) ||
        GetSeparatingPlane(rPos, bAxis[2], aAxis, aSize, bAxis, bSize) ||
        GetSeparatingPlane(rPos, Vector3CrossProduct(aAxis[0], bAxis[0]), aAxis, aSize, bAxis, bSize) ||
        GetSeparatingPlane(rPos, Vector3CrossProduct(aAxis[0], bAxis[1]), aAxis, aSize, bAxis, bSize) ||
        GetSeparatingPlane(rPos, Vector3CrossProduct(aAxis[0], bAxis[2]), aAxis, aSize, bAxis, bSize) ||
        GetSeparatingPlane(rPos, Vector3CrossProduct(aAxis[1], bAxis[0]), aAxis, aSize, bAxis, bSize) ||
        GetSeparatingPlane(rPos, Vector3CrossProduct(aAxis[1], bAxis[1]), aAxis, aSize, bAxis, bSize) ||
        GetSeparatingPlane(rPos, Vector3CrossProduct(aAxis[1], bAxis[2]), aAxis, aSize, bAxis, bSize) ||
        GetSeparatingPlane(rPos, Vector3CrossProduct(aAxis[2], bAxis[0]), aAxis, aSize, bAxis, bSize) ||
        GetSeparatingPlane(rPos, Vector3CrossProduct(aAxis[2], bAxis[1]), aAxis, aSize, bAxis, bSize) ||
        GetSeparatingPlane(rPos, Vector3CrossProduct(aAxis[2], bAxis[2]), aAxis, aSize, bAxis, bSize)
    );

    return {
        Vector3Zero(),
        Vector3Zero(),
        Vector3Zero(),
        0,
        colliding
    };
}
Hrothgor
  • 53
  • 5