/// <summary> Sets rendering mode. </summary> /// <param name="renderMode">Render mode.</param> /// <param name="viewport"> Viewport in world coordinates (meters).</param> public ConfigBuilder SetRenderOptions(RenderMode renderMode, Rectangle2d viewport) { Add <string>(@"tile/render_mode", renderMode.ToString().ToLower()); Add <float>(@"tile/viewport/w", (float)viewport.Width); Add <float>(@"tile/viewport/h", (float)viewport.Height); return(this); }
private List <Point> GetVertices(Path path, RenderMode renderMode, ref Rectangle2d rect) { // do not split path for overview mode var points = _objectPool.NewList <Point>(path.Count); bool isOverview = renderMode == RenderMode.Overview; // split path for scene mode var lastItemIndex = path.Count - 1; for (int i = 0; i <= lastItemIndex; i++) { var start = path[i]; var end = path[i == lastItemIndex ? 0 : i + 1]; var p1 = new Point(Math.Round(start.X / Scale, MathUtils.RoundDigitCount), Math.Round(start.Y / Scale, MathUtils.RoundDigitCount)); var p2 = new Point(Math.Round(end.X / Scale, MathUtils.RoundDigitCount), Math.Round(end.Y / Scale, MathUtils.RoundDigitCount)); if (isOverview && (!rect.IsOnBorder(new Vector2d(p1.X, p1.Y)) || !rect.IsOnBorder(new Vector2d(p2.X, p2.Y)))) { points.Add(p1); continue; } _lineGridSplitter.Split(p1, p2, _objectPool, points); } return(points); }
/// <summary> /// Query the QuadTree for all points contained in this range. /// </summary> /// <param name="range">Range to look for.</param> /// <returns>Points contained in the range.</returns> public List <Point2d> QueryRange(Rectangle2d range) { var pointsInRange = new List <Point2d>(); if (!this.Boundary.IntersectsBox(range)) { return(pointsInRange); } this.Points.ForEach( pt => { if (range.ContainsPoint(pt)) { pointsInRange.Add(pt); } }); // If we reached threshold return if (this.Boundary.XDomain.Length < this.threshold || this.Boundary.YDomain.Length < this.threshold) { return(pointsInRange); } if (this.southWest != null) { pointsInRange.AddRange(this.southWest.QueryRange(range)); pointsInRange.AddRange(this.southEast.QueryRange(range)); pointsInRange.AddRange(this.northWest.QueryRange(range)); pointsInRange.AddRange(this.northEast.QueryRange(range)); } return(pointsInRange); }
/// <summary> Builds mesh cell. </summary> public MeshCell Build(MeshCanvas content, Rectangle2d rectangle) { var renderMode = content.RenderMode; var clipRect = new Path { new IntPoint(rectangle.Left * Scale, rectangle.Bottom * Scale), new IntPoint(rectangle.Right * Scale, rectangle.Bottom * Scale), new IntPoint(rectangle.Right * Scale, rectangle.Top * Scale), new IntPoint(rectangle.Left * Scale, rectangle.Top * Scale) }; var useContours = renderMode == RenderMode.Scene; // NOTE the order of operation is important var water = CreateMeshRegions(clipRect, content.Water, renderMode, ref rectangle, useContours); var resultCarRoads = CreateMeshRegions(clipRect, content.CarRoads, renderMode, ref rectangle, useContours); var resultWalkRoads = CreateMeshRegions(clipRect, content.WalkRoads, renderMode, ref rectangle); var resultSurface = CreateMeshRegions(clipRect, content.Surfaces, renderMode, ref rectangle); var background = CreateMeshRegions(clipRect, content.Background, renderMode, ref rectangle); return(new MeshCell { Water = water, CarRoads = resultCarRoads, WalkRoads = resultWalkRoads, Surfaces = resultSurface, Background = background, Rectangle = rectangle }); }
private void SerializeRectangle(IDataBlock block, Rectangle2d rect) { block.Writer.Write(rect.Top); block.Writer.Write(rect.Left); block.Writer.Write(rect.Bottom); block.Writer.Write(rect.Right); }
public static void Write(this BinaryWriter writer, Rectangle2d value, EndianFormat format = EndianFormat.LittleEndian) { writer.Write(value.Top, format); writer.Write(value.Left, format); writer.Write(value.Bottom, format); writer.Write(value.Right, format); }
/// <inheritdoc /> public MeshQuery.Result Modify(MeshQuery query) { var result = new List <int>(4); var center = query.Epicenter; var x = (int)Math.Floor((center.x - _left) / _xAxisStep); var y = (int)Math.Floor((center.z - _bottom) / _yAxisStep); var center2d = new Vector2d(center.x, center.z); for (int j = y - 1; j <= y + 1; j++) { for (int i = x - 1; i <= x + 1; i++) { var rectangle = new Rectangle2d( _bottomLeft.X + i * _xAxisStep, _bottomLeft.Y + j * _yAxisStep, _xAxisStep, _yAxisStep); // NOTE enlarge search radius to prevent some issues with adjusted triangles // as their position in index defined by their centroid // actually, additional size depends on terrain triangle area if (GeometryUtils.HasCollision(center2d, query.Radius + 6, rectangle)) { AddRange(i, j, result); } } } return(ModifyVertices(query, result)); }
/// <summary> /// Project a point from srcScreen to targetScreen. /// </summary> /// <param name="src"></param> /// <param name="srcScreen"></param> /// <param name="targetScreen"></param> /// <param name="scaling">Calculate point by screen scale, otherwise, convert the right offset and bottom offset only</param> /// <returns></returns> public static Point2d ProjectToScreen(this Point2d src, Rectangle2d srcScreen, Rectangle2d targetScreen, bool scaling = false) { if (scaling) { float xRatio = srcScreen.Width / (float)targetScreen.Width; float yRatio = srcScreen.Height / (float)targetScreen.Height; return(new Point2d() { X = (int)Math.Round(src.X / xRatio), Y = (int)Math.Round(src.Y / yRatio) }); } var x = src.X; var y = src.Y; if (x > targetScreen.Right) { x = targetScreen.Right - (srcScreen.Right - x); } if (y > targetScreen.Bottom) { y = targetScreen.Bottom - (srcScreen.Bottom - y); } return(new Point2d() { X = x, Y = y }); }
public static void Write(this BinaryWriter writer, Rectangle2d rect) { // Write a Rectangle2d object to the stream. writer.Write(rect.top); writer.Write(rect.left); writer.Write(rect.bottom); writer.Write(rect.right); }
/// <summary> Deletes way from element source. </summary> private void DeleteElement(long id, Rectangle2d rectangle) { EnsureElementSource(rectangle.BottomLeft); var nullPoint = _tileController.CurrentTile.RelativeNullPoint; var boundingBox = new BoundingBox( GeoProjection.ToGeoCoordinate(nullPoint, rectangle.BottomLeft), GeoProjection.ToGeoCoordinate(nullPoint, rectangle.TopRight)); _elementSourceEditor.Delete <Way>(id, boundingBox); }
private List <MeshRegion> CreateMeshRegions(Path clipRect, List <MeshCanvas.Region> regionDatas, RenderMode renderMode, ref Rectangle2d rect) { var meshRegions = new List <MeshRegion>(); foreach (var regionData in regionDatas) { meshRegions.Add(CreateMeshRegions(clipRect, regionData, renderMode, ref rect)); } return(meshRegions); }
public static Rectangle2d ReadRectangle2d(this BinaryReader reader) { // Read a Rectangle2d object from the stream. Rectangle2d rect = new Rectangle2d(); rect.top = reader.ReadInt16(); rect.left = reader.ReadInt16(); rect.bottom = reader.ReadInt16(); rect.right = reader.ReadInt16(); return(rect); }
/// <summary> Checks collision between circle and rectangle. </summary> public static bool HasCollision(Vector2d circle, float radius, Rectangle2d rectangle) { var closestX = MathUtils.Clamp(circle.X, rectangle.Left, rectangle.Right); var closestY = MathUtils.Clamp(circle.Y, rectangle.Bottom, rectangle.Top); // Calculate the distance between the circle's center and this closest point var distanceX = circle.X - closestX; var distanceY = circle.Y - closestY; // If the distance is less than the circle's radius, an intersection occurs var distanceSquared = (distanceX * distanceX) + (distanceY * distanceY); return(distanceSquared < (radius * radius)); }
public IGameObject Build(Tile tile, Rule rule) { Trace.Debug(LogTag, "Started to build terrain"); var sw = new System.Diagnostics.Stopwatch(); sw.Start(); var renderMode = tile.RenderMode; var terrainObject = _gameObjectFactory.CreateNew("terrain", tile.GameObject); // NOTE detect grid parameters for scene mode. For overview use 1x1 grid var cellRowCount = renderMode == RenderMode.Scene ? (int)Math.Ceiling(tile.Rectangle.Height / _maxCellSize) : 1; var cellColumnCount = renderMode == RenderMode.Scene ? (int)Math.Ceiling(tile.Rectangle.Width / _maxCellSize) : 1; var cellHeight = tile.Rectangle.Height / cellRowCount; var cellWidth = tile.Rectangle.Width / cellColumnCount; Trace.Debug(LogTag, "Building mesh canvas.."); var meshCanvas = new MeshCanvasBuilder(_objectPool) .SetTile(tile) .SetScale(MeshCellBuilder.Scale) .Build(renderMode); Trace.Debug(LogTag, "Building mesh cells.."); // NOTE keeping this code single threaded dramatically reduces memory presure for (int j = 0; j < cellRowCount; j++) { for (int i = 0; i < cellColumnCount; i++) { var tileBottomLeft = tile.Rectangle.BottomLeft; var rectangle = new Rectangle2d( tileBottomLeft.X + i * cellWidth, tileBottomLeft.Y + j * cellHeight, cellWidth, cellHeight); var name = String.Format("cell {0}_{1}", i, j); var cell = _meshCellBuilder.Build(meshCanvas, rectangle); BuildCell(tile.Canvas, rule, terrainObject, cell, renderMode, name); } } terrainObject.IsBehaviourAttached = true; sw.Stop(); Trace.Debug(LogTag, "Terrain is build in {0}ms", sw.ElapsedMilliseconds.ToString()); return(terrainObject); }
/// <summary> Creates tile. </summary> /// <param name="relativeNullPoint">Relative null point.</param> /// <param name="mapCenter">Center of map.</param> /// <param name="renderMode">Render mode.</param> /// <param name="canvas">Map canvas.</param> /// <param name="width">Tile width in meters.</param> /// <param name="height">Tile height in meters.</param> public Tile(GeoCoordinate relativeNullPoint, Vector2d mapCenter, RenderMode renderMode, Canvas canvas, double width, double height) { RelativeNullPoint = relativeNullPoint; MapCenter = mapCenter; RenderMode = renderMode; Canvas = canvas; var geoCenter = GeoProjection.ToGeoCoordinate(relativeNullPoint, mapCenter); BoundingBox = BoundingBox.Create(geoCenter, width, height); Rectangle = new Rectangle2d(MapCenter.X - width / 2, MapCenter.Y - height / 2, width, height); Registry = new TileRegistry(renderMode); }
/// <summary> Creates instance of <see cref="TerrainMeshIndex"/>. </summary> /// <param name="columnCount">Column count of given bounding box.</param> /// <param name="rowCount">Row count of given bounding box.</param> /// <param name="boundingBox">Bounding box.</param> /// <param name="triangles">Triangles</param> public TerrainMeshIndex(int columnCount, int rowCount, Rectangle2d boundingBox, List <TerrainMeshTriangle> triangles) { _columnCount = columnCount; _rowCount = rowCount; _triangles = triangles; _left = boundingBox.Left; _bottom = boundingBox.Bottom; _bottomLeft = boundingBox.BottomLeft; _xAxisStep = boundingBox.Width / columnCount; _yAxisStep = boundingBox.Height / rowCount; _ranges = new Range[rowCount * columnCount]; }
/// <summary> Process unity specific data. </summary> private void BuildObject(Tile tile, IGameObject gameObjectWrapper, Rule rule, Rectangle2d rect, Vector2d point, float minHeight) { var gameObject = gameObjectWrapper.AddComponent(GameObject.CreatePrimitive(PrimitiveType.Cube)); var transform = gameObject.transform; var elevation = ElevationProvider.GetElevation(point); transform.position = new Vector3((float)point.X, elevation + minHeight, (float)point.Y); // TODO define size transform.localScale = new Vector3(2, 2, 2); var p0 = new Vector2((float)rect.Left, (float)rect.Bottom); var p1 = new Vector2((float)rect.Right, (float)rect.Bottom); var p2 = new Vector2((float)rect.Left, (float)rect.Top); var p3 = new Vector2((float)rect.Right, (float)rect.Top); var mesh = gameObject.GetComponent <MeshFilter>().mesh; // Imagine looking at the front of the cube, the first 4 vertices are arranged like so // 2 --- 3 // | | // | | // 0 --- 1 // then the UV's are mapped as follows // 2 3 0 1 Front // 6 7 10 11 Back // 19 17 16 18 Left // 23 21 20 22 Right // 4 5 8 9 Top // 15 13 12 14 Bottom mesh.uv = new[] { p0, p1, p2, p3, p2, p3, p2, p3, p0, p1, p0, p1, p0, p3, p1, p2, p0, p3, p1, p2, p0, p3, p1, p2 }; gameObject.GetComponent <MeshRenderer>().sharedMaterial = rule.GetMaterial(CustomizationService); gameObjectWrapper.Parent = tile.GameObject; }
private MeshRegion CreateMeshRegions(Path clipRect, MeshCanvas.Region region, RenderMode renderMode, ref Rectangle2d rect, bool useContours = false) { using (var polygon = new Polygon(256, _objectPool)) { var simplifiedPath = ClipByRectangle(clipRect, region.Shape); var contours = new List <List <Point> >(useContours ? simplifiedPath.Count : 0); foreach (var path in simplifiedPath) { var area = Clipper.Area(path); // skip small polygons to prevent triangulation issues if (Math.Abs(area / DoubleScale) < 0.001) { continue; } var vertices = GetVertices(path, renderMode, ref rect); // sign of area defines polygon orientation polygon.AddContour(vertices, area < 0); if (useContours) { contours.Add(vertices); } } contours.ForEach(c => c.Reverse()); var mesh = polygon.Points.Any() ? GetMesh(polygon, renderMode) : null; return(new MeshRegion { GradientKey = region.GradientKey, ElevationNoiseFreq = region.ElevationNoiseFreq, ColorNoiseFreq = region.ColorNoiseFreq, ModifyMeshAction = region.ModifyMeshAction, Mesh = mesh, Contours = contours }); } }
public void CanCreate_QuadTree() { var range = new Rectangle2d( Point2d.Origin, new Point2d(1, 1) ); var tree = new QuadTree(range, .26); var pt = new Point2d(0.35, 0.35); var low = new Point2d(0.3, 0.3); var high = new Point2d(0.4, 0.4); var check = tree.Insert(pt); Assert.True(check); var expected = tree.QueryRange( new Rectangle2d(low, high) ); Assert.Equal(pt, expected[0]); }
private void BuildOffsetShape(TerrainMeshData meshData, MeshRegion region, GradientWrapper gradient, Rectangle2d rect, float colorNoiseFreq, float deepLevel) { foreach (var contour in region.Contours) { var length = contour.Count; for (int i = 0; i < length; i++) { var v2DIndex = i == (length - 1) ? 0 : i + 1; var p1 = new Vector2d((float)contour[i].X, (float)contour[i].Y); var p2 = new Vector2d((float)contour[v2DIndex].X, (float)contour[v2DIndex].Y); // check whether two points are on cell rect if (rect.IsOnBorder(p1) && rect.IsOnBorder(p2)) { continue; } var ele1 = _elevationProvider.GetElevation(p1); var ele2 = _elevationProvider.GetElevation(p2); var firstColor = GradientUtils.GetColor(gradient, new Vector3((float)p1.X, ele1, (float)p1.Y), colorNoiseFreq); var secondColor = GradientUtils.GetColor(gradient, new Vector3((float)p2.X, ele1 - deepLevel, (float)p2.Y), colorNoiseFreq); meshData.AddTriangle( new Vector3((float)p1.X, ele1, (float)p1.Y), new Vector3((float)p2.X, ele2 - deepLevel, (float)p2.Y), new Vector3((float)p2.X, ele2, (float)p2.Y), firstColor); meshData.AddTriangle( new Vector3((float)p1.X, ele1 - deepLevel, (float)p1.Y), new Vector3((float)p2.X, ele2 - deepLevel, (float)p2.Y), new Vector3((float)p1.X, ele1, (float)p1.Y), secondColor); } } }
/// <inheritdoc /> public void Configure(IConfigSection configSection) { _tileSize = configSection.GetFloat("size", 500); _offset = configSection.GetFloat("offset", 50); _moveSensitivity = configSection.GetFloat("sensitivity", 10); var renderModeString = configSection.GetString("render_mode", "scene").ToLower(); _renderMode = renderModeString == "scene" ? RenderMode.Scene : RenderMode.Overview; var viewportConfig = configSection.GetSection("viewport"); var width = viewportConfig != null?viewportConfig.GetFloat("w", 0) : 0; var height = viewportConfig != null?viewportConfig.GetFloat("h", 0) : 0; _viewport = new Rectangle2d(0, 0, width, height); RecalculateOverviewTileCount(); _thresholdDistance = Math.Sqrt(2) * _tileSize; }
public void SetFieldValue(object owner, object value = null, object definition = null) { if (Loading || owner == null) { return; } if (value == null) { if (!short.TryParse(topTextBox.Text, out var top) || !short.TryParse(leftTextBox.Text, out var left) || !short.TryParse(bottomTextBox.Text, out var bottom) || !short.TryParse(rightTextBox.Text, out var right)) { return; } value = new Rectangle2d(top, left, bottom, right); } Field.SetValue(owner, value); }
/// <inheritdoc /> public override IGameObject BuildNode(Tile tile, Rule rule, Node node) { var poinr = GeoProjection.ToMapCoordinate(tile.RelativeNullPoint, node.Point); if (!tile.Contains(poinr, 0)) { return(null); } var uvRectStr = rule.Evaluate <string>("rect"); var width = (int)rule.GetWidth(); var height = (int)rule.GetHeight(); Rectangle2d rect = GetUvRect(uvRectStr, new Size(width, height)); var gameObjectWrapper = GameObjectFactory.CreateNew(GetName(node)); var minHeight = rule.GetMinHeight(); Observable.Start(() => BuildObject(tile, gameObjectWrapper, rule, rect, poinr, minHeight), Scheduler.MainThread); return(gameObjectWrapper); }
/// <inheritdoc /> public void DeleteBuilding(long id, Rectangle2d rectangle) { DeleteElement(id, rectangle); }
public static extern bool GetClientRect(IntPtr hWnd, out Rectangle2d lpRect);
/// <summary> /// Map point to specific screen /// </summary> /// <param name="src"></param> /// <param name="screenRect"></param> /// <returns></returns> public static Point2d MapToScreen(this Point2d src, Rectangle2d screenRect) => new Point2d() { X = src.X + screenRect.Left, Y = src.Y + screenRect.Top };
public static extern bool GetWindowRect(IntPtr hwnd, out Rectangle2d rectangle);
/// <summary> /// Initializes a new instance of the <see cref="QuadTree" /> class. /// </summary> /// <param name="boundary">Boundary of this QuadTree.</param> /// <param name="threshold">Smallest allowed dimension.</param> public QuadTree(Rectangle2d boundary, double threshold) { this.Boundary = boundary; this.Points = new List <Point2d>(); this.threshold = threshold; }
/// <inheritdoc /> public void DeleteBarrier(long id, Rectangle2d rectangle) { DeleteElement(id, rectangle); }