0
\$\begingroup\$

I am doing SAT in 3D, right now just between cuboids/3D rects (idk the terminology). I have intersection working fully, and static collision works as long as the projection axis is not zero. But if it is zero, I am unsure how to get the minimum translation vector and overlap.

Here is the function which returns the face normals, vertices are ordered counter-clockwise starting bottom left - z for face 1, then repeat for +z, where 4 is bottom left +z:

    private float3[] GetAxesFromPoly( float3[] vertices )
    {
        float3[] axes = new float3[ 3 ];
        axes[ 0 ] = math.normalize( ( vertices[ 1 ] - vertices[ 0 ] ) );
        axes[ 1 ] = math.normalize( ( vertices[ 3 ] - vertices[ 0 ] ) );
        axes[ 2 ] = math.normalize( ( vertices[ 4 ] - vertices[ 0 ] ) );

        return axes;
    }

And here is all axes I get to test:

        float3[] axesA = GetAxesFromPoly( vertsA );
        float3[] axesB = GetAxesFromPoly( vertsB );

        float3[] allAxes = new float3[ 15 ];
        allAxes[ 0 ]  = axesA[ 0 ];
        allAxes[ 1 ]  = axesA[ 1 ];
        allAxes[ 2 ]  = axesA[ 2 ];
        allAxes[ 3 ]  = axesB[ 0 ];
        allAxes[ 4 ]  = axesB[ 1 ];
        allAxes[ 5 ]  = axesB[ 2 ];
        allAxes[ 6 ]  = math.cross( axesA[ 0 ] , axesB[ 0 ] );
        allAxes[ 7 ]  = math.cross( axesA[ 0 ] , axesB[ 1 ] );
        allAxes[ 8 ]  = math.cross( axesA[ 0 ] , axesB[ 2 ] );
        allAxes[ 9 ]  = math.cross( axesA[ 1 ] , axesB[ 0 ] );
        allAxes[ 10 ] = math.cross( axesA[ 1 ] , axesB[ 1 ] );
        allAxes[ 11 ] = math.cross( axesA[ 1 ] , axesB[ 2 ] );
        allAxes[ 12 ] = math.cross( axesA[ 2 ] , axesB[ 0 ] );
        allAxes[ 13 ] = math.cross( axesA[ 2 ] , axesB[ 1 ] );
        allAxes[ 14 ] = math.cross( axesA[ 2 ] , axesB[ 2 ] );
```
\$\endgroup\$
3
  • \$\begingroup\$ In what situation do you get a valid projection axis that is zero? \$\endgroup\$ – DMGregory Mar 29 at 22:36
  • \$\begingroup\$ If the intersection is a perfect face intersection. For example if both shapes have a face which are parallel to each other. \$\endgroup\$ – Tree3708 Mar 29 at 22:54
  • \$\begingroup\$ Then by definition, your objects are in "kissing contact", not penetrating, so the overlap and minimum translation vector are zero. \$\endgroup\$ – DMGregory Mar 29 at 22:57
1
\$\begingroup\$

For anyone who might be facing a similar issue, I found the solution. As you may know we are suppose to disregard any axis which are (0,0,0) (cross product of edges from two shapes is 0), because we cannot project onto a vector of zero, as well we will not be able to get a minimum translation vector or minimum overlap.

In my code, in the loop which goes over each projection axis and projects all vertices onto it, I was early outing if the projection axis was (0,0,0), like this:

        for ( int i = 0; i < allAxes.Length; i++ )
        {
            float3 axis = allAxes[ i ];

            if ( axis.x == 0 && axis.y == 0 && axis.z == 0 )
                return true;
        }

It was detecting collisions properly, but because I was early outing I could not resolve the collision. Simple fix was to change return to continue.

I know its a silly mistake but maybe someone else new to SAT may find this useful.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.