Hello Guest

Author Topic: Sprite Collection Analysis at Run Time  (Read 4223 times)

Aubrey

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 6
    • View Profile
Sprite Collection Analysis at Run Time
« on: April 09, 2013, 10:26:57 am »
Hi there,
I'm currently on a project which is for mobile, using in the region of 30* separate sprite collections. Due to the nature of the project, this is only likely to increase.

Our sprite organisation has not been based on "what gets used simultaneously", so it's sub optimal. Entire sprite collections may be loaded just to display 1 sprite from them. There might be 8 sprite collections loaded for one scene, with the scene only referencing one or two sprites from each collection (I exaggerate, but you see our problem!) . Not normally an issue, but we're on mobile, and thus have to be extra cautious about hitting iOS's magical memory "fuck you" threshold. :'(

So, we have to reorganize our sprites in order to minimize sprites which aren't being used at any given moment. This is mostly easy for us to do since our game is very menu heavy, so our menu screens seem to split into collections quite easily.

My question/suggestion for a feature is to have some kind of run time analysis tool which tells you what sprites are being used right now, and from what sprite collection. Also, something to tell you what percentage of each sprite collection is displayed at once.

I'm going to have a stab at it in my own bad way, by running through every camera, and every sprite, and doing an "is visible" check, and then putting a little "check!" mark against each sprite collection to say that it's used, and just have a look at that data in the inspector. Pretty slow, but it's analysis so it doesn't have to be in the release. Maybe there's a better way which hooks more directly into tk2d code? Perhaps you could suggest a better approach to the meta-organization of sprites based on common useage.

*2dToolkit: we love you!

unikronsoftware

  • Administrator
  • Hero Member
  • *****
  • Posts: 9709
    • View Profile
Re: Sprite Collection Analysis at Run Time
« Reply #1 on: April 10, 2013, 12:45:31 am »
I have most certainly thought of doing this before, but there are so many possible ways to create objects it becomes almost impossible to do so. A "snapshot" analysis is certainly possible, but not a static analysis tool.

An example - you can create sprites by placing them in the scene, or you can place sprites by loading them programmatically by storing a reference in the scene, or loading with resources.load, or even load a scene additively. You can also implicitly load sprites in by loading a prefab containing a sprite, or a script with a reference to the sprite collection, etc, etc. These are only the cases I could think of off-hand, there are a lot more possibilities that it would be impractical...

The final thing I've considered is having a system to automatically generate sprite collections for a scene based on static analysis, and another where the atlases are automatically generated at runtime while the game is running. It is a substantial amount of work though, and I'm not sure when if ever something like this will be implemented.

And all of this because Unity can't stream textures properly (like most other modern engines...)

Aubrey

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: Sprite Collection Analysis at Run Time
« Reply #2 on: April 10, 2013, 01:54:16 pm »
Sounds a bit like idTech's megatextures! Worked on a project which had that. Yep. A lot of work!

I'm doing pretty well with my tool (although it's super simplistic). It's already highlighted what collections want to get split and what want to be conjoined, so well worth the effort in our case.

I'm currently trying to calculate how big a sprite is in terms of pixels (so that I can calculate the memory wasteage). I'm finding it harder than expected! Must be missing something!

Is it something like (tk2dSpriteDefinition::texelSize.x * Texture::width ) * (tk2dSpriteDefinition::texelSize.y * Texture::height ) to get pixels used? I never fully understood texels. Are they like, 1 texel = the size of the current texture? Like a UV co-ordinate system? I may be confusing myself.

[Edit]: n/m. That made me think of using UVs. Wasn't for sure about UV index order (i.e. bottom left corner vs. top right corner) so I just grabbed the first and last UV from the sprite def's array... something like this:

Code: [Select]
Vector2 spriteUVSize= new Vector2(
Mathf.Abs(spriteDef.uvs[0].x - spriteDef.uvs[spriteDef.uvs.Length-1].x),
Mathf.Abs(spriteDef.uvs[0].y - spriteDef.uvs[spriteDef.uvs.Length-1].y)
);
spriteUseMemory += (int)((spriteUVSize.x *textureSize.x ) * (spriteUVSize.y * textureSize.y));

Not sure if it necessarily works for sliced sprites, because I'm not sure how the verts are arranged.. just *assuming* index 0 is one corner, and index vertList.Length-1 is the opposite corner.
« Last Edit: April 10, 2013, 02:09:32 pm by Aubrey »

unikronsoftware

  • Administrator
  • Hero Member
  • *****
  • Posts: 9709
    • View Profile
Re: Sprite Collection Analysis at Run Time
« Reply #3 on: April 10, 2013, 02:10:31 pm »
The sprites themselves are stored as geometry, so there isn't really any "direct" access to the texture size, but you can derive this.

Code: [Select]
tk2dSpriteDefinition def = sprite.CurrentSprite;
Vector3 textureDims = Vector3.Scale(def.boundsData[1], new Vector3(1.0f / def.texelSize.x, 1.0f / def.texelSize.y, 0));

Keep in mind this will return "texture dimensions" - when using platform specific collections, and you're using a 1/2 scale atlas, it still thinks its full scale. It should be correct in most normal cases though.

Edit: Oh yeah one more thing - this won't be correct if you use dicing, as the texture will be all over the atlas and optimized in different ways.

Aubrey

  • 2D Toolkit
  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: Sprite Collection Analysis at Run Time
« Reply #4 on: April 10, 2013, 03:24:32 pm »
No dice...ing.

By which I mean, cool, thanks!