void ComputeBoundingBox(int index)
 {
     EnsureUndisposed();
     if (bbmode != BoundingBoxMode.Automatic)
         return;
     BoundingBox bb = new BoundingBox(width - 1, height - 1, 0, 0);
     Bitmap b = frames[index];
     BitmapData bd = b.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
     for (int j = 0; j < height; j++)
     {
         for (int i = 0; i < width; i++)
         {
             int pixel = System.Runtime.InteropServices.Marshal.ReadInt32(bd.Scan0, bd.Stride * j + i * 4);
             int alpha = (int)((uint)pixel >> 24);
             if (alpha > tol)
             {
                 if (bb.Left > i) bb.Left = i;
                 if (bb.Right < i) bb.Right = i;
                 if (bb.Top > j) bb.Top = j;
                 if (bb.Bottom < j) bb.Bottom = j;
             }
         }
     }
     b.UnlockBits(bd);
     if (index >= bboxes.Count)
     {
         while (index >= bboxes.Count)
             bboxes.Add(index == bboxes.Count ? bb : new BoundingBox());
     }
     else
         bboxes[index] = bb;
 }
Ejemplo n.º 2
0
        public System.Collections.BitArray CollisionMask(int framenum)
        {
            EnsureUndisposed();
            if (framenum >= frames.Count)
            {
                return(null);
            }
            if (!separatemasks)
            {
                framenum = 0;
            }
            BoundingBox bb = GetBoundingBox(framenum);

            if (bb.Left > bb.Right || bb.Top > bb.Bottom)
            {
                return(null);
            }
            bb.Normalize();
            int w = bb.Right - bb.Left + 1;
            int h = bb.Bottom - bb.Top + 1;

            System.Collections.BitArray mask = new System.Collections.BitArray(w * h);
            switch (bbshape)
            {
            case BoundingBoxShape.Rectangle:
                // The mask is a rectangle.
                mask.SetAll(true);
                break;

            case BoundingBoxShape.Diamond:
            case BoundingBoxShape.Disk:
                // Use a lambda function for the shape: a disk or a diamond.
                Func <double, double, bool> ftn =
                    bbshape == BoundingBoxShape.Disk ?
                    (Func <double, double, bool>)((double x, double y) => (x * x + y * y < 1.0)) :
                    (Func <double, double, bool>)((double x, double y) => (Math.Abs(x) + Math.Abs(y) < 1.0));

                // Fill in the mask fitting the coordinates into the lambda function for the shape.
                //GM8 BETA1/2/RC1 incorrect version (off-by-one and excessive rounding):
                //int scalex = (bb.Right - bb.Left) >> 1;
                //int scaley = (bb.Bottom - bb.Top) >> 1;
                //for (int j = 0; j < h; j++)
                //    for (int i = 0; i < w; i++)
                //        mask[j * w + i] = ftn((double)(i - scalex) / (double)scalex, (double)(j - scaley) / (double)scaley);
                // correct code:
                double scalex = (double)(bb.Right - bb.Left + 1) * 0.5;
                double scaley = (double)(bb.Bottom - bb.Top + 1) * 0.5;
                for (int j = 0; j < h; j++)
                {
                    for (int i = 0; i < w; i++)
                    {
                        mask[j * w + i] = ftn((double)(i - scalex) / scalex, (double)(j - scaley) / scaley);
                    }
                }
                break;

            default:
                // Generate a mask based on alpha tolerance on each pixel.
                Bitmap     b  = frames[framenum];
                BitmapData bd = b.LockBits(new Rectangle(bb.Left, bb.Top, w, h), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
                for (int j = 0; j < h; j++)
                {
                    for (int i = 0; i < w; i++)
                    {
                        mask[j * w + i] = (int)((uint)System.Runtime.InteropServices.Marshal.ReadInt32(bd.Scan0, (j + bb.Top) * bd.Stride + (i + bb.Left) * 4) >> 24) > tol;
                    }
                }
                b.UnlockBits(bd);
                break;
            }
            return(mask);
        }
 public void SetBoundingBox(BoundingBox bbox)
 {
     EnsureUndisposed();
     bbmode = BoundingBoxMode.Manual;
     bboxes[0] = bbox;
 }
Ejemplo n.º 4
0
 public void SetBoundingBox(BoundingBox bbox)
 {
     EnsureUndisposed();
     bbmode    = BoundingBoxMode.Manual;
     bboxes[0] = bbox;
 }