Maybe we're at cross-purposes here - the simple presence of the BlockTargetResult object in the List returned by getLineOfSight() indicates that the voxel (the 1x1x1 container) *was* intersected by the entity's line of sight.

I'd know that the carpet wasn't included because:
1. It's not the last object in the list (so the entity's line of sight passed through the voxel, but not through the carpet itself)
2. The ``getTargetedFace()`` and ``getTargetedLocation()`` methods for the BlockTargetResult object return null.

There's a distinction to be drawn between blocks to be ignored because of transparency information (the Predicate) and blocks to be ignored because the line of sight doesn't intersect the block's hit box.

It's important to remember that unlike the old API, these methods are returning a targeting result record (or List thereof), not an actual Block.  The result record includes the block that was considered (``getBlock()``) and the results of considering that block (``getTargetedFace()`` and ``getTargetedLocation()``).  For ``getLineOfSight()`` and ``getLastTwoTargetBlocks()``, the intermediate blocks along the line of sight will, by definition, be considered intermediate either due to the Predicate or because the block's hit box was not intersected; only the final record in the returned list *might* have an intersection (and that depends on whether an intersection was found within the ``maxDistance`` parameter).

Regarding ``AIR``: that's a rather special case, since AIR has no hit box at all.  However if you really want to target the nearest AIR block (and we're getting pretty contrived here), pass a ``Predicate<Block>`` which returns true for AIR, and a ``useHitBoxes`` parameter of false.