/**
 * Util to find the normal of the face that we hit.
 * @param PHit - incoming hit from PhysX
 * @param TraceDirectionDenorm - direction of sweep test (not normalized)
 * @param OutNormal - normal we may recompute based on the faceIndex of the hit
 * @return true if we compute a new normal for the geometry.
 */
static bool FindGeomOpposingNormal(const PxLocationHit& PHit, const FVector& TraceDirectionDenorm, FVector& OutNormal)
{
    checkf(InvalidQueryHit.faceIndex == 0xFFFFffff, TEXT("Engine code needs fixing: PhysX invalid face index sentinel has changed or is not part of default PxQueryHit!"));
    if (PHit.faceIndex == InvalidQueryHit.faceIndex)
    {
        return false;
    }

    PxGeometryType::Enum GeomType = PHit.shape->getGeometryType();
    switch (GeomType)
    {
    case PxGeometryType::eSPHERE:
    case PxGeometryType::eBOX:
    case PxGeometryType::eCAPSULE:
        return FindSimpleOpposingNormal(PHit, TraceDirectionDenorm, OutNormal);
    case PxGeometryType::eCONVEXMESH:
        return FindConvexMeshOpposingNormal(PHit, TraceDirectionDenorm, OutNormal);
    case PxGeometryType::eHEIGHTFIELD:
        return FindHeightFieldOpposingNormal(PHit, TraceDirectionDenorm, OutNormal);
    case PxGeometryType::eTRIANGLEMESH:
        return FindTriMeshOpposingNormal(PHit, TraceDirectionDenorm, OutNormal);
    default:
        check(false);	//unsupported geom type
    }

    return false;
}
/**
 * Util to find the normal of the face that we hit. Will use faceIndex from the hit if possible.
 * @param PHit - incoming hit from PhysX
 * @param TraceDirectionDenorm - direction of sweep test (not normalized)
 * @param InNormal - default value in case no new normal is computed.
 * @return New normal we compute for geometry.
 */
static FVector FindGeomOpposingNormal(PxGeometryType::Enum QueryGeomType, const PxLocationHit& PHit, const FVector& TraceDirectionDenorm, const FVector InNormal)
{
	// TODO: can we support other shapes here as well?
	if (QueryGeomType == PxGeometryType::eCAPSULE || QueryGeomType == PxGeometryType::eSPHERE)
	{
		PxGeometryType::Enum GeomType = PHit.shape->getGeometryType();
		switch (GeomType)
		{
		case PxGeometryType::eSPHERE:
		case PxGeometryType::eCAPSULE:		return FindSimpleOpposingNormal(PHit, TraceDirectionDenorm, InNormal);
		case PxGeometryType::eBOX:			return FindBoxOpposingNormal(PHit, TraceDirectionDenorm, InNormal);
		case PxGeometryType::eCONVEXMESH:	return FindConvexMeshOpposingNormal(PHit, TraceDirectionDenorm, InNormal);
		case PxGeometryType::eHEIGHTFIELD:	return FindHeightFieldOpposingNormal(PHit, TraceDirectionDenorm, InNormal);
		case PxGeometryType::eTRIANGLEMESH:	return FindTriMeshOpposingNormal(PHit, TraceDirectionDenorm, InNormal);
		default: check(false);	//unsupported geom type
		}
	}

	return InNormal;
}