Example #1
0
 /// <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);
 }
Example #2
0
        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);
        }
Example #3
0
        /// <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);
        }
Example #4
0
        /// <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
            });
        }
Example #5
0
 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);
 }
Example #6
0
 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));
        }
Example #8
0
        /// <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);
 }
Example #10
0
        /// <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);
        }
Example #11
0
        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);
        }
Example #12
0
        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);
        }
Example #13
0
        /// <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));
        }
Example #14
0
        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);
        }
Example #15
0
        /// <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];
        }
Example #17
0
        /// <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;
        }
Example #18
0
        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
                });
            }
        }
Example #19
0
        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]);
        }
Example #20
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);
                }
            }
        }
Example #21
0
        /// <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;
        }
Example #22
0
        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);
        }
Example #23
0
        /// <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);
        }
Example #24
0
 /// <inheritdoc />
 public void DeleteBuilding(long id, Rectangle2d rectangle)
 {
     DeleteElement(id, rectangle);
 }
Example #25
0
 public static extern bool GetClientRect(IntPtr hWnd, out Rectangle2d lpRect);
Example #26
0
 /// <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
 };
Example #27
0
 public static extern bool GetWindowRect(IntPtr hwnd, out Rectangle2d rectangle);
Example #28
0
 /// <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;
 }
Example #29
0
 /// <inheritdoc />
 public void DeleteBarrier(long id, Rectangle2d rectangle)
 {
     DeleteElement(id, rectangle);
 }