Re: [pygame] extending pygame masks
Nirav Patel wrote: Sorry about the very long delay on this, but I finally committed Mike's convolve function and tests as revision 1796. Nirav Thanks! --Mike
Re: [pygame] extending pygame masks
It was just that, line endings. I took care of it so no one else will be caught by surprise. Lenard Lenard Lindstrom wrote: Hi, Possibly just carriage returns. I will see what happens when I run makeref.py on a fresh checkout. Lenard Nirav Patel wrote: Lenard, I didn't make any changes, and the diffs show no changes, but for some reason, they were included in the commit anyway. Nirav On Sun, Jan 4, 2009 at 5:41 PM, Lenard Lindstrom wrote: Hi Nirav, Did you make changes to locals.html, camera.html, index.html, color.html and pixelarray.html? I ask because I almost clobbered them when I ran makeref.py after applying a patch to src\music.doc. -- Lenard Lindstrom
Re: [pygame] extending pygame masks
Hi, Possibly just carriage returns. I will see what happens when I run makeref.py on a fresh checkout. Lenard Nirav Patel wrote: Lenard, I didn't make any changes, and the diffs show no changes, but for some reason, they were included in the commit anyway. Nirav On Sun, Jan 4, 2009 at 5:41 PM, Lenard Lindstrom wrote: Hi Nirav, Did you make changes to locals.html, camera.html, index.html, color.html and pixelarray.html? I ask because I almost clobbered them when I ran makeref.py after applying a patch to src\music.doc. Lenard Nirav Patel wrote: Sorry about the very long delay on this, but I finally committed Mike's convolve function and tests as revision 1796. Nirav -- Lenard Lindstrom -- Lenard Lindstrom
Re: [pygame] extending pygame masks
Lenard, I didn't make any changes, and the diffs show no changes, but for some reason, they were included in the commit anyway. Nirav On Sun, Jan 4, 2009 at 5:41 PM, Lenard Lindstrom wrote: > Hi Nirav, > > Did you make changes to locals.html, camera.html, index.html, color.html and > pixelarray.html? I ask because I almost clobbered them when I ran makeref.py > after applying a patch to src\music.doc. > > Lenard > > Nirav Patel wrote: >> >> Sorry about the very long delay on this, but I finally committed Mike's >> convolve function and tests as revision 1796. >> >> Nirav >> > -- > Lenard Lindstrom > > >
Re: [pygame] extending pygame masks
Hi Nirav, Did you make changes to locals.html, camera.html, index.html, color.html and pixelarray.html? I ask because I almost clobbered them when I ran makeref.py after applying a patch to src\music.doc. Lenard Nirav Patel wrote: Sorry about the very long delay on this, but I finally committed Mike's convolve function and tests as revision 1796. Nirav -- Lenard Lindstrom
Re: [pygame] extending pygame masks
Sorry about the very long delay on this, but I finally committed Mike's convolve function and tests as revision 1796. Nirav On Fri, Oct 17, 2008 at 10:25 PM, Michael George wrote: > Here are the files. It turns out the actual convolution is much simpler > than the one I sent out before, since I learned about the bitmask_draw > method and just use that internally. It might be slightly slower, but it's > more likely to be correct. > > As I was coding it up, I realized I'm still not completely happy with the > interface. Which of the following two possibilities do people prefer? > > == Option 1 == > Mask.convolve(othermask, outputmask = None, offset = (0,0)): return Mask > > Returns a mask with the (i-offset[0],j-offset[1]) bit set if shifting > othermask > so that it's lower right corner pixel is at (i,j) would cause it to overlap > with self. > > If outputmask is not None, then the output is drawn onto outputmask and > outputmask is returned. Otherwise a mask of size self.get_size() + > othermask.get_size() - (1,1) is created. > > == Option 2 == > Mask.convolve(othermask, outputmask, offset = (0,0)): return Mask > Sets the ((i, j) - offset) bit of outputmask if overlap(self, othermask, > (i,j)) is true. Returns outputmask. > > Mask.convolve(othermask): return Mask > Creates a mask just big enough to hold the convolution of self and other, > and shifts the output so that it fits in the mask. Equivalent to > self.convolve(other, Mask(self.get_size() + othermask.get_size() - (1,1)), > othermask.get_size() - (1,1)) > > > > The difference between the two is how the offset is treated. Both return > the same result in the single-argument case, but Option 1 explains the > multi-argument variant in terms of the single-argument variant, whereas > Option 2 explains the single-argument variant in terms of the multi-argument > invariant. I think Option 2 is simpler to explain/understand (the > lower-right corner of Option 1 just screams "off-by-one"). Option 1 is > slightly more flexible, because you can call it with 2 arguments, although I > don't think there would be any reason to do that (except that the unit tests > do that). Option 1 is implemented in this tarball, although it would be > trivial to switch it to option 2 (and the code might even be > infinitestimally nicer). > > It's splitting hairs I know, but I figure the hairs should be split before > the API becomes public. > > --Mike > > > Nirav Patel wrote: > >> You can use the diff command to generate patches, but if its easier >> for you, you can just upload or email the files you changed. >> >> Nirav >> >> > >
Re: [pygame] extending pygame masks
Here are the files. It turns out the actual convolution is much simpler than the one I sent out before, since I learned about the bitmask_draw method and just use that internally. It might be slightly slower, but it's more likely to be correct. As I was coding it up, I realized I'm still not completely happy with the interface. Which of the following two possibilities do people prefer? == Option 1 == Mask.convolve(othermask, outputmask = None, offset = (0,0)): return Mask Returns a mask with the (i-offset[0],j-offset[1]) bit set if shifting othermask so that it's lower right corner pixel is at (i,j) would cause it to overlap with self. If outputmask is not None, then the output is drawn onto outputmask and outputmask is returned. Otherwise a mask of size self.get_size() + othermask.get_size() - (1,1) is created. == Option 2 == Mask.convolve(othermask, outputmask, offset = (0,0)): return Mask Sets the ((i, j) - offset) bit of outputmask if overlap(self, othermask, (i,j)) is true. Returns outputmask. Mask.convolve(othermask): return Mask Creates a mask just big enough to hold the convolution of self and other, and shifts the output so that it fits in the mask. Equivalent to self.convolve(other, Mask(self.get_size() + othermask.get_size() - (1,1)), othermask.get_size() - (1,1)) The difference between the two is how the offset is treated. Both return the same result in the single-argument case, but Option 1 explains the multi-argument variant in terms of the single-argument variant, whereas Option 2 explains the single-argument variant in terms of the multi-argument invariant. I think Option 2 is simpler to explain/understand (the lower-right corner of Option 1 just screams "off-by-one"). Option 1 is slightly more flexible, because you can call it with 2 arguments, although I don't think there would be any reason to do that (except that the unit tests do that). Option 1 is implemented in this tarball, although it would be trivial to switch it to option 2 (and the code might even be infinitestimally nicer). It's splitting hairs I know, but I figure the hairs should be split before the API becomes public. --Mike Nirav Patel wrote: You can use the diff command to generate patches, but if its easier for you, you can just upload or email the files you changed. Nirav convolve.tar.gz Description: GNU Zip compressed data
Re: [pygame] extending pygame masks
You can use the diff command to generate patches, but if its easier for you, you can just upload or email the files you changed. Nirav On Fri, Oct 17, 2008 at 6:57 PM, Michael George <[EMAIL PROTECTED]> wrote: > I added a convolve function with the proposed interface, as well as docs and > a handful of unit tests. How do I generate and submit a patch? > > --Mike > > René Dudfield wrote: >> >> Sounds cool. >> >> Remember to also write unittests :) The mask module is falling >> behind it unittests at the moment. >> >> cheers! >> >> >> On Thu, Oct 16, 2008 at 5:40 AM, Michael George <[EMAIL PROTECTED]> >> wrote: >> >>> >>> Nirav Patel wrote: >>> It's not necessarily a good idea to have stuff that specific to an app in a library. I think it would be good to have the convolution function built into mask, and leave the rest of the implementation up to the user. As for how to deal with the interface for convolving, perhaps it would be useful to have one of the masks specified as being the "world", and the other as the object being moved? Something like: Mask.convolve(world = Mask) returning a mask the size of the world mask. >>> >>> I think it makes more sense to do it the other way - world.convolve(obj) >>> rather than obj.convolve(world). The two are flips of each other anyway, >>> so >>> it's probably not a big deal. In either case, the output needs to be >>> bigger >>> than both of the inputs (the size of the convolution is the sum of the >>> sizes >>> of the inputs, minus one). >>> >>> I guess it's not too hard to compute the rects if you're careful. >>> It would be fairly easy to construct this world mask by using Mask.draw. >>> >>> Yeah, that's probably best. In fact, I was thinking that I might need to >>> do >>> it that way anyway. The only reason to do it for a collection in one go >>> is >>> that you can avoid allocating all of those intermediate masks, and >>> shifting >>> everything twice. I guess masks are pretty small and shifts are pretty >>> fast >>> so it's not such a big deal. >>> >>> So here's a revised proposal: >>> >>> Mask.convolve(other = Mask): return Mask >>> compute the convolution of self and other. The (x,y) bit of the return >>> value will be set if shifting the lower-right corner of other to position >>> (x,y) would cause it to overlap with self. The return value has size >>> equal >>> to self.getsize() + other.getsize() - (1,1). >>> >>> >>> (and possibly) >>> Mask.convolve(other = Mask, world = Mask, offset = (x,y)): return None >>> Functionally the same as world.union(self.convolve(other), offset) but >>> more efficient >>> >>> Then the stuff that computes the rectangles and masks for a sprite group >>> would be up to the application developer (i.e. me). >>> >>> On a side note, does Mask.draw do an "or" or a copy of the two masks? >>> They're probably both useful. Assuming it's a copy, I've used >>> world.union >>> to denote orring the bitmasks. >>> >>> --Mike >>> >>> > >
Re: [pygame] extending pygame masks
I added a convolve function with the proposed interface, as well as docs and a handful of unit tests. How do I generate and submit a patch? --Mike René Dudfield wrote: Sounds cool. Remember to also write unittests :) The mask module is falling behind it unittests at the moment. cheers! On Thu, Oct 16, 2008 at 5:40 AM, Michael George <[EMAIL PROTECTED]> wrote: Nirav Patel wrote: It's not necessarily a good idea to have stuff that specific to an app in a library. I think it would be good to have the convolution function built into mask, and leave the rest of the implementation up to the user. As for how to deal with the interface for convolving, perhaps it would be useful to have one of the masks specified as being the "world", and the other as the object being moved? Something like: Mask.convolve(world = Mask) returning a mask the size of the world mask. I think it makes more sense to do it the other way - world.convolve(obj) rather than obj.convolve(world). The two are flips of each other anyway, so it's probably not a big deal. In either case, the output needs to be bigger than both of the inputs (the size of the convolution is the sum of the sizes of the inputs, minus one). I guess it's not too hard to compute the rects if you're careful. It would be fairly easy to construct this world mask by using Mask.draw. Yeah, that's probably best. In fact, I was thinking that I might need to do it that way anyway. The only reason to do it for a collection in one go is that you can avoid allocating all of those intermediate masks, and shifting everything twice. I guess masks are pretty small and shifts are pretty fast so it's not such a big deal. So here's a revised proposal: Mask.convolve(other = Mask): return Mask compute the convolution of self and other. The (x,y) bit of the return value will be set if shifting the lower-right corner of other to position (x,y) would cause it to overlap with self. The return value has size equal to self.getsize() + other.getsize() - (1,1). (and possibly) Mask.convolve(other = Mask, world = Mask, offset = (x,y)): return None Functionally the same as world.union(self.convolve(other), offset) but more efficient Then the stuff that computes the rectangles and masks for a sprite group would be up to the application developer (i.e. me). On a side note, does Mask.draw do an "or" or a copy of the two masks? They're probably both useful. Assuming it's a copy, I've used world.union to denote orring the bitmasks. --Mike
Re: [pygame] extending pygame masks
Sounds cool. Remember to also write unittests :) The mask module is falling behind it unittests at the moment. cheers! On Thu, Oct 16, 2008 at 5:40 AM, Michael George <[EMAIL PROTECTED]> wrote: > Nirav Patel wrote: >> >> It's not necessarily a good idea to have stuff that specific to an app >> in a library. I think it would be good to have the convolution >> function built into mask, and leave the rest of the implementation up >> to the user. As for how to deal with the interface for convolving, >> perhaps it would be useful to have one of the masks specified as being >> the "world", and the other as the object being moved? Something like: >> Mask.convolve(world = Mask) returning a mask the size of the world mask. >> >> > > I think it makes more sense to do it the other way - world.convolve(obj) > rather than obj.convolve(world). The two are flips of each other anyway, so > it's probably not a big deal. In either case, the output needs to be bigger > than both of the inputs (the size of the convolution is the sum of the sizes > of the inputs, minus one). > > I guess it's not too hard to compute the rects if you're careful. >> >> It would be fairly easy to construct this world mask by using Mask.draw. >> >> > > Yeah, that's probably best. In fact, I was thinking that I might need to do > it that way anyway. The only reason to do it for a collection in one go is > that you can avoid allocating all of those intermediate masks, and shifting > everything twice. I guess masks are pretty small and shifts are pretty fast > so it's not such a big deal. > > So here's a revised proposal: > > Mask.convolve(other = Mask): return Mask > compute the convolution of self and other. The (x,y) bit of the return > value will be set if shifting the lower-right corner of other to position > (x,y) would cause it to overlap with self. The return value has size equal > to self.getsize() + other.getsize() - (1,1). > > > (and possibly) > Mask.convolve(other = Mask, world = Mask, offset = (x,y)): return None > Functionally the same as world.union(self.convolve(other), offset) but > more efficient > > Then the stuff that computes the rectangles and masks for a sprite group > would be up to the application developer (i.e. me). > > On a side note, does Mask.draw do an "or" or a copy of the two masks? > They're probably both useful. Assuming it's a copy, I've used world.union > to denote orring the bitmasks. > > --Mike >
Re: [pygame] extending pygame masks
Nirav Patel wrote: It's not necessarily a good idea to have stuff that specific to an app in a library. I think it would be good to have the convolution function built into mask, and leave the rest of the implementation up to the user. As for how to deal with the interface for convolving, perhaps it would be useful to have one of the masks specified as being the "world", and the other as the object being moved? Something like: Mask.convolve(world = Mask) returning a mask the size of the world mask. I think it makes more sense to do it the other way - world.convolve(obj) rather than obj.convolve(world). The two are flips of each other anyway, so it's probably not a big deal. In either case, the output needs to be bigger than both of the inputs (the size of the convolution is the sum of the sizes of the inputs, minus one). I guess it's not too hard to compute the rects if you're careful. It would be fairly easy to construct this world mask by using Mask.draw. Yeah, that's probably best. In fact, I was thinking that I might need to do it that way anyway. The only reason to do it for a collection in one go is that you can avoid allocating all of those intermediate masks, and shifting everything twice. I guess masks are pretty small and shifts are pretty fast so it's not such a big deal. So here's a revised proposal: Mask.convolve(other = Mask): return Mask compute the convolution of self and other. The (x,y) bit of the return value will be set if shifting the lower-right corner of other to position (x,y) would cause it to overlap with self. The return value has size equal to self.getsize() + other.getsize() - (1,1). (and possibly) Mask.convolve(other = Mask, world = Mask, offset = (x,y)): return None Functionally the same as world.union(self.convolve(other), offset) but more efficient Then the stuff that computes the rectangles and masks for a sprite group would be up to the application developer (i.e. me). On a side note, does Mask.draw do an "or" or a copy of the two masks? They're probably both useful. Assuming it's a copy, I've used world.union to denote orring the bitmasks. --Mike
Re: [pygame] extending pygame masks
It's not necessarily a good idea to have stuff that specific to an app in a library. I think it would be good to have the convolution function built into mask, and leave the rest of the implementation up to the user. As for how to deal with the interface for convolving, perhaps it would be useful to have one of the masks specified as being the "world", and the other as the object being moved? Something like: Mask.convolve(world = Mask) returning a mask the size of the world mask. It would be fairly easy to construct this world mask by using Mask.draw. Of course, its not really up to me. Anyone else with opinions on the matter, feel free to chime in. Nirav On Wed, Oct 15, 2008 at 1:04 PM, Michael George <[EMAIL PROTECTED]> wrote: > Would it make sense for me to build this right into the Mask module and send > you a patch then, or would it be better for me to develop it separately as I > have been and share the source with you when it's finished so that you can > put it together? > > I'm still not entirely sure about the interface I want to provide. The > problem is computing the corresponding rects. Let's say you have an > obstacle with rect a and are dragging an object with rect b. Then the > output should have rect c where > > c.top= a.top- b.bottom > c.bottom = a.bottom - b. top > c.left = a.left - b.right > c.right = a.right - b.left > > (this might be off-by-one somewhere..probably need a -1 in c.bottom and > c.left). This would mean the bit of c corresponding to (x,y) would be set > if b were translated by (x,y). The reason this all presents a problem is > because masks don't have associated rects, but I'd rather not leave it to > the user to do the math. Probably the right thing to do is provides > something that takes a pair of sprites with rect and mask fields and outputs > a sprite. > > The other problem is that for my application I'd like to apply this to many > sprites all at once and then compute the overlay. It would be more > efficient to compute this all in one go since the intermediate masks could > be avoided. Probably the right thing then is to provide a function to > compute the hitmask of a whole sprite group. > > So I guess I've answered my own question. The interface should consist of > two functions: > > hitmask(Sprite) :: Sprite Return a sprite with the rect and mask > attributes set > grouphitmask(Group) :: Sprite Return a sprite with the rect and mask > attributes set, containing the union of the hitmasks for the group > > What do you think? Also, if you do want me to add this to pygame, should it > go in the mask module or the sprite module? > > --Mike > > Nirav Patel wrote: >> >> Mike >> >> Ah, very interesting. Can I see the source on that? I would love to >> see that included in the Mask module. >> >> Nirav >> > >
Re: [pygame] extending pygame masks
Would it make sense for me to build this right into the Mask module and send you a patch then, or would it be better for me to develop it separately as I have been and share the source with you when it's finished so that you can put it together? I'm still not entirely sure about the interface I want to provide. The problem is computing the corresponding rects. Let's say you have an obstacle with rect a and are dragging an object with rect b. Then the output should have rect c where c.top= a.top- b.bottom c.bottom = a.bottom - b. top c.left = a.left - b.right c.right = a.right - b.left (this might be off-by-one somewhere..probably need a -1 in c.bottom and c.left). This would mean the bit of c corresponding to (x,y) would be set if b were translated by (x,y). The reason this all presents a problem is because masks don't have associated rects, but I'd rather not leave it to the user to do the math. Probably the right thing to do is provides something that takes a pair of sprites with rect and mask fields and outputs a sprite. The other problem is that for my application I'd like to apply this to many sprites all at once and then compute the overlay. It would be more efficient to compute this all in one go since the intermediate masks could be avoided. Probably the right thing then is to provide a function to compute the hitmask of a whole sprite group. So I guess I've answered my own question. The interface should consist of two functions: hitmask(Sprite) :: Sprite Return a sprite with the rect and mask attributes set grouphitmask(Group) :: Sprite Return a sprite with the rect and mask attributes set, containing the union of the hitmasks for the group What do you think? Also, if you do want me to add this to pygame, should it go in the mask module or the sprite module? --Mike Nirav Patel wrote: Mike Ah, very interesting. Can I see the source on that? I would love to see that included in the Mask module. Nirav
Re: [pygame] extending pygame masks
I just realized that with a very slight modification the code I sent you could be used for sweep-based pixel-perfect collision detection. That is, by convolving a mask with a path you would have a mask that covers all of the pixels that the object touches as it traverses the path (rather than normal collision detection which just gives you the endpoint positions). Anyway, just a thought - not sure if that would be useful for anyone. --Mike Nirav Patel wrote: Mike Ah, very interesting. Can I see the source on that? I would love to see that included in the Mask module. Nirav On Tue, Oct 14, 2008 at 10:44 AM, Michael George <[EMAIL PROTECTED]> wrote: Thanks, what I need is different - I need to compute overlap_mask for each possible offset, so that I can search for an optimal placement. Of course I could write a loop and call overlap_mask for each offset, but I think that would be prohibitively slow - I'm computing it all in one pass. To move the #defines into pygame.h you wouldn't need to include the PyObject stuff in bitmask.h. If anything, pygame.h would have to include bitmask.h, not the other way around (although you could just add a forward declaration of bitmask_t). In the mean time, I guess I'll just copy the defs into my source. --Mike Nirav Patel wrote: Mike, I'm not sure if this is what you mean, but the Mask module has a function in SVN called Mask.overlap_mask, which returns a mask of the overlapping pixels between two masks by an offset. The internals of most of the bitmask stuff is exposed in bitmask.h. It could be useful to move the defines and typedef from mask.c to there. I think the reason it wasn't is that what's in bitmask.h currently is purely C, while the typedef has a PyObject_HEAD in it. Alternately, if you're making an external module, you could just import bitmask.h and copy the typedef and defines into your file. Nirav On Tue, Oct 14, 2008 at 9:11 AM, Michael George <[EMAIL PROTECTED]> wrote: hello, I've been working on some code that generates what I've been calling a "hitmask", namely a mask with the (x,y) bit set if placing one mask on another offset by (x,y) would cause a collision. It's part of a slick algorithm I'm working on for drag-and-drop collision response. I've implemented it in C against the bitmask api. I have n questions: 1. Is there any interest in putting this in pygame? I suspect no, because it's only useful for situations where you may freely drag oddly-shaped objects around but need to avoid collisions between them. It would be good for things like map editors. However if there is interest, I'd be happy to contribute it. 2. If not, I'd like to avoid shipping a modified pygame with my game. Is it possible for me to build and ship extensions that link against pygame internals (really just the bitmask stuff, and maybe rects at some point)? I haven't dug into the python/C boundary too much, although glancing over the pygame source it doesn't seem too bad. Can someone point me in the right direction? 3. If I do build my code separately, it currently looks impossible to actually get at the internals of a PyMaskObject without doing something hacky. In particular, the data structure and the PyMask_AsBitmap macro are only defined in mask.c, rather than in a separate header file. Is it reasonable for you to move that into pygame.h, or is it hidden for a reason? ...where n = 3. Thanks! --Mike
Re: [pygame] extending pygame masks
Attached. It's not integrated w/ python yet, but the tricky part is mostly done. --Mike Nirav Patel wrote: Mike Ah, very interesting. Can I see the source on that? I would love to see that included in the Mask module. Nirav On Tue, Oct 14, 2008 at 10:44 AM, Michael George <[EMAIL PROTECTED]> wrote: Thanks, what I need is different - I need to compute overlap_mask for each possible offset, so that I can search for an optimal placement. Of course I could write a loop and call overlap_mask for each offset, but I think that would be prohibitively slow - I'm computing it all in one pass. To move the #defines into pygame.h you wouldn't need to include the PyObject stuff in bitmask.h. If anything, pygame.h would have to include bitmask.h, not the other way around (although you could just add a forward declaration of bitmask_t). In the mean time, I guess I'll just copy the defs into my source. --Mike Nirav Patel wrote: Mike, I'm not sure if this is what you mean, but the Mask module has a function in SVN called Mask.overlap_mask, which returns a mask of the overlapping pixels between two masks by an offset. The internals of most of the bitmask stuff is exposed in bitmask.h. It could be useful to move the defines and typedef from mask.c to there. I think the reason it wasn't is that what's in bitmask.h currently is purely C, while the typedef has a PyObject_HEAD in it. Alternately, if you're making an external module, you could just import bitmask.h and copy the typedef and defines into your file. Nirav On Tue, Oct 14, 2008 at 9:11 AM, Michael George <[EMAIL PROTECTED]> wrote: hello, I've been working on some code that generates what I've been calling a "hitmask", namely a mask with the (x,y) bit set if placing one mask on another offset by (x,y) would cause a collision. It's part of a slick algorithm I'm working on for drag-and-drop collision response. I've implemented it in C against the bitmask api. I have n questions: 1. Is there any interest in putting this in pygame? I suspect no, because it's only useful for situations where you may freely drag oddly-shaped objects around but need to avoid collisions between them. It would be good for things like map editors. However if there is interest, I'd be happy to contribute it. 2. If not, I'd like to avoid shipping a modified pygame with my game. Is it possible for me to build and ship extensions that link against pygame internals (really just the bitmask stuff, and maybe rects at some point)? I haven't dug into the python/C boundary too much, although glancing over the pygame source it doesn't seem too bad. Can someone point me in the right direction? 3. If I do build my code separately, it currently looks impossible to actually get at the internals of a PyMaskObject without doing something hacky. In particular, the data structure and the PyMask_AsBitmap macro are only defined in mask.c, rather than in a separate header file. Is it reasonable for you to move that into pygame.h, or is it hidden for a reason? ...where n = 3. Thanks! --Mike #include #include "bitmask.h" /* ** Convolution * */ /* or aw bits from a into o + offset bits */ static void shift_or(BITMASK_W * a, int aw, int offset, BITMASK_W * o) { int woff = offset / BITMASK_W_LEN; int boff = offset & BITMASK_W_MASK; int mask_len; BITMASK_W residue = 0; BITMASK_W current; int i = 0; for (i = 0; (i+1) * BITMASK_W_LEN < aw + boff; i++) { current = residue | (a[i] << boff); residue = a[i] >> (BITMASK_W_LEN - boff); o[woff + i] |= current; } mask_len = BITMASK_W_LEN - (offset + aw) & BITMASK_W_MASK; current = residue | (a[i] << boff); current = current << mask_len >> mask_len; o[woff + i] |= current; } /* create "hitmask": a mask with the [x,y] bit set if the corresponding offset * would cause an intersection between a and b. Assumes that b is * right-aligned */ void bitmask_convolve(bitmask_t * a, bitmask_t * b, bitmask_t * o, int xoff, int yoff) { /* widths in words */ int aw = a->w / BITMASK_W_LEN + (a->w % BITMASK_W_LEN != 0), ow = o->w / BITMASK_W_LEN + (o->w % BITMASK_W_LEN != 0); /* loop variables; positions in a and b */ int ax, bx, ay, by; for (ay = 0; ay < a->h; ay++) for (by = 0; by < b->h; by++) for (bx = 0; bx < b->w; bx++) if (bitmask_getbit(b, b->w - bx - 1, by)) { /* oy is the row of the output */ int oy = ay - by + yoff + b->h - 1; /* or a->w bits from ay'th row to oy'th row, offset by xoff + bx bits */ shift_or(&(a->bits[ay*aw]), a->w, xoff + bx, &(o->bits[oy*ow])); } } /* ** Closest Point *** */ #define SQ(x) ((x) * (x)) /* find the closest point to (*x,*y) with getbit(mask,x,y) cleared. Set (*x, *y) * to the result. The result may be just outside of the boundary. */ void bitmask_closest(bitmask_t * mask,
Re: [pygame] extending pygame masks
Mike Ah, very interesting. Can I see the source on that? I would love to see that included in the Mask module. Nirav On Tue, Oct 14, 2008 at 10:44 AM, Michael George <[EMAIL PROTECTED]> wrote: > Thanks, > > what I need is different - I need to compute overlap_mask for each possible > offset, so that I can search for an optimal placement. Of course I could > write a loop and call overlap_mask for each offset, but I think that would > be prohibitively slow - I'm computing it all in one pass. > > To move the #defines into pygame.h you wouldn't need to include the PyObject > stuff in bitmask.h. If anything, pygame.h would have to include bitmask.h, > not the other way around (although you could just add a forward declaration > of bitmask_t). In the mean time, I guess I'll just copy the defs into my > source. > > --Mike > > Nirav Patel wrote: >> >> Mike, >> >> I'm not sure if this is what you mean, but the Mask module has a >> function in SVN called Mask.overlap_mask, which returns a mask of the >> overlapping pixels between two masks by an offset. >> >> The internals of most of the bitmask stuff is exposed in bitmask.h. >> It could be useful to move the defines and typedef from mask.c to >> there. I think the reason it wasn't is that what's in bitmask.h >> currently is purely C, while the typedef has a PyObject_HEAD in it. >> Alternately, if you're making an external module, you could just >> import bitmask.h and copy the typedef and defines into your file. >> >> Nirav >> >> On Tue, Oct 14, 2008 at 9:11 AM, Michael George <[EMAIL PROTECTED]> >> wrote: >> >>> >>> hello, >>> >>> I've been working on some code that generates what I've been calling a >>> "hitmask", namely a mask with the (x,y) bit set if placing one mask on >>> another offset by (x,y) would cause a collision. It's part of a slick >>> algorithm I'm working on for drag-and-drop collision response. I've >>> implemented it in C against the bitmask api. I have n questions: >>> >>> 1. Is there any interest in putting this in pygame? I suspect no, >>> because >>> it's only useful for situations where you may freely drag oddly-shaped >>> objects around but need to avoid collisions between them. It would be >>> good >>> for things like map editors. However if there is interest, I'd be happy >>> to >>> contribute it. >>> >>> 2. If not, I'd like to avoid shipping a modified pygame with my game. Is >>> it >>> possible for me to build and ship extensions that link against pygame >>> internals (really just the bitmask stuff, and maybe rects at some point)? >>> I >>> haven't dug into the python/C boundary too much, although glancing over >>> the >>> pygame source it doesn't seem too bad. Can someone point me in the right >>> direction? >>> >>> 3. If I do build my code separately, it currently looks impossible to >>> actually get at the internals of a PyMaskObject without doing something >>> hacky. In particular, the data structure and the PyMask_AsBitmap macro >>> are >>> only defined in mask.c, rather than in a separate header file. Is it >>> reasonable for you to move that into pygame.h, or is it hidden for a >>> reason? >>> >>> >>> ...where n = 3. >>> >>> Thanks! >>> >>> --Mike >>> >>> > >
Re: [pygame] extending pygame masks
Thanks, what I need is different - I need to compute overlap_mask for each possible offset, so that I can search for an optimal placement. Of course I could write a loop and call overlap_mask for each offset, but I think that would be prohibitively slow - I'm computing it all in one pass. To move the #defines into pygame.h you wouldn't need to include the PyObject stuff in bitmask.h. If anything, pygame.h would have to include bitmask.h, not the other way around (although you could just add a forward declaration of bitmask_t). In the mean time, I guess I'll just copy the defs into my source. --Mike Nirav Patel wrote: Mike, I'm not sure if this is what you mean, but the Mask module has a function in SVN called Mask.overlap_mask, which returns a mask of the overlapping pixels between two masks by an offset. The internals of most of the bitmask stuff is exposed in bitmask.h. It could be useful to move the defines and typedef from mask.c to there. I think the reason it wasn't is that what's in bitmask.h currently is purely C, while the typedef has a PyObject_HEAD in it. Alternately, if you're making an external module, you could just import bitmask.h and copy the typedef and defines into your file. Nirav On Tue, Oct 14, 2008 at 9:11 AM, Michael George <[EMAIL PROTECTED]> wrote: hello, I've been working on some code that generates what I've been calling a "hitmask", namely a mask with the (x,y) bit set if placing one mask on another offset by (x,y) would cause a collision. It's part of a slick algorithm I'm working on for drag-and-drop collision response. I've implemented it in C against the bitmask api. I have n questions: 1. Is there any interest in putting this in pygame? I suspect no, because it's only useful for situations where you may freely drag oddly-shaped objects around but need to avoid collisions between them. It would be good for things like map editors. However if there is interest, I'd be happy to contribute it. 2. If not, I'd like to avoid shipping a modified pygame with my game. Is it possible for me to build and ship extensions that link against pygame internals (really just the bitmask stuff, and maybe rects at some point)? I haven't dug into the python/C boundary too much, although glancing over the pygame source it doesn't seem too bad. Can someone point me in the right direction? 3. If I do build my code separately, it currently looks impossible to actually get at the internals of a PyMaskObject without doing something hacky. In particular, the data structure and the PyMask_AsBitmap macro are only defined in mask.c, rather than in a separate header file. Is it reasonable for you to move that into pygame.h, or is it hidden for a reason? ...where n = 3. Thanks! --Mike
Re: [pygame] extending pygame masks
Mike, I'm not sure if this is what you mean, but the Mask module has a function in SVN called Mask.overlap_mask, which returns a mask of the overlapping pixels between two masks by an offset. The internals of most of the bitmask stuff is exposed in bitmask.h. It could be useful to move the defines and typedef from mask.c to there. I think the reason it wasn't is that what's in bitmask.h currently is purely C, while the typedef has a PyObject_HEAD in it. Alternately, if you're making an external module, you could just import bitmask.h and copy the typedef and defines into your file. Nirav On Tue, Oct 14, 2008 at 9:11 AM, Michael George <[EMAIL PROTECTED]> wrote: > hello, > > I've been working on some code that generates what I've been calling a > "hitmask", namely a mask with the (x,y) bit set if placing one mask on > another offset by (x,y) would cause a collision. It's part of a slick > algorithm I'm working on for drag-and-drop collision response. I've > implemented it in C against the bitmask api. I have n questions: > > 1. Is there any interest in putting this in pygame? I suspect no, because > it's only useful for situations where you may freely drag oddly-shaped > objects around but need to avoid collisions between them. It would be good > for things like map editors. However if there is interest, I'd be happy to > contribute it. > > 2. If not, I'd like to avoid shipping a modified pygame with my game. Is it > possible for me to build and ship extensions that link against pygame > internals (really just the bitmask stuff, and maybe rects at some point)? I > haven't dug into the python/C boundary too much, although glancing over the > pygame source it doesn't seem too bad. Can someone point me in the right > direction? > > 3. If I do build my code separately, it currently looks impossible to > actually get at the internals of a PyMaskObject without doing something > hacky. In particular, the data structure and the PyMask_AsBitmap macro are > only defined in mask.c, rather than in a separate header file. Is it > reasonable for you to move that into pygame.h, or is it hidden for a reason? > > > ...where n = 3. > > Thanks! > > --Mike >