I was curious about this, so I took a look. The stretching is related to the fact that your replacement textures are loaded into a square OpenGL texture with powers-of-two sides: the image_scale attribute doesn't play nice with the code to deal with translating between the actual texture size and your replacement image's size. The "Non-power-of-two textures" setting fixes it, but a better workaround is to make your replacements valid OpenGL sizes, like 256x256 or 512x512.
With OpenGL-friendly image sizes, then you can simply set the image_scale parameter to match the "scale factor" from the frame in ShapeFusion. (This is 5 for the magnum frames.) If you create higher-res images, then you'll need to adjust image_scale appropriately. The offsets come after scaling, so multiply the real pixel offset by the scale factor.
Here's a version of your plugin with a full example of this approach. The original magnum idle frame is offset by 50 pixels inside a 256x256 canvas.
[attachment=4836:Weapons_...d_Canvas.zip]
Weapons In Hand
- Attachments
-
- Weapons_In_Hand__Expanded_Canvas.zip
- (13.78 KiB) Downloaded 353 times
- Ares Ex Machina
- Mjolnir Mark IV
- Posts: 614
- Joined: Jan 23rd '08, 08:07
- Contact:
Oh, wow. Thank you! This is much better than I was hoping for. Awesome!
I'm following everything except one thing: how did you get -570 and -770 for your mml offsetting? About the only thing I understand is that those numbers have been multiplied by 5.
I'm following everything except one thing: how did you get -570 and -770 for your mml offsetting? About the only thing I understand is that those numbers have been multiplied by 5.
I didn't; as far as I can tell, the attachment above has -250 and -250 in the mml...Ares Ex Machina wrote:how did you get -570 and -770 for your mml offsetting?
Code: Select all
<texture coll="1" bitmap="3" normal_image="Weapons/Magnum/magnum_03.png" opac_type="1" type="3" image_scale="5.00" x_offset="-250" y_offset="-250"/>
Should we fix this?Hopper wrote:I was curious about this, so I took a look. The stretching is related to the fact that your replacement textures are loaded into a square OpenGL texture with powers-of-two sides: the image_scale attribute doesn't play nice with the code to deal with translating between the actual texture size and your replacement image's size.
I'm considering adding an aspect_ratio attribute so the XBLA replacements can work without a shapes file. I think they're already POT though.
- Ares Ex Machina
- Mjolnir Mark IV
- Posts: 614
- Joined: Jan 23rd '08, 08:07
- Contact:
Oops, I accidentally edited your file instead of mine. I guess what I'm not getting is exactly how the real pixel offset is determined.Hopper wrote:I didn't; as far as I can tell, the attachment above has -250 and -250 in the mml...
For my new magnum image, what I did was measure the distance from the left side of my image to the left side of my canvas: 93 pixels.
Then I measured the distance from the top of my image to the top of my canvas: 67 pixels.
Multiplied by 5, this gave me an X offset of -465 and a Y offset of -335, so that's what I plugged into the mml. But my weapon is off center in-game, so where did I go wrong?
Last edited by Ares Ex Machina on Jun 5th '11, 22:22, edited 1 time in total.
It'd be very difficult to use image_scale and not run into this bug, and it looks like it's been there for the last 5 years, but how many people would have needed to set a different bounding box for a replacement than the one in the Shapes file? Most scenario makers would be able to get around needing image_scale at all.Treellama wrote:Should we fix this?
Doing HD upgrades of the stock content is the likeliest reason for image_scale, but it's not used in WEP or Shots Fired. Going as far as A.E.M. did to find the aspect problems and compensate for them, without mentioning it anywhere devs would notice, seems farfetched. I'm leaning toward fixing it.
After seeing what the engine is doing, I'm not sure you need a new attribute to work with a stock Shapes file. If they aren't POT and we don't fix this bug, then they'd need to be resized to POT first. I'm also not certain that Shader handles monsters the same way, but in Classic it looks possible that even the orange compilers could work.I'm considering adding an aspect_ratio attribute so the XBLA replacements can work without a shapes file. I think they're already POT though.
The offset is based on where the top left of the Shapes-file image would line up on your canvas, which may or may not be the top left of your final image. If you're drawing an extra glow outside these borders, that will not change the offset you want in the MML. The easiest way to find the offset is to overlay the original graphic, as exported from ShapeFusion with the blue background, onto your canvas: the offset is the position of that first blue pixel.Ares Ex Machina wrote:For my new magnum image, what I did was measure the distance from the left side of my image to the left side of my canvas: 93 pixels.
Then I measured the distance from the top of my image to the top of my canvas: 67 pixels.
Multiplied by 5, this gave me an X offset of -465 and a Y offset of -335, so that's what I plugged into the mml. But my weapon is off center in-game, so where did I go wrong?
If that process still gives you 93 and 67, then there's the obvious but easily overlooked: You have image_scale set to 5? Your canvas set to 256x256? No typos in the MML?
- Ares Ex Machina
- Mjolnir Mark IV
- Posts: 614
- Joined: Jan 23rd '08, 08:07
- Contact:
Alright, thanks! Everything is working great now. Where I went wrong: measuring without using the blue background, and measuring from the edges rather than the upper left corner.
Last edited by Ares Ex Machina on Jun 6th '11, 06:07, edited 1 time in total.
I was never able to adjust the aspect ratio on replacement images. It looks like offset_x has a chance of doing that? Not very intuitive...Hopper wrote:After seeing what the engine is doing, I'm not sure you need a new attribute to work with a stock Shapes file.
Not offset_x, but image_scale. When image_scale is unspecified (or <= 0), then your replacement is locked exactly to the bounds of the original image. When image_scale is a positive number, it shows your image as square pixels, using image_scale as it would the Shapes file's scale factor. Offset_x and offset_y can then be used to recenter that image.Treellama wrote:I was never able to adjust the aspect ratio on replacement images. It looks like offset_x has a chance of doing that? Not very intuitive...
The upshot is, if you use image_scale, the engine will use the aspect ratio of the replacement, not the aspect ratio of the original frame.
That's even less intuitive! And not documented!Hopper wrote:Not offset_x, but image_scale. When image_scale is unspecified (or <= 0), then your replacement is locked exactly to the bounds of the original image. When image_scale is a positive number, it shows your image as square pixels, using image_scale as it would the Shapes file's scale factor. Offset_x and offset_y can then be used to recenter that image.
The upshot is, if you use image_scale, the engine will use the aspect ratio of the replacement, not the aspect ratio of the original frame.
And it doesn't help you correct the aspect ratio of shapes resized to fit POT textures.
Last edited by treellama on Jun 7th '11, 14:49, edited 1 time in total.
Documentation can be fixed, but not intuitive-ness. Without the POT fix, image_scale is horribly broken anyway, so I'd scrap it in a second in favor of an easier-to-understand API.Treellama wrote:That's even less intuitive! And not documented!
To me, if image_scale were actually multiplied by the Shapes file's scale factor, it'd be a lot more intuitive. With that change, if you exported an original shape and loaded it as a replacement with an image_scale of 1, it'd look exactly the same, instead of needing an image_scale of 5. If you created a high-res version at 4x the size and used an image_scale of 0.25, it'd fit perfectly. If you used a replacement with 4x the pixels and an image_scale of 1, the monster/weapon would look 4 times bigger. If the replacement was wider, it'd be shown undistorted, with the extra pixels extending past the right of the original shape's boundary. (Centering the replacement might make more sense than anchoring the top left, although I gather some XBLA shapes have the data in the top left of a large square canvas.)
One problem with that scheme is that it doesn't really mesh well with the default, no-image_scale-specified case, where the shape is the same apparent size regardless of the number of pixels in the replacement. If you stick closer to that behavior, then you need extra margin parameters to allow for the space A.E.M. needs around the original shape boundaries.
Regardless of the eventual solution, I don't think we should feel tied to either the name or the behavior of image_scale.
It works as long as the replacement image has the correct aspect ratio when viewed in an image editor. Do we need to support replacements where the Pixel Aspect Ratio is not equal to the Display Aspect Ratio? Are the XBLA textures distorted in their raw form? Unless there's compelling existing content like that, I don't see why adjusting the aspect ratio of replacements in-engine is more important than, say, rotating or flipping them (features previously requested that we decided against adding).And it doesn't help you correct the aspect ratio of shapes resized to fit POT textures.
Heh, I would expect a 4x resolution version of an image to display at the same size as the original if image_scale is 1.0. Granted, that's not the current behavior either.Hopper wrote:To me, if image_scale were actually multiplied by the Shapes file's scale factor, it'd be a lot more intuitive. With that change, if you exported an original shape and loaded it as a replacement with an image_scale of 1, it'd look exactly the same, instead of needing an image_scale of 5. If you created a high-res version at 4x the size and used an image_scale of 0.25, it'd fit perfectly. If you used a replacement with 4x the pixels and an image_scale of 1, the monster/weapon would look 4 times bigger. If the replacement was wider, it'd be shown undistorted, with the extra pixels extending past the right of the original shape's boundary. (Centering the replacement might make more sense than anchoring the top left, although I gather some XBLA shapes have the data in the top left of a large square canvas.)
If image_scale defaulted to 1.0, then my expectation could still be met. I'm not saying it should.One problem with that scheme is that it doesn't really mesh well with the default, no-image_scale-specified case, where the shape is the same apparent size regardless of the number of pixels in the replacement.
Turns out they aren't. But they don't match the aspect ratio of the built-in shapes, and I didn't realize mucking with image_scale would use the replacement aspect ratio instead. They are a mix of padded POT DDS and cropped PNG though, so there's no getting them working without a POT padding fix.Are the XBLA textures distorted in their raw form?
I had been giving the advice to scale replacements in this way, because it makes better use of texture memory than just padding them. You may find them in shots fired, the high-res Halathon weapons (which I may have the only copy of), and Blauwe Vingers. In all of those cases, though, I believe the aspect ratio will match the one in the shapes file, and we only have to preserve the default behavior. I don't think anything sets image_scale right now, just because nobody understood it.Unless there's compelling existing content like that, I don't see why adjusting the aspect ratio of replacements in-engine is more important than, say, rotating or flipping them (features previously requested that we decided against adding).
So, I agree on not adding it.
Last edited by treellama on Jun 7th '11, 20:45, edited 1 time in total.
I think I see where you're coming from now. The current version of image_scale (assuming the POT fix) re-uses nothing from the original shape but the top left corner; it's very oriented around using knowledge from the replacement image, but not knowing or caring a lot about the original bounds -- image_scale is relative to the replacement image, not the shape. Your approach, as I understand it, modifies the original shape's bounding box, and then fits the replacement into it. That does match the default case, where the original bounding box is not modified, and the replacement is fitted into it. Let's see where this leads.Treellama wrote:Heh, I would expect a 4x resolution version of an image to display at the same size as the original if image_scale is 1.0.
A.E.M's 400% canvas replacements, then, would use a shape_scale of 4.0; the original shape's bounding box would be increased accordingly, and would contain the extra padding built into the replacement. The increased canvas and increased scale cancel each other out, so nothing appears changed. (Offsets may be necessary, depending on the anchor point we choose, but that's a separate discussion.)
To load an M1 compiler (exported from the M1A1 shapes file) in place of an M2 compiler, you'd need something to change the aspect ratio. For argument's sake, let's say the aspect_ratio attribute keeps the height constant, and resets the bounding box width to be height * aspect_ratio. I considered x_scale and y_scale instead of shape_scale and aspect_ratio, but that seems no less confusing.
The M2 compiler is 86x184; an M1A1 compiler is 63x172. You'd need an aspect_ratio of 63/172 = .3663, to match the M1A1 image. To account for the difference in height, you'd need a shape_scale of 172/184 = .9348. If the M1 compiler were stretched into a 256x256 image, or blown up to a high-res version, the same values would work, as the attributes are only changing the bounding box and don't care about the replacement's pixel dimensions at all.
For the same M1 compiler padded into a 256x256 texture instead, the aspect would be 1.0 to match the replacement's dimensions, and the shape_scale would be 256/184 = 1.3913. Because the actual compiler image only takes up 172/256 of the space, overall each pixel would take up the same space on screen as the previous example. The extra space in the shape would be blank, and it has nothing to do with the actual physics model, so it wouldn't be noticeable.
In both of the examples above, the aspect_ratio is the same as the replacement image's aspect ratio. This allows us to accept aspect-distorted images, at the expense of having to calculate the replacement dimensions and code them into the MML. To streamline that, we could reduce the float to a boolean "use replacement aspect ratio", or accept a special value like -1 to have the engine calculate and apply the replacement's native aspect ratio.
Yeah, I was imagining texture replacements as OpenGL textures. It doesn't matter whether you load a 128x128 or 1024x1024, the texture coordinates are still the same.
I was also used to the offsets the engine applies automatically to texture maps when it pads images to powers of two. It does this by changing UScale and VScale.
So, I wasn't expecting image_scale and offset_x to affect the bounding box of the sprite instead.
Maybe it would be more intuitive to separate the two: specify the new width and height of the bounding box, and use actual_width and actual_height to compensate for any padding already present in the replacement texture. Would there be any need for image_scale then?
I was also used to the offsets the engine applies automatically to texture maps when it pads images to powers of two. It does this by changing UScale and VScale.
So, I wasn't expecting image_scale and offset_x to affect the bounding box of the sprite instead.
Maybe it would be more intuitive to separate the two: specify the new width and height of the bounding box, and use actual_width and actual_height to compensate for any padding already present in the replacement texture. Would there be any need for image_scale then?
Actual_width and actual_height do make the padding cases much easier. I didn't mention them because -- wait for it -- they're not documented! I had no idea they were there.Treellama wrote:Maybe it would be more intuitive to separate the two: specify the new width and height of the bounding box, and use actual_width and actual_height to compensate for any padding already present in the replacement texture. Would there be any need for image_scale then?
I do like the idea of directly specifying the bounding box in pixels, with the defaults being the dimensions of the Shapes bitmap. Without fractional math, it's a lot easier to grasp. You're correct, we don't need image_scale any more. We do still need x and y offsets, so we can keep the x_offset and y_offset names, or rename them to go with our width and height. Maybe sprite_left, sprite_top, sprite_width, and sprite_height?
Heh, so it seems. I wonder who added thoseHopper wrote:Actual_width and actual_height do make the padding cases much easier. I didn't mention them because -- wait for it -- they're not documented! I had no idea they were there.
Do we still need to do key point alignment in the shapes? So, maybe offset_x and offset_y could be the offsets from that key point, and you'd calculate right/bottom using sprite_width and sprite_height. (how about shape_width and shape_height?)I do like the idea of directly specifying the bounding box in pixels, with the defaults being the dimensions of the Shapes bitmap. Without fractional math, it's a lot easier to grasp. You're correct, we don't need image_scale any more. We do still need x and y offsets, so we can keep the x_offset and y_offset names, or rename them to go with our width and height. Maybe sprite_left, sprite_top, sprite_width, and sprite_height?
Seems like no NPOT fix would be necessary, since the engine accounts for the padding it does with UScale and VScale, and the MML user can account for same with actual_width and actual_height? Just get the bounding box right, and even aspect ratio doesn't matter.
Last edited by treellama on Jun 9th '11, 19:12, edited 1 time in total.
Well, there's keypoint and there's origin. We definitely need to shift origin. Keypoint gets used as a distance from the origin, so offset_x and offset_y would adjust both by the same amount. We probably don't need to adjust the two independently; the current code doesn't offer that feature. (If we really wanted full control, we'd attach MML directly to frames instead of bitmaps.)Treellama wrote:Do we still need to do key point alignment in the shapes? So, maybe offset_x and offset_y could be the offsets from that key point, and you'd calculate right/bottom using sprite_width and sprite_height. (how about shape_width and shape_height?)
Any suggestions for the following functionality and documentation, then?
shape_width: the width of a substituted sprite's bounding box, in pixel units (default: the width of the original Shapes-file bitmap)shape_height: the height of a substituted sprite's bounding box, in pixel units (default: the height of the original Shapes-file bitmap)offset_x: the amount to adjust the sprite's keypoint and origin x coordinates, in pixel units (default: 0 -- do not adjust). Positive numbers move the origin to the right, which makes the sprite appear closer to the left of the screen.offset_y: the amount to adjust the sprite's keypoint and origin y coordinates, in pixel units (default: 0 -- do not adjust). Positive numbers move the origin down, which makes the sprite appear closer to the top of the screen.
Correct! The bug occurred when calculating the new bounding box based on the replacement size, which won't happen any more.Seems like no NPOT fix would be necessary, since the engine accounts for the padding it does with UScale and VScale, and the MML user can account for same with actual_width and actual_height? Just get the bounding box right, and even aspect ratio doesn't matter.
Oops, I meant origin anyway. These attributes make sense to me.
- Ares Ex Machina
- Mjolnir Mark IV
- Posts: 614
- Joined: Jan 23rd '08, 08:07
- Contact:
Now nothing is working as it should. Understandable, since you guys have changed a few things around since beta 2. My frames are now too small and stretched. Is this how image replacement is going to work for 1.0? If so, what do I need to change in order to get my replacements looking the way they did in beta 2?Ares Ex Machina wrote:Everything is working great now.
Follow Hopper's last post in this thread. That's the implementation that went in! It should be in MML.html too I hope.Ares Ex Machina wrote:Now nothing is working as it should. Understandable, since you guys have changed a few things around since beta 2. My frames are now too small and stretched. Is this how image replacement is going to work for 1.0? If so, what do I need to change in order to get my replacements looking the way they did in beta 2?
- Ares Ex Machina
- Mjolnir Mark IV
- Posts: 614
- Joined: Jan 23rd '08, 08:07
- Contact:
Ok, thanks! Wasn't sure which one of those posts (if any) was relevant. Everything's working fine again.Treellama wrote:Follow Hopper's last post in this thread. That's the implementation that went in! It should be in MML.html too I hope.
Last edited by Ares Ex Machina on Jul 3rd '11, 22:03, edited 1 time in total.
- Ares Ex Machina
- Mjolnir Mark IV
- Posts: 614
- Joined: Jan 23rd '08, 08:07
- Contact:
Happy Bungie Day! These weapons are done! Try them out!
Here's what the new muzzle flash graphics look like:
[attachment=4857:shotgun.png]
[attachment=4855:magnum.png]
[attachment=4856:fusion.png]
[attachment=4858:ar.png]
[attachment=4859:alien.png]
Here's what the new muzzle flash graphics look like:
[attachment=4857:shotgun.png]
[attachment=4855:magnum.png]
[attachment=4856:fusion.png]
[attachment=4858:ar.png]
[attachment=4859:alien.png]
- Attachments
-
- alien.png (1.06 MiB) Viewed 17339 times
-
- ar.png (1.31 MiB) Viewed 17340 times
-
- shotgun.png (920.03 KiB) Viewed 17340 times
-
- fusion.png (1013.43 KiB) Viewed 17340 times
-
- magnum.png (1.2 MiB) Viewed 17339 times
Might want to mention they require Aleph One 1.0b3, before the 1-star HOW DO I MUZZLE FLASHED WEAPON? reviews start rolling in!
- Ares Ex Machina
- Mjolnir Mark IV
- Posts: 614
- Joined: Jan 23rd '08, 08:07
- Contact:
Good point, thanks!Treellama wrote:Might want to mention they require Aleph One 1.0b3, before the 1-star HOW DO I MUZZLE FLASHED WEAPON? reviews start rolling in!