Trying derpately to find a way to scale physics outlines at runtime

As the title says, I’ve been trying to find a workaround for the fact that physics outlines cannot be scaled.

Now, I don’t actually need to be able to scale physics outlines dynamically / on the fly, I just need to do it once at startup. The reason for this is that I’m allowing custom user content, which among other things, can define a scaling factor for an object.

Easy enough for sprites. Then I discovered that outlines don’t have a :scale function, so I started trying to work around it… Since I need to scale the hitbox for the objects to fit the scaled sprites.

My first idea was to first load the outline from an image file, as just a display object, scale it, and cache it to disk again in its scaled form… And THEN, load that cached image as a graphics outline. And, you know what, it worked… I thought. Until I discovered that the dimensions of the saved images on disk are completely nonsensical. On Windows, running with no screen scaling options, no zoom on the preview window, when I save a 128x128 displayObject to disk, it’s saved as a 85x85 image. What?

So yeah, I fought for hours with that, but I could never get the save to actually save the object the way it was displayed in game. The dimensions were never the same.

So then I figure well, okay, what if I create the outline based on the original image file, and then scaled the coordinates in the outline array? Just a simple multiplication right?

Right. It works. But at the same time, for some completely mysterious reason, it also doesn’t work.

If I load an outline… Multiply every coordinate in the array by my scaling factor… And draw it (the outline) to the screen using newPolygon, it looks perfect. The shape is correct, the scale is perfect. Great.

Now when I apply the SAME OUTLINE as an option to an object when I do physics.addBody(sprite, {outline = myScaledOutline}) … It’s wrong. The position of the collision box is offset, by some strange factor that I cannot figure out. I can adjust it by hand by offsetting every vertex in the outline array during my scaling step, but it only works for 1 scaling factor. I can’t find a pattern.

I don’t understand how the outline can produce a perfect polygon when used with newPolygon, but the SAME ARRAY doesn’t work as a physics outline?

I am losing my mind

This is dummy code, but it describes essentially what I am doing in the last example:

local scale = 4 local scaledSprite = display.newImage(spriteSheet, spriteIndex, centerX-256, centerY) scaledSprite:scale(scale, scale) local scaledOutline = graphics.newOutline(app.outlineTexels, outlineSheet, outlineIndex) for vert,coord in pairs(scaledOutline) do scaledOutline[vert] = vert \* scale end physics.addBody(scaledSprite, "dymanic", {outline = scaledOutline}) local outlineTest = display.newPolygon(centerX+256, centerY, scaledOutline)

Here’s a small animation showing the results (just focus on the two big “U” shapes):
https://gfycat.com/gifs/detail/CreamyDisfiguredArabianwildcat

The moving block turns red when it collides with something, as you can see the collision for the big blue U is way off. Even though it uses, literally, the same outline array for collision as what was used to draw the white U polygon on the right hand side.