Weapons In Hand

Discuss and unveil current Marathon projects.
User avatar
Hopper
Mjolnir Mark IV
Posts: 585
Joined: May 10th '09, 17:02
Contact:

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]
Attachments
Weapons_In_Hand__Expanded_Canvas.zip
(13.78 KiB) Downloaded 353 times
Aleph One:  Download 1.2.1         Plugins:  Vasara  ·  more
User avatar
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.
User avatar
Hopper
Mjolnir Mark IV
Posts: 585
Joined: May 10th '09, 17:02
Contact:

Ares Ex Machina wrote:how did you get -570 and -770 for your mml offsetting?
I didn't; as far as I can tell, the attachment above has -250 and -250 in the mml...

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"/>
Aleph One:  Download 1.2.1         Plugins:  Vasara  ·  more
User avatar
treellama
Vidmaster
Posts: 6110
Joined: Jun 2nd '06, 02:05
Location: Pittsburgh
Contact:

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.
Should we fix this?

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.
User avatar
Ares Ex Machina
Mjolnir Mark IV
Posts: 614
Joined: Jan 23rd '08, 08:07
Contact:

Hopper wrote:I didn't; as far as I can tell, the attachment above has -250 and -250 in the mml...
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.

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.
User avatar
Hopper
Mjolnir Mark IV
Posts: 585
Joined: May 10th '09, 17:02
Contact:

Treellama wrote:Should we fix this?
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.

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.
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.
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.
Aleph One:  Download 1.2.1         Plugins:  Vasara  ·  more
User avatar
Hopper
Mjolnir Mark IV
Posts: 585
Joined: May 10th '09, 17:02
Contact:

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?
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.

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?
Aleph One:  Download 1.2.1         Plugins:  Vasara  ·  more
User avatar
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.
User avatar
treellama
Vidmaster
Posts: 6110
Joined: Jun 2nd '06, 02:05
Location: Pittsburgh
Contact:

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.
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...
User avatar
Hopper
Mjolnir Mark IV
Posts: 585
Joined: May 10th '09, 17:02
Contact:

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...
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.
Aleph One:  Download 1.2.1         Plugins:  Vasara  ·  more
User avatar
treellama
Vidmaster
Posts: 6110
Joined: Jun 2nd '06, 02:05
Location: Pittsburgh
Contact:

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.
That's even less intuitive! And not documented!

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.
User avatar
Hopper
Mjolnir Mark IV
Posts: 585
Joined: May 10th '09, 17:02
Contact:

Treellama wrote:That's even less intuitive! And not documented!
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.

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.
And it doesn't help you correct the aspect ratio of shapes resized to fit POT textures.
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).
Aleph One:  Download 1.2.1         Plugins:  Vasara  ·  more
User avatar
treellama
Vidmaster
Posts: 6110
Joined: Jun 2nd '06, 02:05
Location: Pittsburgh
Contact:

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.)
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.
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 image_scale defaulted to 1.0, then my expectation could still be met. I'm not saying it should.
Are the XBLA textures distorted in their raw form?
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.
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).
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.

So, I agree on not adding it.
Last edited by treellama on Jun 7th '11, 20:45, edited 1 time in total.
User avatar
Hopper
Mjolnir Mark IV
Posts: 585
Joined: May 10th '09, 17:02
Contact:

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.
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.

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.
Aleph One:  Download 1.2.1         Plugins:  Vasara  ·  more
User avatar
treellama
Vidmaster
Posts: 6110
Joined: Jun 2nd '06, 02:05
Location: Pittsburgh
Contact:

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?
User avatar
Hopper
Mjolnir Mark IV
Posts: 585
Joined: May 10th '09, 17:02
Contact:

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?
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.

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?
Aleph One:  Download 1.2.1         Plugins:  Vasara  ·  more
User avatar
treellama
Vidmaster
Posts: 6110
Joined: Jun 2nd '06, 02:05
Location: Pittsburgh
Contact:

Hopper 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.
Heh, so it seems. I wonder who added those :)
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?
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?)

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.
User avatar
Hopper
Mjolnir Mark IV
Posts: 585
Joined: May 10th '09, 17:02
Contact:

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?)
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.)

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.
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.
Correct! The bug occurred when calculating the new bounding box based on the replacement size, which won't happen any more.
Aleph One:  Download 1.2.1         Plugins:  Vasara  ·  more
User avatar
treellama
Vidmaster
Posts: 6110
Joined: Jun 2nd '06, 02:05
Location: Pittsburgh
Contact:

Oops, I meant origin anyway. These attributes make sense to me.
User avatar
Ares Ex Machina
Mjolnir Mark IV
Posts: 614
Joined: Jan 23rd '08, 08:07
Contact:

Ares Ex Machina wrote:Everything is working great now.
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?
User avatar
treellama
Vidmaster
Posts: 6110
Joined: Jun 2nd '06, 02:05
Location: Pittsburgh
Contact:

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?
Follow Hopper's last post in this thread. That's the implementation that went in! It should be in MML.html too I hope.
User avatar
Ares Ex Machina
Mjolnir Mark IV
Posts: 614
Joined: Jan 23rd '08, 08:07
Contact:

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.
Ok, thanks! Wasn't sure which one of those posts (if any) was relevant. Everything's working fine again. [MUp]
Last edited by Ares Ex Machina on Jul 3rd '11, 22:03, edited 1 time in total.
User avatar
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]
Attachments
alien.png
alien.png (1.06 MiB) Viewed 17339 times
ar.png
ar.png (1.31 MiB) Viewed 17340 times
shotgun.png
shotgun.png (920.03 KiB) Viewed 17340 times
fusion.png
fusion.png (1013.43 KiB) Viewed 17340 times
magnum.png
magnum.png (1.2 MiB) Viewed 17339 times
User avatar
treellama
Vidmaster
Posts: 6110
Joined: Jun 2nd '06, 02:05
Location: Pittsburgh
Contact:

Might want to mention they require Aleph One 1.0b3, before the 1-star HOW DO I MUZZLE FLASHED WEAPON? reviews start rolling in!
User avatar
Ares Ex Machina
Mjolnir Mark IV
Posts: 614
Joined: Jan 23rd '08, 08:07
Contact:

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!
Good point, thanks!
Post Reply