SwitchCraftCC / sc-peripherals

Custom peripherals for the SwitchCraft server
MIT License
10 stars 9 forks source link

[Issue] Hex values in .3dj files are converted to 0xRRGGBB formats, but hex values that go over are clamped down #32

Closed Magicmaan closed 1 year ago

Magicmaan commented 1 year ago

"The color to tint this shape. Must be of the form 0xRRGGBB. Defaults to 0xFFFFFF (white)"

This limits colours values to a max of 99,99,99. anything over just gets cut off

Using this code from the print3d program.

local function parseTint(tint) if type(tint) == "string" then return tonumber(tint, 16) elseif type(tint) == "number" then return tint else return 0xFFFFFF end end

In the example of the HEX value #551f1b, this gets converted to the RGB value of #55115111. But since its over the formatting of 0xRRGGBB, this gets clamped down to #551151.

image image image

The fix for this would be for either printer.addShape to only take HEX values, or increase the limit to 0xRRRGGGBBB, to allow for full colour range

Magicmaan commented 1 year ago

tile.zip These are the relevant files I used to test, the hex / colour values are correct in both the BB file, my plugin I used to export, and the .3dj file. From what I see the issue is entirely within the code, as it doesn't allow values over 6

Lemmmy commented 1 year ago

I think the issue is in your plugin. There are several invalid colors in your 3dj file:

"tint": "4310c" "tint": "38104" "tint": "3eeb" "tint": "13ff"

I took the actual white colors from your BB file and a few others and tested them against the function in print3d.lua:

local function parseTint(tint)
  if type(tint) == "string" then
    return tonumber(tint, 16)
  elseif type(tint) == "number" then
    return tint
  else
    return 0xFFFFFF
  end
end

print(parseTint("ffffff"))
print(parseTint("ff0000"))
print(parseTint("0000ff"))
print(parseTint("0000ff"))
print(parseTint("868686"))
print(parseTint("7c7a72"))
print(parseTint("6a655d"))

Which provided the entirely correct and expected values:

image

So I think this is a bug in your plugin, or you have a misunderstanding of hexadecimal colors. The hexadecimal number FF is a representation of the decimal number 255, which is the maximum possible brightness value in the RGB system we use. Therefore, white would be FFFFFF in hex (and 16777215 in decimal) and black would be 000000 (0 in decimal). I'm not sure where you're getting 99 or 0xRRRGGGBBB from but I think you might be confusing hexadecimal with decimal.

Looking closer I think I see what you did wrong - you converted each individual hex digit (0-9a-f) to decimal and then concatenated them. You might want a refresher on how hexadecimal works.

Can you share the code you're using to generate 3dj files?

Magicmaan commented 1 year ago

yes its correctly converted, the the printer.addshape for the tint value only takes the format 0xRRGGBB. so in the example of "16777215", this gets clamped down to only "167772". sam3djcust.zip here is my custom blockbench plugin, its for private use since I just edited the source code.


let tmp = cube.faces['up'].getTexture();
targetRectangle = cube.faces['up'].getBoundingRect();

            //console.log(targetRectangle);
            //console.log(targetRectangle.ax);

            targetCanvas = Painter.getCanvas(tmp);
            targetContext = targetCanvas.getContext('2d');

            ax = targetRectangle.ax;
            ay = targetRectangle.ay;

            console.log(ax);
            console.log(ay);
            buffer = targetContext.getImageData(targetRectangle.ax, targetRectangle.ay, 1, 1);

            var hex = [
                Math.round(buffer.data[0]).toString(16),
                Math.round(buffer.data[1]).toString(16),
                Math.round(buffer.data[2]).toString(16)
            ];```
           This is the relevant code, all it does it take the RGB value and converts it to hex. Its being correctly transcribed to from BB to the file
Lemmmy commented 1 year ago

Your current code will remove leading zeroes from numbers, which means you'll be missing important data. The color 255, 0, 255 should be FF00FF but your current code makes it FF0FF (notice the missing digit in the middle).

I'm not sure where your clamping assumption comes from, I cannot reproduce this behavior. If you look closely at the parseTint function you'll see that it accepts strings or numbers as the input. If you remove the quotes from around the tint in the 3dj JSON (e.g. "tint": 16777215), it will keep the decimal as-is instead of parsing it as a hex string.

To be clear:

I apologise if my explanations aren't quite making sense, but since the issue seems to be with your code, I'm going to close this issue. Your question is probably better suited for the Minecraft Computer Mods Discord where people will be able to help you. Please feel free to reopen this if you find a bug in sc-peripherals.

Magicmaan commented 1 year ago

Oh right sorry I misunderstood, You were correct, I wasn't adding the missing digit. Sorry about that

Lemmmy commented 1 year ago

No worries :)