示例#1
0
        public static Vec2 CalculateForce(Vec2 a, Vec2 b, double coulomb)
        {
            Vec2 acc = a - b;

            acc /= acc.Length();
            acc *= coulomb / (DistanceSq(a, b));
            return(acc);
        }
示例#2
0
        private unsafe void ProcessCapture()
        {
            try
            {
                Screenshot         ssht = _capture.Capture();
                Image <Gray, byte> process;

                fixed(byte *p = ssht.Data)
                {
                    IntPtr ptr = (IntPtr)p;

                    Screen = new Image <Bgra, byte>(ssht.Width, ssht.Height, ssht.Stride, ptr)
                    {
                        ROI = BOX_SIZE
                    };
                    process = Screen.Convert <Gray, byte>();
                }
                ssht.Dispose();

                _force = new Vec2();

                // Read player position from memory
                _playerPos = GetPlayerPosition();

                Rectangle powerDetectionROI = new Rectangle(
                    (int)Math.Max(_playerPos.X - 100, 0),
                    (int)Math.Max(_playerPos.Y - 75, 0),
                    (int)Math.Min(BOX_SIZE.Width - (_playerPos.X - 100), 200),
                    (int)Math.Min(BOX_SIZE.Height - (_playerPos.Y - 75), 100));
                // Look for power
                process.ROI = powerDetectionROI;

                using (Image <Gray, float> result = process.MatchTemplate(_imgPower, TemplateMatchingType.SqdiffNormed))
                {
                    double minDistSq = double.MaxValue;
                    int    minX = 0, minY = 0;
                    for (int y = 0; y < result.Height; y++)
                    {
                        for (int x = 0; x < result.Width; x++)
                        {
                            if (result.Data[y, x, 0] < 0.20)
                            {
                                double dist =
                                    (x - _playerPos.X) * (x - _playerPos.X) +
                                    (y - _playerPos.Y) * (y - _playerPos.Y);
                                if (dist < minDistSq)
                                {
                                    minDistSq = dist;
                                    minX      = x;
                                    minY      = y;
                                }
                            }
                        }
                    }
                    if (minDistSq != double.MaxValue)
                    {
                        Rectangle match = new Rectangle(minX + process.ROI.X, minY + process.ROI.Y, _imgPower.Width,
                                                        _imgPower.Height);
                        if (DO_DRAWING)
                        {
                            Screen.Draw(match, new Bgra(0, 255, 255, 255), 2);
                            Screen.Draw(new LineSegment2DF(match.Location, _playerPos), new Bgra(0, 255, 255, 255), 1);
                        }
                        Vec2 acc = Vec2.CalculateForce(
                            new Vec2(match.X + _imgPower.Width / 2.0, match.Y + _imgPower.Height / 2.0),
                            new Vec2(_playerPos.X, _playerPos.Y), 4000);
                        _force += acc;
                    }
                }

                // Processing bounding box
                Rectangle bulletDetectionROI = new Rectangle(
                    (int)Math.Max(_playerPos.X - INITIAL_DETECTION_RADIUS, 0),
                    (int)Math.Max(_playerPos.Y - INITIAL_DETECTION_RADIUS, 0),
                    (int)Math.Min(BOX_SIZE.Width - ((int)_playerPos.X - INITIAL_DETECTION_RADIUS), INITIAL_DETECTION_RADIUS * 2),
                    (int)Math.Min(BOX_SIZE.Height - ((int)_playerPos.Y - INITIAL_DETECTION_RADIUS), INITIAL_DETECTION_RADIUS * 2));
                process.ROI = bulletDetectionROI;


                if (TEST_MODE)
                {
                    return;
                }
                Vec2 _playerVec = new Vec2(_playerPos.X, _playerPos.Y);

                var binthresh = process.SmoothBlur(3, 3).ThresholdBinary(new Gray(240), new Gray(255)); //220
                // Detect blobs (bullets) on screen
                CvBlobs resultingImgBlobs = new CvBlobs();
                uint    noBlobs           = _bDetect.Detect(binthresh, resultingImgBlobs);
                int     blobCount         = 0;
                resultingImgBlobs.FilterByArea(10, 500);
                foreach (CvBlob targetBlob in resultingImgBlobs.Values)
                {
                    if (DO_DRAWING)
                    {
                        Screen.ROI = new Rectangle(process.ROI.X + BOX_SIZE.X, process.ROI.Y + BOX_SIZE.Y,
                                                   process.ROI.Width,
                                                   process.ROI.Height);
                        Screen.FillConvexPoly(targetBlob.GetContour(), new Bgra(0, 0, 255, 255));
                    }
                    // Find closest point on blob contour to player
                    Point  minPoint = targetBlob.GetContour()[0];
                    double minDist  = double.MaxValue;
                    foreach (var point in targetBlob.GetContour())
                    {
                        Point  adj  = new Point(point.X + process.ROI.X, point.Y + process.ROI.Y);
                        double dist =
                            (adj.X - _playerPos.X) * (adj.X - _playerPos.X) +
                            (adj.Y - _playerPos.Y) * (adj.Y - _playerPos.Y);

                        if (dist < minDist)
                        {
                            minPoint = adj;
                            minDist  = dist;
                        }
                    }
                    // Ensure the bullet is in the correct range
                    if (minDist < _detectionRadius * _detectionRadius)
                    {
                        // Calculate forces
                        Vec2 acc = Vec2.CalculateForce(new Vec2(minPoint.X, minPoint.Y),
                                                       _playerVec, -5000);
                        _force += acc;
                        if (DO_DRAWING)
                        {
                            Screen.ROI = BOX_SIZE;
                            Screen.Draw(new LineSegment2DF(_playerPos, minPoint), new Bgra(0, 255, 128, 255), 1);
                        }
                        blobCount++;
                    }
                }
                Screen.ROI  = BOX_SIZE;
                process.ROI = Rectangle.Empty;

                // Calculate new detection orb radius
                //float nRad = Math.Max(20.0f, INITIAL_DETECTION_RADIUS/(1 + blobCount*0.3f));
                if (blobCount >= 1)
                {
                    _detectionRadius = (_detectionRadius * 29 + 5.0f) / 30.0f;
                }
                else
                {
                    _detectionRadius = (_detectionRadius * 59 + INITIAL_DETECTION_RADIUS) / 60.0f;
                }

                // Account for border force, to prevent cornering
                //if (BOX_SIZE.Width - _playerPos.X < 120)
                _force += new Vec2(Vec2.CalculateForce(BOX_SIZE.Width - _playerPos.X, -4000), 0);
                //if (_playerPos.X < 120)
                _force += new Vec2(Vec2.CalculateForce(_playerPos.X, 4000), 0);
                if (BOX_SIZE.Height - _playerPos.Y < 50)
                {
                    _force += new Vec2(0, Vec2.CalculateForce(BOX_SIZE.Height - _playerPos.Y, -2000));
                }
                if (_playerPos.Y < 200)
                {
                    _force += new Vec2(0, Vec2.CalculateForce(_playerPos.Y, 2000));
                }
                // Corners are the devil
                _force += Vec2.CalculateForce(new Vec2(BOX_SIZE.Width, BOX_SIZE.Height),
                                              _playerVec, -2000);
                _force += Vec2.CalculateForce(new Vec2(0, BOX_SIZE.Height),
                                              _playerVec, -2000);
                _force += Vec2.CalculateForce(new Vec2(0, 0),
                                              _playerVec, -2000);
                _force += Vec2.CalculateForce(new Vec2(BOX_SIZE.Width, 0),
                                              _playerVec, -2000);

                // Assist force
                if (ShouldAssist)
                {
                    Vec2   sub  = new Vec2(AssistPoint.X, AssistPoint.Y) - _playerVec;
                    double dist = sub.Length();
                    _force += new Vec2(sub.X / dist * 2, sub.Y / dist * 2);
                }
                //imageToShow.Draw("BLOB_AREA: " + percBlob, new Point(10, 20), FontFace.HersheyPlain, 1, new Bgra(255, 255, 255, 255), 1);

                if (DO_DRAWING)
                {
                    Screen.Draw(
                        new Rectangle((int)(_playerPos.X - 3), (int)(_playerPos.Y - 3), 6, 6),
                        new Bgra(0, 255, 0, 255),
                        2);

                    Screen.Draw(new CircleF(_playerPos, _detectionRadius), new Bgra(0, 255, 255, 255), 1);
                    if (ShouldAssist)
                    {
                        Screen.Draw(
                            new LineSegment2DF(_playerPos, AssistPoint),
                            new Bgra(128, 0, 255, 255), 2);
                        Screen.Draw("ASSIST", new Point(10, 40), FontFace.HersheyPlain, 1, new Bgra(0, 255, 0, 255), 1);
                    }
                    // Draw force vector
                    Screen.Draw(
                        new LineSegment2DF(_playerPos,
                                           new PointF((float)(_playerPos.X + _force.X), (float)(_playerPos.Y + _force.Y))),
                        new Bgra(0, 128, 255, 255), 5);
                    Screen.Draw(powerDetectionROI, new Bgra(255, 255, 0, 255), 1);
                    Screen.Draw(bulletDetectionROI, new Bgra(0, 0, 255, 255), 1);
                    if (DoMovement)
                    {
                        Screen.Draw("DO_MOVEMENT", new Point(10, 20), FontFace.HersheyPlain, 1, new Bgra(0, 255, 0, 255),
                                    1);
                    }
                    _form.imageBox.Image = Screen;
                }
                process.Dispose();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }