How to create a visualization of cached chunks?
mvrozanti opened this issue ยท 29 comments
What do you need help with?
I want to use the cached chunks to create an image to visually represent what chunks have been visited. Is this currently possible, using the *.bcr files generated?
Final checklist
- I know how to properly use check boxes
- I have not used any OwO's or UwU's in this issue.
Yea, this was possible at some point. I don't think it was ever merged into master due to stability?
Sorry, that's not what I meant.
I want to serialize the chunks to an image file, not render it in-game. The functionality should work as described in this Impact issue, to which you replied by the way :)
Like, I'd imagine that if we take the top-side texture of each block that is immediately under the highest air block (or sequence of vertically aligned air blocks) in a given X,Z coordinate (or if it is the highest block at that location), we can stitch an image that represents that coordinate correctly. Then we stitch chunks together and then stitch regions together or something like that.
We could worry about block rotation in the future, if that works.
Can we extract every BlockPos
in a bcr file though? Because if so, we can visualize it with a little effort
ICachedRegion cr = ctx.worldData().getCachedWorld().getRegion(0, 0);
This is pretty much it, I think. We just need to:
- List every cached region for current server
- For each region, extract every block contained in it
- For every block in the region map the image for that block in the correct relative position (possibly a
BufferedImage
?) - Save that to a png
Is this a wanted feature?
Textures can be found at .minecraft/versions/1.15.2.jar/assets/minecraft/textures/block/, and this tutorial shows how to concatenate images.
for me #66 looks similar to this
@ZacSharp It really does. But development on that branch seems discontinued?
It also seems overcomplicated. Why bring a "Web UI" into it? Or shading. Bitwise operations.
I'm not even sure what they meant to do and there seems to be no corresponding issue to that PR. But thanks for pointing it out, maybe something is salvageable
Well, development is really discontinued there ๐
They didn't touch the Web UI there, just talk about it. I also think the goal seems to be slightly different (you want to create a image that contains all faces with full resolution, oldgalileo kinda tried to mimic the vanilla map behaviour) and the bitwise operations are there to assemble r, b and g values into one rgb value.
Yes there is no issue for it because it is perfectly possible to just start developing a feature without opening an issue first.
BTW I think you will need to reduce the resolution as well because default render distance with a 16x16 texturepack with 21*16*16 x 21*16*16 = 5376 x 5376
pixels is already a 5k image.
Good point. I assume we could use a single pixel for each block and the color of that pixel could be the average color in that block's texture. Maybe the resolution can be adjusted (and turned adjustable?) in the future.
Imo I'd love an option for full textures, even if it takes a while to export would be cool for making desktop wallpapers
The part I'm most interested in right now is how to calculate the block coordinates of the corners of a given region, so we can query the block IDs contained in that region. This is an example for the region 0,0 (in region coordinates), I'm just not sure if this is right:
public static Map<String, int[]> getBlockCoordsOfRegionCorners(int regionX, int regionZ) { // region coordinates
int[] northwest = new int[]{
x * 512,
z * 512,
};
int[] northeast = new int[]{
(x + 1) * 512 - 1,
z * 512,
};
int[] southwest = new int[]{
x * 512,
(z + 1) * 512 - 1,
};
int[] southeast = new int[]{
(x + 1) * 512 - 1,
(z + 1) * 512 - 1,
};
return new HashMap<String, int[]>() {
{
put("NW", northwest);
put("NE", northeast);
put("SW", southwest);
put("SE", southeast);
}
};
}
In this thread, there's an algorithm to check if a coordinate belongs to a given chunk, which may or may not help.
EDIT: can anyone agree or disagree on that
I'd rely on your IDEs autocomplete for that. I'm on mobile otherwise I'd check myself
There's Block.BLOCK_STATE_IDS#get
, but it returns an integer. I'd like the namespaced ID.
This is region 0,0 of my favorite server. We are now able to create a per-region image. We just need to efficiently stitch them together and serialize it.
I've been reading about image formats and bitmap is an interesting one because we don't have to have the image loaded to append to it. I think this will be the most difficult part.
Shouldn't the image be coloured?
EDIT: It definitely should be. Although baritone only caches most blocks a one of AVOID, SOLID, AIR and WASTER it does additionally cache the full blockstate of some interesting blocks and the top layer, which is everything we need here
bitmap is an interesting one because we don't have to have the image loaded to append to it
As far as I know that's only half true. We can in fact just append new lines to the bottom of it but when we want to append to the side we need to rewrite the whole file. It still has a benefit over the compressed formats because we don't need to have it loaded at once even when appending to the side. We can just read it line by line and write every line plus our addition straight to the output and forget them (which results a lot of IO operations though).
Shouldn't the image be coloured?
Yeah, I'm not really sure why it didn't turn out to be colored inside the square. The rest being black is expected though, since it's all bedrock (or, its average color).
My mistake, well pointed out. I just copy pasted it from some stackoverflow thread
I'm closing this because there's absolutely no way I'm solving that bug of baritone not being able to load cached chunks (described in PR #2257) on my own.
Color(sumr / num, sumg / num, sumb / num)
Because you are using int
for sumr
, sumg
, sumb
and num
the result of the divisions is trucated to be an in as well. You need to make at least one of the variables in each division (I suggest num because it is used in all of them) to float or double so the result is a float/double.