Contributing to ENIGMA => Proposals => Topic started by: forthevin on October 06, 2012, 10:32:31 AM

Title: Collision shape options
Post by: forthevin on October 06, 2012, 10:32:31 AM
Currently, the structure for sprites does not contain information for which kind of shape is wanted for a given sprite, such as bounding box, precise, ellipse, diamond or polygon mesh.

I propose a simple system, where a single integer field, for example "collisionshape", is used as an enum, and where each value indicates a given desired shape, for example:

0: bounding box

1: precise

2: ellipse

3: diamond

4: polygon mesh

Different collision systems can interpret the wanted shape differently. The BBox collision system can for example always use bounding boxes independent of the wanted shape, and a polygon collision system could model bounding boxes, ellipses and diamonds as polygons internally and ignore the precise shape. I think this is fine, because a collision system cannot handle a shape it does not support anyway, and it is very easy to change between collision systems. Basically, game developers should pick shapes that fit the collision system they use for a given game.
Title: Re: Collision shape options
Post by: Josh @ Dreamland on October 06, 2012, 12:04:16 PM
In principle, I'm fine with that. My concern is keeping the IDs straight. As such, I think it best to define the above as enum constants in collisions_mandatory.h.
Code: (C++) [Select]
enum collision_type {

This way, if a collision system offers some other, more obscure shape, it can be added without confusing other systems.

We'll also need to define void *get_collision_mask(sprite* spr, collision_type ct) to fetch a collision mask from the system, and void *free_collision_mask(void* mask) to set the colldata values in spritestruct.h (https://github.com/enigma-dev/enigma-dev/blob/master/ENIGMAsystem/SHELL/Universal_System/spritestruct.h).
Title: Re: Collision shape options
Post by: forthevin on October 06, 2012, 04:04:47 PM
Using enum constants for the collision type instead of a single integer field is a good idea.

I don't quite understand how get_collision_mask and free_collision_mask should work or be used. Does the collision mask returned from get_collision_mask only contain collision data for one subimage, or does it contain collision data for all subimages? Is it a linked list? What does free_collision_mask take as argument and return, and how should it be used in regards to setting the colldata?
Title: Re: Collision shape options
Post by: Josh @ Dreamland on October 07, 2012, 07:40:18 PM
Since it returns void*, get_collision_mask would only be for one subimage (the actual array is void**).

The other function, free_collision_mask, would only be for use on game termination for the purposes of cleaning up. It should actually return void, not void*. It would just cast the (void*) to the appropriate collision-system-specific structure and delete it. For example,

Code: (C++) [Select]
void free_collision_mask(void* mask) {
  delete (polygon_mesh*)mask;

Note that it might not necessarily be a single class type, but the point is that the collision_data is a black box that only the selected collision system need understand. So it must handle allocation and freeing in addition to the actual checking.
Title: Re: Collision shape options
Post by: forthevin on October 09, 2012, 02:08:57 PM
I think I understand the functions now. void *get_collision_mask(sprite* spr, collision_type ct) seems like it lacks a way to pass the collision system the input data for a subimage, since the sprite struct does not contain image data.

That brings up another issue, namely what to do if the collision type requires different input data than image data. For the majority of the collision types, image data works, but for collision types like polygon, the input data should ought to be vertex data rather than image data.

The current input data for collisionsystem_sprite_data_create is of the form char*. That works for image data, and I believe it could also work for vertex data as well as other formats. For instance, for image data, char* can be interpreted as it is currently, namely as an array of pixel-values, where each quadruple of bytes constitutes an RGBA-value, and where the size of the array can be calculated from the sprite's width and height. For vertex data, the first four bytes could indicate the number of vertices and therefore also the size of the array, and each following 2*4 bytes could indicate a vertex with (x, y) coordinates, each coordinate 32-bit.

The functions would then look like this:

Code: [Select]
void *get_collision_mask(sprite* spr, collision_type ct, char* input_data)
void free_collision_mask(void* mask)
Title: Re: Collision shape options
Post by: IsmAvatar on October 11, 2012, 03:43:10 PM
the sprite struct does not contain image data.
Depends which sprite struct we're talking about.
backend/resources/sprite.h:36:   SubImage *subImages;
backend/sub/SubImage.h:17:    Image image;
backend/util/Image.h:16: char *data; //zlib compressed RGBA
Title: Re: Collision shape options
Post by: forthevin on October 12, 2012, 06:11:24 AM
Sorry about that, I can see how that could be confusing. The sprite struct I was talking about is the one in "ENIGMAsystem/SHELL/Universal_System/spritestruct.h".
Title: Re: Collision shape options
Post by: Josh @ Dreamland on October 12, 2012, 06:01:36 PM
Quite right. We'll need to pass that as a second parameter, then; your correction is accepted. Though I might switch the last two parameters because I'm anal-retentive and I like the types to be of descending size.

The system needs refactored, anyway, I believe; we currently do not query the collision system for any kind of sprite data (which I believe is okay for now because, as I recall, the bbox_ values only change when the sprite_index changes, not the image_index).

Moreover, the sprite editor doesn't support editing anything on a per-subimage basis, meaning polygon masks created by the user cannot currently be animated. And to top it all off, the mask system is very poorly integrated. So, some more planning is required at this phase.

That said, anything else you want to add to that function, speak now.

I might also point out that ENIGMA has had pixel-perfect collisions in the past, so it's not that difficult; I just don't want another clusterfuck.
Title: Re: Collision shape options
Post by: forthevin on October 14, 2012, 08:55:54 AM
I can't think of anything more that get_collision_mask should have, so I think it is good to go.

In regards to the mask system integration, I think it would be a good idea to support generic collision types in LateralGM, basically collision types that are identified only by their enum value and which has a generic representation (such as a byte array) for the collision data stored in each subimage. That would make it easier to support new collision types without making extensive modifications to LateralGM. It should still be possible to support a given collision type directly in LateralGM, for instance for the purpose of adding graphical editing for the collision type. Since adding graphical editing for generic collision types is not possible, LateralGM should support loading collision data for subimages from files, for instance by reading the contents of a file in as a byte array for a given subimage.
Title: Re: Collision shape options
Post by: forthevin on October 20, 2012, 03:30:05 PM
Unless anyone has any objections, I would like to go ahead and try to make a patch to implement the proposed changes. Since the changes regarding LateralGM and generic collision types are most useful once polygons or other collision types are supported in a collision system, I suggest that those changes are postponed until they are needed.
Title: Re: Collision shape options
Post by: Josh @ Dreamland on October 20, 2012, 04:58:36 PM
I'll happily pull the patch so long as it doesn't break any existing functions.
Title: Re: Collision shape options
Post by: forthevin on October 21, 2012, 01:30:23 PM
I have just finished the patch, and it can be seen here: https://github.com/forthevin/enigma-dev/commit/de35331e431188f6ddb6767229cad064c87dc5e9. It has also been added to the existing pull request.

In regards to the interface change and the commit, I decided to change the interface from using char* to using unsigned char*, since that turned out to fit better with the existing systems. Apart from that, there was no other changes to the new interface.
Title: Re: Collision shape options
Post by: polygone on November 07, 2012, 12:30:49 AM
forthevin: to note; the move_* functions etc should use the object parameter when checking collision_inst_inst not all. Also in the for loops you should increment by DMIN instead of 1.

ps are you ever possibly planning on using the enigma irc channel? It would be nice to know your future plans etc with regards to what you're going to be working on in enigma. Great to see someone actually doing precise collisions again though.
Title: Re: Collision shape options
Post by: forthevin on November 08, 2012, 07:34:15 PM
Thanks for the notice, I have fixed object and all in the move_* functions. Why should DMIN be used instead of 1 to increment in the "for" loops?

I don't really have any future plans about what to work on in ENIGMA, apart from doing various small fixes. I do have a couple of ideas, but I haven't decided on any of them yet. Once the precise collisions are done, I will take some time to figure out what to work on, and then tell about my plans then.