private static byte[] ConvertSocketPointsToBytes(SimplePoint[] points)
 {
     var pointBytes = new List<byte>(points.Length * 4);
     foreach (var point in points)
     {
         pointBytes.AddRange(BitConverter.GetBytes(point.X));
         pointBytes.AddRange(BitConverter.GetBytes(point.Y));
     }
     return pointBytes.ToArray();
 }
 public CenterMapSocketObject(SimplePoint centerMap)
     : base(SocketConstants.SocketAction.CenterMap)
 {
     CenterMap = centerMap;
 }
 private void connection_OnCenterMapReceived(SimplePoint centerMap)
 {
     // Take the point that we want to show, and center it on the client's UI.
     SetScroll(centerMap.X - this.Width / 2, centerMap.Y - this.Height / 2);
 }
Exemple #4
0
 public void Add(SimplePoint point)
 {
     _points.AddLast(point);
 }
Exemple #5
0
 public virtual void SetCenterMap(SimplePoint centerMap)
 {
     this.SetCenterMap(centerMap, false);
 }
Exemple #6
0
        protected void SetCenterMap(SimplePoint centerMap, bool animate)
        {
            // Take the point that we want to show, and center it on the client's UI.
            this.BeginInvoke(new Action(() =>
            {
                // The point that came in is raw on the map...
                var x = centerMap.X;
                var y = centerMap.Y;

                // We also need to account for the client's zoom factor (gives us the X/Y of a Zoomed map), to which we then "unzoom" the X/Y back to the raw map location for scroll purposes.
                x = (int)(((x * AssignedZoomFactor) - (this.VisibleSize.Width / 2.0d)) * this.InverseZoomFactor);
                y = (int)(((y * AssignedZoomFactor) - (this.VisibleSize.Height / 2.0d)) * this.InverseZoomFactor);

                if (!animate)
                {
                    SetScroll(x, y);
                    return;
                }

                // If we're already doing a Center Map fade, we're going to simply pop out the old values. It may glitch a bit to the end user, but the end result will be fine.
                // Our timer will go from True/0.0 to True/1.0, then flip to False/1.0 down to False/0.0
                this.centerMapFadingTimer.Tag = new SimplePoint(x, y);
                this.centerMapFadingValues = new Tuple<bool, float>(true, 0.0f);
                this.centerMapFadingTimer.Start();
            }));
        }
        public void WriteCenterMap(SimplePoint point)
        {
            if (ClientsCount == 0)
                return;

            EnqueueWrite(new CenterMapSocketObject(point));
        }
 private void ctlMiniMap_OnNewCenterMap(SimplePoint centerMap)
 {
     this.DnDMapControl.SetCenterMap(centerMap);
 }
Exemple #9
0
        //Compute the distance from AB to C
        //if isSegment is true, AB is a segment, not a line.
        private static double LineToPointDistance2D(SimplePoint linePoint1, SimplePoint linePoint2, SimplePoint pointTest, bool isSegment = true)
        {
            if (linePoint1.X == linePoint1.X && linePoint1.Y == linePoint2.Y)
                return 255;

            var pointA = new double[] { linePoint1.X, linePoint1.Y };
            var pointB = new double[] { linePoint2.X, linePoint2.Y };
            var pointC = new double[] { pointTest.X, pointTest.Y };
            double dist = CrossProduct(pointA, pointB, pointC) / Distance(pointA, pointB);
            if (isSegment)
            {
                double dot1 = DotProduct(pointA, pointB, pointC);
                if (dot1 > 0)
                    return Distance(pointB, pointC);

                double dot2 = DotProduct(pointB, pointA, pointC);
                if (dot2 > 0)
                    return Distance(pointA, pointC);
            }

            return Math.Abs(dist);
        }
Exemple #10
0
        private static unsafe bool ApplyFog(Bitmap fog, int delta, params FogUpdate[] fogUpdates)
        {
            if (fog == null || fogUpdates == null || !fogUpdates.Any())
                return false;

            var isInwards = (delta < 0);

            var anyComplete = false;

            // TODO: Look into a better way to handle multiple fog updates at the same time?
            foreach (var fogUpdate in fogUpdates)
            {
                var points = fogUpdate.Points;
                var isAddingFog = !fogUpdate.IsClearing;

                var pointPolygon = new List<IntPoint>(points.Select(x => new IntPoint(x.X, x.Y)));
                var pointPolygons = new List<List<IntPoint>>() { pointPolygon };
                var offsetPolygons = Clipper.OffsetPolygons(pointPolygons, delta, JoinType.jtRound);

                // If our offset was simply too large to have an offset polygon, we'll change it (towards 0)
                // until we find one. If we never do, we'll just do direct drawing as the shape is too small for alpha fading.
                var retryDelta = delta;
                if (isInwards)
                {
                    // Inwards means the delta is negative (to make the fog go inwards), so we'll add to it to get it to -1.
                    while (offsetPolygons.Count == 0 && retryDelta != -1)
                    {
                        // The last iteration will end up with retryDelta set to 1, which will cause the smallest offset polygon to be generated.
                        retryDelta = Math.Min(-1, retryDelta + DnDMapConstants.FogAlphaEffectRetryDelta);
                        offsetPolygons = Clipper.OffsetPolygons(pointPolygons, retryDelta, JoinType.jtRound);
                    }
                }

                // If we still don't have any offset polygon, then the size must just be too small so we'll draw it using the direct method instead.
                if (offsetPolygons.Count == 0)
                {
                    anyComplete |= ApplyFogDirect(fog, fogUpdates);
                    continue;
                }

                var offsetPoints = offsetPolygons[0].Select(x => new SimplePoint((int)x.X, (int)x.Y)).ToArray();

                // When we're doing inwards delta, the offsetPoints shape is smaller than the points shape.
                // Therefore, we'll flip the variables to pretend that the user drew the smaller shape.
                if (isInwards)
                {
                    var p = points;
                    points = offsetPoints;
                    offsetPoints = p;
                }

                var boundingBoxBuffered = GetBoundingBox(fog, offsetPoints, 4);
                var boundingBox = GetBoundingBox(fog, points, 0);

                var bmd = fog.LockBits(boundingBoxBuffered, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
                int pixelSize = 4;
                Parallel.For(0, bmd.Height, (y) =>
                {
                    var row = (byte*)bmd.Scan0 + (y * bmd.Stride);
                    for (var x = 0; x < bmd.Width; x++)
                    {
                        var offsetX = x + boundingBoxBuffered.X;
                        var offsetY = y + boundingBoxBuffered.Y;

                        if (isAddingFog)
                        {
                            // If the pixel is already opaque, then we'll skip it
                            if (row[x * pixelSize + 3] == 255)
                                continue;
                        }
                        else
                        {
                            // If the pixel is already transparent, then we'll hide it
                            if (row[x * pixelSize + 3] == 0)
                                continue;
                        }

                        // When going outwards, we reveal everything in the points (the actual drawn polygon)
                        //                      we partially reveal anything in the offset polygons
                        // When going inwards, we reveal anythign in the offset points (an inner polygon)
                        //                      we partially reveal anything in the actual polygon
                        // This is handled by flipping the points and offsetPoints variables above.
                        if (IsPointInPolygon(points, offsetX, offsetY))
                        {
                            row[x * pixelSize + 3] = (byte)(isAddingFog ? 255 : 0);
                        }
                        else if (IsPointInPolygon(offsetPoints, offsetX, offsetY))
                        {
                            var testPoint = new SimplePoint(offsetX, offsetY);
                            var dist = LineToPointDistance2D(points[0], points[1], testPoint);
                            for (int i = 0, j = points.Length - 1; i < points.Length; j = i++)
                            {
                                var newDist = LineToPointDistance2D(points[j], points[i], testPoint);
                                if (newDist < dist)
                                    dist = newDist;
                            }

                            var alpha = (255 - 5.5 * dist);
                            alpha = Math.Max(Math.Floor(alpha), 0);
                            if (isAddingFog)
                                alpha = Math.Min(alpha + row[x * pixelSize + 3], 255);
                            else
                                alpha = Math.Max(row[x * pixelSize + 3] - alpha, 0);
                            row[x * pixelSize + 3] = (byte)(alpha);
                        }
                    }
                });

                fog.UnlockBits(bmd);
                anyComplete = true;
            }

            return anyComplete;
        }
Exemple #11
0
        private static bool IsPointInPolygon(SimplePoint[] polygon, float testx, float testy)
        {
            int nvert = polygon.Length;
            var vertx = polygon.Select(x => (float)(x.X)).ToArray();
            var verty = polygon.Select(x => (float)(x.Y)).ToArray();

            int i, j = 0;
            bool c = false;
            for (i = 0, j = nvert - 1; i < nvert; j = i++)
            {
                if (((verty[i] > testy) != (verty[j] > testy)) &&
                 (testx < (vertx[j] - vertx[i]) * (testy - verty[i]) / (verty[j] - verty[i]) + vertx[i]))
                    c = !c;
            }
            return c;
        }
Exemple #12
0
        private static Rectangle GetBoundingBox(Image fog, SimplePoint[] points, int buffer = 8)
        {
            if (points.Length == 0)
            {
                return new Rectangle(0, 0, 0, 0);
            }

            var left = points[0].X;
            var right = points[0].X;
            var top = points[0].Y;
            var bottom = points[0].Y;
            foreach (var point in points)
            {
                if (point.X < left)
                    left = point.X;
                if (point.X > right)
                    right = point.X;
                if (point.Y < top)
                    top = point.Y;
                if (point.Y > bottom)
                    bottom = point.Y;
            }

            var rect = new Rectangle(left, top, right - left, bottom - top);
            rect.X = Math.Max(0, rect.X - buffer);
            rect.Y = Math.Max(0, rect.Y - buffer);
            rect.Width = Math.Min(fog.Width - rect.X, rect.Width + buffer);
            rect.Height = Math.Min(fog.Height - rect.Y, rect.Height + buffer);
            return rect;
        }
Exemple #13
0
 public void Add(SimplePoint point)
 {
     _points.AddLast(point);
 }
 public CenterMapSocketObject(SimplePoint centerMap)
     : base(SocketConstants.SocketAction.CenterMap)
 {
     CenterMap = centerMap;
 }
Exemple #15
0
 private void ctlDnDMap_PerformCenterMap(SimplePoint centerMap)
 {
     connection.WriteCenterMap(centerMap);
 }
 public override void SetCenterMap(SimplePoint centerMap)
 {
     base.SetCenterMap(centerMap, true);
 }
Exemple #17
0
 private void connection_OnCenterMapReceived(SimplePoint centerMap)
 {
     this.ctlDnDMap.SetCenterMap(centerMap);
 }