private List <GroundShapeInfoInTree> FindOverlappingGroundShapes(GroundShapeInfo info) { var queryEnvelope = MyNetTopologySuiteUtils.ToEnvelope(info.GlobalSubposition); var overlappingElements = _groundTree.Query(queryEnvelope) .Where(c => c.GlobalSubpositionEnvelope.Intersection(queryEnvelope).Area > 1) .ToList(); return(overlappingElements); }
private ILinearRing Translate(ILinearRing input) { return(new LinearRing( input.Coordinates .Select(c => MyNetTopologySuiteUtils.ToVector2(c)) .Select(c => _translator.TranslateToUnity(c)) .Select(c => MyNetTopologySuiteUtils.ToCoordinate(c)) .ToArray() )); }
public MyQuadtree <HabitatFieldInTree> QueryMap(MyRectangle queryArea) { var outTree = new MyQuadtree <HabitatFieldInTree>(); Vector2 reoffsetStartPosition = new Vector2(queryArea.X, queryArea.Y) - _mapStartPosition; Vector2 reoffsetEndPosition = new Vector2(queryArea.X + queryArea.Width, queryArea.Y + queryArea.Height) - _mapStartPosition; var startGridX = Mathf.FloorToInt(reoffsetStartPosition.x / _mapGridSize.x); var startGridY = Mathf.FloorToInt(reoffsetStartPosition.y / _mapGridSize.y); var endGridX = Mathf.Min(_gridCellsCount.X, Mathf.CeilToInt(reoffsetEndPosition.x / _mapGridSize.x)); var endGridY = Mathf.Min(_gridCellsCount.Y, Mathf.CeilToInt(reoffsetEndPosition.y / _mapGridSize.y)); if (startGridX < 0 || startGridY < 0 || endGridX > _gridCellsCount.X || endGridY > _gridCellsCount.Y) { Preconditions.Fail( $"Querying area {queryArea}, makes grids query: x:{startGridX} - {endGridX} y:{startGridY}-{endGridY} which is out of size {_gridCellsCount}"); } var queryEnvelope = MyNetTopologySuiteUtils.ToGeometryEnvelope(queryArea); for (var gridX = startGridX; gridX < endGridX; gridX++) { for (var gridY = startGridY; gridY < endGridY; gridY++) { //todo return other structure - one that uses gridded tree in array List <HabitatFieldInTree> treeElements = null; treeElements = _treeArray[gridX, gridY].QueryAll().Select(c => new { intersection = c.Field.Geometry.Intersection(queryEnvelope), elem = c }) .Where(c => !c.intersection.IsEmpty && !(c.intersection is ILineString)) .SelectMany(c => MyNetTopologySuiteUtils.ToSinglePolygons(c.intersection).Select( k => new HabitatFieldInTree() { Field = new HabitatField() { Geometry = k, Type = c.elem.Field.Type } })).ToList(); treeElements.ForEach(c => outTree.Add(c)); } } return(outTree); }
private MyQuadtree <HabitatEnlargedByMarginInTree> GenerateEnlargedTree(List <HabitatField> habitatFields) { var outTree = new MyQuadtree <HabitatEnlargedByMarginInTree>(); foreach (var field in habitatFields) { var geo = field.Geometry; var enlargedGeo = MyNetTopologySuiteUtils.EnlargeByMargin(geo, _configuration.HabitatMargin); outTree.Add(new HabitatEnlargedByMarginInTree() { Type = field.Type, MarginedHabitatField = enlargedGeo, StandardHabitatField = geo }); } return(outTree); }
private void InitializeBushObjectsDb(List <VegetationSubjectEntity> smallDb, ForgingVegetationSubjectInstanceContainerProxy forgingContainerProxy) { var repositioner = _veConfiguration.VegetationRepositioner; var supportedSpecies = _veConfiguration.SupportedLeadingBushSpecies; var speciesChanger = new VegetationSpeciesRandomChanger(_veConfiguration.SpeciesChangingList, 661); //todo! var filteredEntities = smallDb .Where(c => supportedSpecies.Contains(c.Detail.SpeciesEnum)) .Select(c => speciesChanger.ChangeSpecies(c)) .Where(c => _veConfiguration.SupportedBushSpecies.Contains(c.Detail.SpeciesEnum)); var quadtree = new Quadtree <VegetationSubjectEntity>(); foreach (var entity in filteredEntities) { quadtree.Insert(MyNetTopologySuiteUtils.ToPointEnvelope(entity.Position2D), entity); } var positionsProvider = new VegetationSubjectsPositionsDatabase(quadtree); var runtimeManagement = new VegetationRuntimeManagement( positionsProvider: positionsProvider, vegetationSubjectsChangesListener: forgingContainerProxy, visibleEntitiesContainer: new VegetationSubjectsVisibleEntitiesContainer(), configuration: _veConfiguration.BushObjectsVegetationRuntimeManagementConfiguration); var vegetationRuntimeManagementProxy = new VegetationRuntimeManagementProxy(runtimeManagement); _ultraUpdatableContainer.AddUpdatableElement(new FieldBasedUltraUpdatable() { StartCameraField = (camera) => { vegetationRuntimeManagementProxy.StartThreading(); var position = camera.Position; vegetationRuntimeManagementProxy.Start(repositioner.InvMove(position)); }, UpdateCameraField = (camera) => { var position = camera.Position; vegetationRuntimeManagementProxy.AddUpdate(repositioner.InvMove(position)); vegetationRuntimeManagementProxy.SynchronicUpdate(repositioner.InvMove(position)); }, }); }
public List <VegetationSubjectEntity> GetEntiesFrom(IGeometry area, VegetationDetailLevel level) { var outPositions = new List <Vector2>(); if (level == VegetationDetailLevel.FULL) { var envelope = area.EnvelopeInternal; var gridPositionsStart = new IntVector2( Mathf.CeilToInt((float)envelope.MinX / _configuration.PositionsGridSize.x), Mathf.CeilToInt((float)envelope.MinY / _configuration.PositionsGridSize.y)); var afterGridingLength = new Vector2( (float)(envelope.MaxX - gridPositionsStart.X * _configuration.PositionsGridSize.x), (float)(envelope.MaxY - gridPositionsStart.Y * _configuration.PositionsGridSize.y)); var gridLength = new IntVector2( //ceil becouse there is point at length 0 !! Mathf.CeilToInt(afterGridingLength.x / _configuration.PositionsGridSize.x), Mathf.CeilToInt(afterGridingLength.y / _configuration.PositionsGridSize.y)); for (int x = 0; x < gridLength.X; x++) { for (int y = 0; y < gridLength.Y; y++) { var position = new Vector2( (0.5f + (gridPositionsStart.X + x)) * _configuration.PositionsGridSize.x, (0.5f + (gridPositionsStart.Y + y)) * _configuration.PositionsGridSize.y); outPositions.Add(position); } } } return(outPositions.Where(c => area.Contains(MyNetTopologySuiteUtils.ToGeometryEnvelope( MyNetTopologySuiteUtils.ToPointEnvelope(c)))).Select(c => new VegetationSubjectEntity( new DesignBodyLevel0Detail() { Pos2D = c, Radius = 0, Size = 0, SpeciesEnum = VegetationSpeciesEnum.Grass2SpotMarker })).ToList()); }
private VegetationSubjectsPositionsDatabase CreateSamplePositionsDatabase() { var tree = new Quadtree <VegetationSubjectEntity>(); for (int x = 0; x < 4000; x += 30) { for (int y = 0; y < 4000; y += 30) { var newEntity = new VegetationSubjectEntity( new DesignBodyLevel0Detail() { Pos2D = new Vector2(x, y), Radius = 0, Size = 0, SpeciesEnum = VegetationSpeciesEnum.Tree1A }); tree.Insert(MyNetTopologySuiteUtils.ToPointEnvelope(newEntity.Position2D), newEntity); } } return(new VegetationSubjectsPositionsDatabase(tree)); }
//19.64311408996582 49.603153228759766 // 1914206496 // 180998242 //19.71388099829122, 49.648193645648 // 19.628429388931949, 49.617853376339596 private ILinearRing ToLinearRing(List <Vector2> nodes) { var nodesAsCoordinates = nodes.Select(c => MyNetTopologySuiteUtils.ToCoordinate(c)).ToList(); if (!nodesAsCoordinates.First().Equals(nodesAsCoordinates.Last())) { var repairedRing = nodesAsCoordinates.ToList(); repairedRing.Add(nodesAsCoordinates.First()); var ring = new LinearRing(repairedRing.ToArray()); if (!ring.IsValid) { //simple connection failed. Propably should do crectangle merging var ringRect = ring.EnvelopeInternal; Debug.Log("Pushing your luck. Lets hope that it is his only, 2415555 relation!"); //todo make better invalid circular way repairing algorithm. Like find which two sides // of enveloping rectangle would be shorted in repairing road var newRingPoint = ringRect.ToMyRectangle().TopRightPoint; repairedRing[repairedRing.Count - 1] = new Coordinate(newRingPoint.x, newRingPoint.y); repairedRing.Add(nodesAsCoordinates.First()); ring = new LinearRing(repairedRing.ToArray()); if (!ring.IsValid) { var validOp = new IsValidOp(ring); Debug.Log("Validation error is: " + validOp.ValidationError); Debug.Log("R1 Ring is " + ring.ToString()); return(null); //var text = ring.ToText(); //File.WriteAllText(@"C:\inz\wrongRing.wkt", text); } Preconditions.Assert(ring.IsValid, "Ring still invalid. What to do?"); } return(ring); } else { return(new LinearRing(nodesAsCoordinates.ToArray())); } }
public static void CreateDebugHabitatField(HabitatField field, float positionMultiplier = 1000, GameObject parentGameObject = null) { var polys = MyNetTopologySuiteUtils.ToSinglePolygons(field.Geometry); if (polys.Count == 1) { var poly = polys[0]; var exteriorRing = poly.ExteriorRing.Coordinates.Select(i => MyNetTopologySuiteUtils.ToVector2(i)) .ToList(); var rootObject = CreateRingGameObject(exteriorRing, positionMultiplier); if (parentGameObject != null) { rootObject.transform.SetParent(parentGameObject.transform); } rootObject.name = field.Type.ToString(); foreach (var interiorRing in poly.Holes) { var ring = interiorRing.Coordinates.Select(i => MyNetTopologySuiteUtils.ToVector2(i)).ToList(); var ringObject = CreateRingGameObject(ring, positionMultiplier); ringObject.transform.SetParent(rootObject.transform); } } else { foreach (var habitatField in polys.Select(poly => new HabitatField() { Geometry = poly, Type = field.Type })) { CreateDebugHabitatField(habitatField, positionMultiplier, parentGameObject); } } }
public static HabitatMap Create( MyRectangle areaOnMap, Vector2 mapGridSize, List <HabitatField> habitatFields, HabitatType defaultHabitatType, HabitatTypePriorityResolver priorityResolver) { var fullTree = new MyQuadtree <HabitatFieldInTree>(); habitatFields.ForEach(c => fullTree.Add(new HabitatFieldInTree() { Field = c })); int gridXCount = Mathf.CeilToInt(areaOnMap.Width / mapGridSize.x); int gridYCount = Mathf.CeilToInt(areaOnMap.Height / mapGridSize.y); var gridTreeArray = new MyQuadtree <HabitatFieldInTree> [gridXCount, gridYCount]; for (int gridX = 0; gridX < gridXCount; gridX++) { for (int gridY = 0; gridY < gridYCount; gridY++) { var gridArea = new MyRectangle( areaOnMap.X + gridX * mapGridSize.x, areaOnMap.Y + gridY * mapGridSize.y, mapGridSize.x, mapGridSize.y); var geometryEnvelope = MyNetTopologySuiteUtils.ToGeometryEnvelope(gridArea); var fieldsInArea = fullTree.QueryWithIntersection(geometryEnvelope); //Debug.Log("U34: "+fieldsInArea.Count(c => c.Field.Type == HabitatType.Fell)); //if (fieldsInArea.Count(c => c.Field.Type == HabitatType.Fell) > 0 ) //{ // Debug.Log($"J2: {StringUtils.ToString(fieldsInArea.Where(c => c.Field.Type == HabitatType.Fell).Select(c => c.Field.Geometry.AsText()))}"); //} var fieldsInEnvelope = fieldsInArea.Select(c => new HabitatField() { Geometry = MySafeIntersection(c.Field.Geometry, geometryEnvelope), Type = c.Field.Type }).Where(c => c.Geometry != null && !c.Geometry.IsEmpty); // removal of elements one on other var sortedFields = fieldsInEnvelope.OrderByDescending(c => priorityResolver.Resolve(c.Type)) .ToList(); for (int i = 0; i < sortedFields.Count; i++) { var current = sortedFields[i]; for (int j = i + 1; j < sortedFields.Count; j++) { var other = sortedFields[j]; other.Geometry = other.Geometry.Difference(current.Geometry); } } sortedFields = sortedFields.Where(c => !c.Geometry.IsEmpty).ToList(); var notUsedAreaInGrid = geometryEnvelope; foreach (var cutGeometry in sortedFields.Select(c => c.Geometry)) { notUsedAreaInGrid = notUsedAreaInGrid.Difference(cutGeometry); } if (!notUsedAreaInGrid.IsEmpty) { sortedFields.Add( new HabitatField() { Type = defaultHabitatType, Geometry = notUsedAreaInGrid } ); } var singleFieldsInTree = sortedFields.SelectMany(c => MyNetTopologySuiteUtils .ToSinglePolygons(c.Geometry).Select(poly => new HabitatField() { Geometry = poly, Type = c.Type })).Select(c => new HabitatFieldInTree() { Field = c }).ToList(); gridTreeArray[gridX, gridY] = MyQuadtree <HabitatFieldInTree> .CreateWithElements(singleFieldsInTree); } } return(new HabitatMap( new Vector2(areaOnMap.X, areaOnMap.Y), mapGridSize, new IntVector2(gridXCount, gridYCount), gridTreeArray)); }
private async Task <Dictionary <HabitatType, Texture2D> > CreateHabitatTexturesDict( Vector2 startOffset, IntVector2 habitatTextureSize, List <HabitatFieldInTree> habitats) { var habitatTextureTemplatesDict = new Dictionary <HabitatType, MyTextureTemplate>(); var allTypes = habitats.Select(c => c.Field.Type).Distinct(); foreach (var type in allTypes) { //var newTex = new Texture2D(habitatTextureSize.X, habitatTextureSize.Y, TextureFormat.RGB24, false, true); var newTexTemplate = new MyTextureTemplate(habitatTextureSize.X, habitatTextureSize.Y, TextureFormat.ARGB32, false, FilterMode.Bilinear) { wrapMode = TextureWrapMode.Clamp }; habitatTextureTemplatesDict[type] = newTexTemplate; } var enlargedTree = GenerateEnlargedTree(habitats.Select(c => c.Field).ToList()); for (int x = 0; x < habitatTextureSize.X; x++) { for (int y = 0; y < habitatTextureSize.Y; y++) { var centerPoint = new Vector2( (x + 0.5f) * (_configuration.HabitatSamplingUnit), (y + 0.5f) * (_configuration.HabitatSamplingUnit) ) + startOffset; var pointGeometry = MyNetTopologySuiteUtils.ToGeometryEnvelope(MyNetTopologySuiteUtils .ToPointEnvelope(centerPoint)); var marginTouchingHabitats = enlargedTree.QueryWithIntersection(pointGeometry); foreach (var texture in habitatTextureTemplatesDict.Values) { texture.SetPixel(x, y, new Color(0, 0, 0)); } foreach (var habitatType in marginTouchingHabitats.Select(c => c.Type).Distinct()) { var maxIntensityValue = 0f; foreach (var habitat in marginTouchingHabitats.Where(c => c.Type == habitatType)) { if (habitat.StandardHabitatField.Contains(pointGeometry)) { maxIntensityValue = 1; } else { var distance = MyNetTopologySuiteUtils.Distance(pointGeometry, habitat.StandardHabitatField, _configuration.HabitatMargin); maxIntensityValue = Mathf.Max(maxIntensityValue, Mathf.Clamp01(1 - (distance / _configuration.HabitatMargin))); } } habitatTextureTemplatesDict[habitatType].SetPixel(x, y, new Color(maxIntensityValue, 0, 0)); } } } var renderedTextures = await TaskUtils.WhenAll( habitatTextureTemplatesDict.Values .Select(async(c) => await _textureConciever.ConcieveTextureAsync(c))); var outDict = Enumerable.Range(0, renderedTextures.Count) .ToDictionary(i => habitatTextureTemplatesDict.Keys.ToList()[i], i => renderedTextures[i]); return(outDict); }
public bool Intersects(IGeometry geometry) { return(MyNetTopologySuiteUtils.ToGeometryEnvelope(CoordedHeightArray.Coords).Intersects(geometry)); }
public Envelope CalculateEnvelope() { return(MyNetTopologySuiteUtils.ToEnvelope(CoordedHeightArray.Coords)); }
private void StartTreesRuntimeManagment() { var globalInstancingContainer = _initializationFields.Retrive <GlobalGpuInstancingContainer>(); var representationContainer = new DesignBodyRepresentationContainer(); var instanceBucketsContainer = new DesignBodyInstanceBucketsContainer(globalInstancingContainer); var quadBillboardMesh = GameObject.CreatePrimitive(PrimitiveType.Quad).GetComponent <MeshFilter>().mesh; IDesignBodyRepresentationInstanceCombinationProvider combinationProvider; if (_veConfiguration.Mode == VegetationMode.Legacy) { var gShifter = new GTreeDetailProviderShifter(new DetailProviderRepository(), quadBillboardMesh); var treeFileManager = new TreeFileManager(new TreeFileManagerConfiguration() { WritingTreeCompletedClanDirectory = _veConfiguration.TreeCompletedClanDirectiory }); combinationProvider = new GDesignBodyRepresentationInstanceCombinationProvider(treeFileManager, gShifter); } else { var eVegetationShifter = new EVegetationDetailProviderShifter( _veConfiguration.ShaderNames, new DetailProviderRepository(), quadBillboardMesh, _veConfiguration.ReferencedAssets, _materialCommonPack); combinationProvider = new EVegetationDesignBodyRepresentationInstanceCombinationProvider(new TreePrefabManager(), eVegetationShifter, _veConfiguration.ReferencedAssets); } foreach (var pair in _veConfiguration.ShiftingConfigurations.Where(c => _veConfiguration.SupportedVegetationSpecies.Contains(c.Key))) { var clanRepresentations = combinationProvider.CreateRepresentations(pair.Value, pair.Key); representationContainer.InitializeLists(clanRepresentations); instanceBucketsContainer.InitializeLists(clanRepresentations); } var designBodySpotUpdaterProxy = _initializationFields.Retrive <DesignBodySpotUpdaterProxy>(); var mediatorSpotUpdater = new ListenerCenteredMediatorDesignBodyChangesUpdater(designBodySpotUpdaterProxy); var rootMediator = _initializationFields.Retrive <RootMediatorSpotPositionsUpdater>(); rootMediator.AddListener(mediatorSpotUpdater); var repositioner = _veConfiguration.VegetationRepositioner; var forgingContainerProxy = new ForgingVegetationSubjectInstanceContainerProxy( new ForgingVegetationSubjectInstanceContainer( new DesignBodyPortrayalForger( representationContainer, instanceBucketsContainer, repositioner), mediatorSpotUpdater//teraz napisz tak, zeby info zwrotne se spotupdatera wracalo zgodnie z multithreadingiem (szlo do innego watku!) )); mediatorSpotUpdater.SetTargetChangesListener(new LambdaSpotPositionChangesListener(dict => { forgingContainerProxy.AddSpotModifications(dict); })); _ultraUpdatableContainer.AddOtherThreadProxy(forgingContainerProxy); MyProfiler.BeginSample("Vegetation1: Loading from file"); var baseVegetationList = VegetationDatabaseFileUtils.LoadListFromFiles(_veConfiguration.LoadingVegetationDatabaseDictionaryPath); MyProfiler.EndSample(); if (_veConfiguration.GenerateTrees) { MyProfiler.BeginSample("Vegetation2: pushingToFile"); foreach (var pair in _veConfiguration.PerRankVegetationRuntimeManagementConfigurations) { var rank = pair.Key; var managementConfiguration = pair.Value; var baseRankedDb = baseVegetationList[rank]; var supportedSpecies = _veConfiguration.SupportedTreeSpecies; var filteredEntities = baseRankedDb.Where(c => supportedSpecies.Contains(c.Detail.SpeciesEnum)).ToList(); var stagnantEntities = new List <VegetationSubjectEntity>(); var nonStagnantEntities = new List <VegetationSubjectEntity>(); var nonStagnantVegetationRect = _veConfiguration.NonStagnantVegetationArea; foreach (var entity in filteredEntities) { if (nonStagnantVegetationRect.Contains(entity.Position2D)) { nonStagnantEntities.Add(entity); } else { stagnantEntities.Add(entity); } } var stagnantVegetationRuntimeManagement = new StagnantVegetationRuntimeManagement(forgingContainerProxy, stagnantEntities, _veConfiguration.StagnantVegetationRuntimeManagementConfiguration); var stagnantVegetationRuntimaManagementProxy = new StagnantVegetationRuntimeManagementProxy(stagnantVegetationRuntimeManagement); _ultraUpdatableContainer.AddUpdatableElement(new FieldBasedUltraUpdatable() { StartField = () => { stagnantVegetationRuntimaManagementProxy.StartThreading(); } }); var quadtree = new Quadtree <VegetationSubjectEntity>(); foreach (var entity in nonStagnantEntities) { quadtree.Insert(MyNetTopologySuiteUtils.ToPointEnvelope(entity.Position2D), entity); } var positionsProvider = new VegetationSubjectsPositionsDatabase(quadtree); var runtimeManagement = new VegetationRuntimeManagement( positionsProvider: positionsProvider, vegetationSubjectsChangesListener: forgingContainerProxy, visibleEntitiesContainer: new VegetationSubjectsVisibleEntitiesContainer(), configuration: managementConfiguration); var outerVegetationRuntimeManagementProxy = new VegetationRuntimeManagementProxy(runtimeManagement); _ultraUpdatableContainer.AddUpdatableElement(new FieldBasedUltraUpdatable() { StartCameraField = (camera) => { outerVegetationRuntimeManagementProxy.StartThreading(); var position = camera.Position; outerVegetationRuntimeManagementProxy.Start(repositioner.InvMove(position)); }, UpdateCameraField = (camera) => { var position = camera.Position; outerVegetationRuntimeManagementProxy.AddUpdate(repositioner.InvMove(position)); outerVegetationRuntimeManagementProxy.SynchronicUpdate(repositioner.InvMove(position)); }, }); } MyProfiler.EndSample(); } if (_veConfiguration.GenerateBigBushes) { InitializeBushObjectsDb(baseVegetationList[VegetationLevelRank.Small], forgingContainerProxy); } }