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; }