Pages: 1
  Print  
Author Topic: Collision shape options  (Read 4003 times)
Offline (Unknown gender) forthevin
Posted on: October 06, 2012, 10:32:31 AM

Contributor
Joined: Jun 2012
Posts: 171

View Profile
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.
Logged
Offline (Male) Josh @ Dreamland
Reply #1 Posted on: October 06, 2012, 12:04:16 PM

Prince of all Goldfish
Developer
Location: Pittsburgh, PA, USA
Joined: Feb 2008
Posts: 2960

View Profile Email
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 {
  ct_bbox,
  ct_precise,
  ct_circle,
  ct_ellipse,
  ct_diamond,
  ct_polygon
}

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.
« Last Edit: October 06, 2012, 12:11:09 PM by Josh @ Dreamland » Logged
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble
"I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
Offline (Unknown gender) forthevin
Reply #2 Posted on: October 06, 2012, 04:04:47 PM

Contributor
Joined: Jun 2012
Posts: 171

View Profile
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?
Logged
Offline (Male) Josh @ Dreamland
Reply #3 Posted on: October 07, 2012, 07:40:18 PM

Prince of all Goldfish
Developer
Location: Pittsburgh, PA, USA
Joined: Feb 2008
Posts: 2960

View Profile Email
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.
Logged
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble
"I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
Offline (Unknown gender) forthevin
Reply #4 Posted on: October 09, 2012, 02:08:57 PM

Contributor
Joined: Jun 2012
Posts: 171

View Profile
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)
Logged
Offline (Female) IsmAvatar
Reply #5 Posted on: October 11, 2012, 03:43:10 PM

LateralGM Developer
LGM Developer
Location: Pennsylvania/USA
Joined: Apr 2008
Posts: 886

View Profile Email
Quote
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
Logged
Offline (Unknown gender) forthevin
Reply #6 Posted on: October 12, 2012, 06:11:24 AM

Contributor
Joined: Jun 2012
Posts: 171

View Profile
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".
Logged
Offline (Male) Josh @ Dreamland
Reply #7 Posted on: October 12, 2012, 06:01:36 PM

Prince of all Goldfish
Developer
Location: Pittsburgh, PA, USA
Joined: Feb 2008
Posts: 2960

View Profile Email
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.
« Last Edit: October 12, 2012, 06:04:21 PM by Josh @ Dreamland » Logged
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble
"I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
Offline (Unknown gender) forthevin
Reply #8 Posted on: October 14, 2012, 08:55:54 AM

Contributor
Joined: Jun 2012
Posts: 171

View Profile
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.
Logged
Offline (Unknown gender) forthevin
Reply #9 Posted on: October 20, 2012, 03:30:05 PM

Contributor
Joined: Jun 2012
Posts: 171

View Profile
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.
Logged
Offline (Male) Josh @ Dreamland
Reply #10 Posted on: October 20, 2012, 04:58:36 PM

Prince of all Goldfish
Developer
Location: Pittsburgh, PA, USA
Joined: Feb 2008
Posts: 2960

View Profile Email
I'll happily pull the patch so long as it doesn't break any existing functions.
Logged
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble
"I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
Offline (Unknown gender) forthevin
Reply #11 Posted on: October 21, 2012, 01:30:23 PM

Contributor
Joined: Jun 2012
Posts: 171

View Profile
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.
Logged
Offline (Male) polygone
Reply #12 Posted on: November 07, 2012, 12:30:49 AM

Contributor
Location: England
Joined: Mar 2009
Posts: 803

View Profile
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.
« Last Edit: November 07, 2012, 07:23:08 AM by polygone » Logged
I honestly don't know wtf I'm talking about but hopefully I can muddle my way through.
Offline (Unknown gender) forthevin
Reply #13 Posted on: November 08, 2012, 07:34:15 PM

Contributor
Joined: Jun 2012
Posts: 171

View Profile
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.
Logged
Pages: 1
  Print