Sprite scaling based on the source image's dimensions - how to achieve this?


when I import my sprites using the SpritePackedManager, they all are scaled to width = height = 1 world units (I think). This makes most of them look very odd, so it seems that I need to scale them manually. I wanted to do this by using my precalculated pixelsPerWorldUnit value (in this case, 32 pixels should be 1 world unit), so that a sprite with original width of 64 px would be scaled to width = 2.0 (2 world units = tiles in my game).

Unfortunately, I can’t seem to find any way to access the original properties of the source images, despite it being present in the JSON I generated via TexturePacker in the form of the grid’s boundaries. I haven’t seen anything at all in the Sprite APIs that allows scaling other than using world coordinates directly, which is useless if I can’t fathom how big the sprite should be in the first place. The HOWTO/Tutorials also ignore this crucial step of rendering sprites correctly, simply stating that I can set the dimensions with the width/height/size properties. Am I missing something basic here? This seems like a no-brainer otherwise.

Perhaps someone can point me in the right direction? Cheers!

Edit: I found this in the SpritePackedManager object (dumped via JS): https://i.imgur.com/vQIcYWK.png

There’s a private property _celldata containing a sourceSize.w and sourceSize.h property for each frame object, as well as the spriteSourceSize containing the same info?

This is exactly the value I need, except I’m not sure about which to use, and if there’s a proper API. Relying on the internal fields seems like a terrible idea. Ideally, I’d just want to use sprite.sourceSize.w or something similarly straight-forward.

Also, I can’t fathom what the difference is between the two. Does it matter? spriceSourceSize appears to also have some x, y fields that are always zero in my case?

Hi @rdw1 and welcome to the forum :slight_smile:

There is some documentation about the sprite Packed Manager available here : Sprites - Babylon.js Documentation

It’s possible have sprites with different sizes by creating the JSON with the position and size information (see SourceSize).

Thanks, but I’ve long since read that documentation. It doesn’t mention any way to access the source size directly. In fact, it explicitly states that “SpritePackedManager only uses the frame property for each sprite” (though as far as I can tell, that should include the source dimensions, as well?).

What I need is to access the sourceSize already contained in the JSON and apparently provided by ISpriteJSONSprite - Babylon.js Documentation. All the information is definitely present somewhere in the convoluted object hierarchy (see my edit to the OP), I just haven’t found an API or “intended” way to access it :slight_smile:

It isn’t listed in the Sprite nor SpritePackedManager API docs, presumably because it’s a private field? My JSON has all the required information, I just haven’t been able to use it in BJS.

This PG https://www.babylonjs-playground.com/#X2FVF5#11 shows how to use the JSON with the spritePackedManager.
Basically, you specify the JSON data to the SpritePackedManager constructor.

Let me know if helps … or not :slight_smile:

Actually, do you want to modify the sourceSize by code?

Thanks for the reply! I’m afraid I don’t see how this allows me to access the sourceSize of the sprite manager, my JSON uses the same format though.

I don’t need to modify the sourceSize, all I require is to read it so that I can scale the sprite properly :slight_smile:

Whats are you trying to have happen? I am responsible for fixes on this topic, what is it that you need? Im sorry Im recovering still from surgery and am kinda in the clouds, but if I can figure out what you need i’ll fix it.

Ohh right now on the packed manager it only takes the “frame” into account. There is a way to resize the sprite dependent on the sourceSize. Let me see if I can find that example.

I will be updating the SPM to use the other parameters on the JSON by the end of the month.

var spm = new BABYLON.SpritePackedManager("spm", PRYME.textureAtlasUri, 96, scene, jsonDat);
   let keys = Object.keys(spm._cellData)
   for(var i = 0; i<keys.length; i++){
        let sn = keys[i]
        let sDat = spm._cellData[sn]
        let s = new BABYLON.Sprite(sn, spm);
            s.cellRef = sn

            let frame = parsedArray[sn].frame
            let base = parsedArray[sn].sourceSize

            frame = new BABYLON.Vector2(frame.w, frame.h)
            source = new BABYLON.Vector2(base.w, base.h)

            offsetSource = new BABYLON.Vector2(parsedArray[sn].spriteSourceSize.x, parsedArray[sn].spriteSourceSize.y)

            let ratio = frame.divide(source)
            let offset = source.subtract(offsetSource)
            let masterScale = (new BABYLON.Vector2(1,1)).divide(source)

            s.width = ratio.x
            s.height = ratio.y
            s.invertU = 0            
            s.position.x = (i)-((1-ratio.x)*0.5)+(1.0-offset.x)
            s.position.y = ((1-ratio.y)*0.5)+offset.y

I think is what you need?

1 Like

Thanks, that seems like it’s doing something similar to the playground I made earlier to illustrate the problem: https://www.babylonjs-playground.com/#IM20QJ#12

I’ve now been able to achieve the correct scaling, see the final comparison here: https://i.imgur.com/IVcA6kl.png

Still, I think that’s a very… creative way, digging around in the internals for something that should be immediately accessible. Is this really the intended way to scale sprites, which must be a fairly standard task? If so, the documentation should probably mention the fact they’re scaled to 1:1 world units by default, as well as how to change that.

Either way, no rush. I understand it’s still a fairly new feature :slight_smile:

I’ll be making fixes here as soon as I am a little more healed, thank you for your input!


Hello again! Are there any updates for this issue?

I just started working with the sprites again and it seems the documentation/API hasn’t changed, so it seems there’s no proper way to fix these scaling problems yet? Or maybe I just haven’t found the right information.