private void RefineSampler(Area spawnArea, ref BoundingBoxD spawnBox, ref Vector3D desiredHalfSize, MyBBSetSampler setSampler)
        {
            var entities = MyEntities.GetEntitiesInAABB(ref spawnBox);
            foreach (var entity in entities)
            {
                if (entity is MyEnvironmentItems)
                    continue;
                if (entity is MyVoxelBase)
                    continue;
                var entityBox = entity.PositionComp.WorldAABB;
                entityBox.Inflate(desiredHalfSize);
                entityBox.Min.Y = DEBUG_BOX_Y_MIN_POS;
                entityBox.Max.Y = DEBUG_BOX_Y_MAX_POS;
                setSampler.SubtractBB(ref entityBox);
            }
            entities.Clear();

            m_aabbTree.OverlapAllBoundingBox(ref spawnBox, m_tmpAreas2);
            foreach (var area in m_tmpAreas2)
            {
                if (area != spawnArea)
                {
                    var box = area.ForestBox;
                    box.Inflate(desiredHalfSize);
                    setSampler.SubtractBB(ref box);
                }
            }
            m_tmpAreas2.Clear();
        }
        private bool TryFindLocationOutsideForestInternal(Vector3D? desiredLocationSize, out Vector3D location, Predicate<AreaData> predicate = null)
        {
            Vector3D desiredHalfSize = desiredLocationSize.HasValue ? desiredLocationSize.Value * 0.5f : Vector3D.Zero;
            desiredHalfSize.Y = 0;

            if (m_highLevelBoxes.Count == 0)
            {
                // no forest on the map, generate starting point
                bool valid = false;
                while (m_initialForestLocations.Count > 0 && !valid)
                {
                    var potentialTreePosition = m_initialForestLocations.Dequeue();
                    valid = true;
                    BoundingBoxD itemBox = new BoundingBoxD(potentialTreePosition, potentialTreePosition);
                    itemBox.Inflate(desiredHalfSize);

                    var entities = MyEntities.GetEntitiesInAABB(ref itemBox);
                    foreach (var entity in entities)
                    {
                        if (entity is MyEnvironmentItems)
                            continue;
                        if (entity is MyVoxelBase)
                            continue;
                        var entityBox = entity.PositionComp.WorldAABB;
                        var containment = entityBox.Intersects(itemBox);
                        if (containment)
                        {
                            valid = false;
                            break;
                        }
                    }
                    entities.Clear();

                    if (valid)
                    {
                        Vector3D end = potentialTreePosition;
                        end.Y -= 20;
                        if (RaycastForExactPosition(potentialTreePosition, end, out location))
                        {
                            d_foundEnlargingPoints.Add(location);
                            return true;
                        }
                        else
                        {
                            valid = false;
                        }
                    }
                }

                location = Vector3D.Zero;
                return false;
            }
            else
            {
                if (!TryGetRandomAreas(m_tmpAreas))
                {
                    location = Vector3D.Zero;
                    return false;
                }

                int areaIdx = 0;
                int randomStartIdx = MyUtils.GetRandomInt(m_tmpAreas.Count);
                while (areaIdx < m_tmpAreas.Count)
                {
                    var spawnArea = m_tmpAreas[randomStartIdx];
                    randomStartIdx = (randomStartIdx + 1) % m_tmpAreas.Count;
                    areaIdx++;

                    if (!spawnArea.IsValid || spawnArea.IsFull)
                        continue;

                    if (predicate != null && !predicate(spawnArea.GetAreaData()))
                    {
                        spawnArea.IsFull = true;
                        continue;
                    }

                    var spawnBox = spawnArea.ForestBox;
                    var forestBox = spawnArea.ForestBox;
                    spawnBox = forestBox.Inflate(desiredHalfSize);
                    spawnBox.Inflate(new Vector3D(0.2, 0, 0.2)); // inflate for some minimum size

                    MyBBSetSampler setSampler = new MyBBSetSampler(spawnBox.Min, spawnBox.Max);
                    setSampler.SubtractBB(ref forestBox);
                    RefineSampler(spawnArea, ref spawnBox, ref desiredHalfSize, setSampler);

                    if (!setSampler.Valid)
                        continue;

                    Vector3D exactLocation;
                    Vector3D samplePosition = setSampler.Sample();
                    if (TryGetExactLocation(spawnArea, samplePosition, 40, out exactLocation))
                    {
                        location = exactLocation;
                        d_foundEnlargingPoints.Add(exactLocation);
                        m_tmpAreas.Clear();
                        return true;
                    }
                    else
                    {
                        location = Vector3D.Zero;
                        m_tmpAreas.Clear();
                        return false;
                    }
                }
            }

            location = Vector3D.Zero;
            m_tmpAreas.Clear();
            return false;
        }