[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
Re: [pygame] Pixel perfect collision detection sugestion
I so totally agree with you!
Only problem is that I never done any C-extensions for python before. (I do
hack C...but never done it for python)
/John
>
> Hey,
>
> The reason why the numeric one will probably be faster is that it is
> all in C. Python for loops are quite slow. However if you were using
> psyco yours would be quite fast!
>
> We could translate the loop into C though, then it would be really quick
:)My vote is to use your code, but changed to do that loop in C,
> abstract the hitmask, and generate the HitMask in C without using
> numeric.
>
>
>
> Now a note onto why we should abstract your code a little more...
>
> There may be a faster way with bitsets or RLE encoding. However those
> are a bit(HAR HAR) more complicated. So if we make it a HitMask
> object, and have the functions use those, then we can implement the
> bitset/rle stuff later.
>
> Bitsets could compare up to 32 pixels at once with a SHIFT+AND, and
> RLE could do say 256 pixels at once if they were all empty/full
> pixels. This would be quite useful for lots of images, or very large
> sparse images.
>
> So it's worth abstracting the HitMask a little more now, so that we
> can upgrade to those later if anyone feels like implementing them
> without people needed to change the api.
>
>
>
>
> def _pixelPerfectCollisionDetection(sp1,sp2):
> """ Internal method used for pixel perfect collision
detection.
> Returns 1 if the hitmasks collide.
> Would probably replace this function call with just the line
> below where
> _pixelPerfectCollisionDetection is used.
> """
> return sp1.hitmask.collide(sp1.rect, sp2.hitmask, sp2.rect)
>
>
>
> # Here is an unfinished HitMask object which will be generated by C
code...class HitMask:
> # generated via a C function rather than array_colorkey.
> # very similar to:
> # pygame.surfarray.array_colorkey() or
pygame.surfarray.array_alpha()
> # except don't use numeric.
> #TODO: have to make sure that integers are 32 bits. otherwise, treat
> # differently. Perhaps use SDL functions/constants for this.
> #bitset = array.array('L',range(int(math.ceil(numpixels / 32.))))
> #eight_bits_per_pixel = array.array('B',range(numpixels))
> #rle_encoded = Surface((h,w), 8, RLEACCEL)
>
> def collide(self, rect1, other_hitmask, rect2):
> """ returns True if collision.
> NOTE: this will be done in C.
> """
> # if they are aligned we can use bitsets... if not... RLE.
> # otherwise we use the normal one.
> # note: could also use the numeric collision detection code one in
here.
>
> hm1 = self.eight_bits_per_pixel
> hm2 = other_hitmask.eight_bits_per_pixel
>
> intersect_rect = rect1.clip(rect2)
>
> x1 = intersect_rect.x-rect1.x
> y1 = intersect_rect.y-rect1.y
> x2 = intersect_rect.x-rect2.x
> y2 = intersect_rect.y-rect2.y
>
> for r in range(0,rect.height):
> for c in range(0,rect.width):
> if hm1[c+x1][r+y1] & hm2[c+x2][r+y2]:
> return 1
>
> return 1
>
>
>
> On 9/9/05, John Eriksson <john@xxxxxxxxxxxx> wrote:
> > BTW...even if you do have large images with large areas of
intersection you
> > probably still would find a hit within the first row wouldn't you?
Then the
> > nested loop wouldn't cost that much after all.
> >
> > Best Regards
> > /John
> >
> > >
> > > hmm, time flies... but seriously, you're already using Numeric
anyway,
> > > and if you replaced just the part with the nested Python loops
with a
> > > Numeric function, it would probably be much faster, especially
if you
> > > ever have large images with large areas of intersection.
> > >
> >
> >
>
>
>
>