private static bool PathHitsTerrain(NativeArray <TerrainSystem.AABB> blockBoxes, int2 terrainSize, float3 start,
                                            float3 end, float paraA, float paraB, float paraC)
        {
            float distance = math.distance(end.xz, start.xz);
            int   steps    = math.max(2, (int)math.ceil(distance / TerrainSystem.BOX_SPACING) + 1);

            steps = (int)math.ceil(steps * COLLISION_STEP_MULTIPLIER);

            for (int i = 0; i < steps; i++)
            {
                float              t   = i / (steps - 1f);
                float3             pos = GetSimulatedPosition(start, end, paraA, paraB, paraC, t);
                TerrainSystem.AABB box = new TerrainSystem.AABB
                {
                    Min = pos - CANNONBALL_RADIUS,
                    Max = pos + CANNONBALL_RADIUS,
                };
                if (BoxHitsTerrain(blockBoxes, terrainSize, box))
                {
                    return(true);
                }
            }

            return(false);
        }
        static private bool BoxHitsTerrain(NativeArray <TerrainSystem.AABB> blockBoxes, int2 terrainSize,
                                           TerrainSystem.AABB box)
        {
            // check nearby boxes -- TODO bias by half a box
            int xMin = (int)math.floor((box.Min.x + 0.5f) / TerrainSystem.BOX_SPACING);
            int xMax = (int)math.floor((box.Max.x + 0.5f) / TerrainSystem.BOX_SPACING);
            int zMin = (int)math.floor((box.Min.z + 0.5f) / TerrainSystem.BOX_SPACING);
            int zMax = (int)math.floor((box.Max.z + 0.5f) / TerrainSystem.BOX_SPACING);

            xMin = math.max(0, xMin);
            xMax = math.min(terrainSize.x - 1, xMax);
            zMin = math.max(0, zMin);
            zMax = math.min(terrainSize.y - 1, zMax);

            for (int z = zMin; z <= zMax; z++)
            {
                for (int x = xMin; x <= xMax; x++)
                {
                    int blockIndex = TerrainSystem.BlockCoordsToIndex(new int2(x, z), terrainSize);
                    TerrainSystem.AABB blockBox = blockBoxes[blockIndex];
                    bool intersects             = !(box.Max.x <blockBox.Min.x || box.Min.x> blockBox.Max.x ||
                                                    box.Max.y <blockBox.Min.y || box.Min.y> blockBox.Max.y ||
                                                    box.Max.z <blockBox.Min.z || box.Min.z> blockBox.Max.z);
                    if (intersects)
                    {
                        return(true);
                    }
                }
            }

            // TODO: check tanks
            return(false);
        }