Merge PR #2012 from greatmastermario

This commit is contained in:
Nicolas F 2022-05-16 20:03:48 +02:00
commit 03cb8eeaeb
10 changed files with 52 additions and 37 deletions

View File

@ -1101,10 +1101,10 @@ Depth
**Options**
min
lowest level of blocks to render. Default: 0
lowest level of blocks to render. Default: -64
max
highest level of blocks to render. Default: 255
highest level of blocks to render. Default: 319
Exposed
Only renders blocks that are exposed (adjacent to a transparent block).

View File

@ -29,7 +29,7 @@ tiles that can be displayed with a Leaflet interface. This section goes over how
Minecraft worlds work and are stored.
A Minecraft world extends indefinitely along the two horizontal axes, and are
exactly 256 units high. Minecraft worlds are made of voxels (volumetric pixels),
exactly 384 units high. Minecraft worlds are made of voxels (volumetric pixels),
hereby called "blocks", where each block in the world's grid has a type that
determines what it is (grass, stone, ...). This makes worlds relatively
uncomplicated to render, the Overviewer simply determines what blocks to draw
@ -40,15 +40,15 @@ iteratively.
The coordinate system for Minecraft has three axes. The X and Z axes are the
horizontal axes. They extend indefinitely towards both positive and negative
infinity. (There are practical limits, but no theoretical limits). The Y axis
extends from 0 to 255, which corresponds with the world height limit. Each
extends from -64 to 319, which corresponds with the world height limit. Each
block in Minecraft has a coordinate address, e.g. the block at 15,78,-35 refers
to 15 along the X axis, -35 along the Z axis, and 78 units up from bedrock.
The world is organized in a three-layer hierarchy. At the finest level are the
blocks (voxels). A 16x16x16 array of blocks is called a *chunk section*. A
vertical column of 16 chunk sections makes a *chunk*. A chunk is therefore a 16
vertical column of 24 chunk sections makes a *chunk*. A chunk is therefore a 16
by 16 area of the world that extends from bedrock to sky. In other words, a 16
by 256 by 16 "chunk" of the world. A 32 by 32 area of chunks is called a
by 384 by 16 "chunk" of the world. A 32 by 32 area of chunks is called a
*region*. Regions are stored on disk one per file.
While blocks have a global coordinate (the ones you see in the debug output
@ -355,7 +355,8 @@ origin being at the left corner.
To ensure that block closer to the viewer are drawn on top while blocks that
should be obstructed are drawn are hidden, the blocks are drawn one layer at a
time from bottom to top (Y=0 to Y=15) and from back to front.
time from bottom to top (Y=0 to Y=23, corresponding to sections Y=-4 to Y=19)
and from back to front.
From the data file on disk, block information in a chunk is a three-dimensional
array of bytes, each representing a `block id
@ -372,12 +373,12 @@ Now that we know how to draw a single chunk, let's move on to how to place
chunks relative to each other.
Before we get started, let's take a moment to remember that one chunk section is
only 1/16th of a chunk:
only 1/24th of a chunk:
.. image:: tilerendering/entirechunk.png
:alt: An entire chunk
A chunk is 16 chunk sections stacked together.
A chunk is 24 chunk sections stacked together.
Since this is pretty tall, the diagrams in this section are simplified to only
show the *top face* of a chunk, as shown in green here:
@ -504,7 +505,7 @@ pixels.
The rendering routines takes the given range of columns and rows, converts it
back into chunk coordinates, and renders the given 8 chunks plus all chunks from
the 16 rows above the given range (see the note below). The chunks are
the 24 rows above the given range (see the note below). The chunks are
positioned correctly with the above positioning rules, so any chunks that are
out of the bounds get rendered off the tile and don't affect the final image.
(There is therefore no penalty for rendering out-of-bounds chunks for a tile

View File

@ -622,7 +622,7 @@ overviewer.util = {
lat += 6 * z * perPixel;
// each block down along Z adds 12px to y
lat += 12 * (256 - y) * perPixel;
lat += 12 * (320 - y) * perPixel;
// add on 12 px to the X coordinate to center our point
lng += 12 * perPixel;
@ -678,8 +678,8 @@ overviewer.util = {
// only latitude and longitude, so assume Y=64. Since this is lowering
// down from the height of a chunk, it depends on the chunk height as
// so:
point.x += 256-64;
point.z -= 256-64;
point.x += 320-64;
point.z -= 320-64;
if(north_direction == overviewerConfig.CONST.UPPERRIGHT){
temp = point.z;

View File

@ -67,8 +67,8 @@ class HeightFading(RenderPrimitive):
class Depth(RenderPrimitive):
name = "depth"
options = {
"min": ("lowest level of blocks to render", 0),
"max": ("highest level of blocks to render", 255),
"min": ("lowest level of blocks to render", -64),
"max": ("highest level of blocks to render", 319),
}
class Exposed(RenderPrimitive):

View File

@ -178,7 +178,7 @@ bool load_chunk(RenderState* state, int32_t x, int32_t z, uint8_t required) {
if (!ycoord)
continue;
sectiony = PyLong_AsLong(ycoord);
sectiony = PyLong_AsLong(ycoord) + 4;
if (sectiony >= 0 && sectiony < SECTIONS_PER_CHUNK)
load_chunk_section(dest, sectiony, section);
}
@ -353,7 +353,7 @@ generate_pseudo_data(RenderState* state, uint16_t ancilData) {
/* calculate the global block coordinates of this position */
wx = (state->chunkx * 16) + x;
wz = (state->chunkz * 16) + z;
wy = (state->chunky * 16) + y;
wy = ((state->chunky - 4) * 16) + y;
/* lilypads orientation is obtained with these magic numbers */
/* magic numbers obtained from: */
/* http://llbit.se/?p=1537 */

View File

@ -31,7 +31,7 @@
// increment this value if you've made a change to the c extension
// and want to force users to rebuild
#define OVERVIEWER_EXTENSION_VERSION 107
#define OVERVIEWER_EXTENSION_VERSION 109
#include <stdbool.h>
#include <stdint.h>
@ -78,7 +78,7 @@ PyObject* resize_half_wrap(PyObject* self, PyObject* args);
typedef struct _RenderMode RenderMode;
/* in iterate.c */
#define SECTIONS_PER_CHUNK 16
#define SECTIONS_PER_CHUNK 24
typedef struct {
/* whether this chunk is loaded: use load_chunk to load */
int32_t loaded;

View File

@ -37,7 +37,7 @@ depth_start(void* data, RenderState* state, PyObject* support) {
static bool
depth_hidden(void* data, RenderState* state, int32_t x, int32_t y, int32_t z) {
PrimitiveDepth* self = (PrimitiveDepth*)data;
y += 16 * state->chunky;
y += 16 * (state->chunky - 4);
if (y > self->max || y < self->min) {
return true;
}

View File

@ -17,10 +17,10 @@
#include "../overviewer.h"
#define NETHER_ROOF 127
#define NETHER_ROOF 191
#define WIDTH 16
#define DEPTH 16
#define HEIGHT 256
#define HEIGHT 384
// add two to these because the primative functions should expect to
// deal with x and z values of -1 and 16

View File

@ -92,6 +92,8 @@ do_work(workobj)
"""
TILESET_VERSION = 2 # Update this whenever there is a breaking change with tile renders
# small but useful
def iterate_base4(d):
"""Iterates over a base 4 number with d digits"""
@ -309,6 +311,7 @@ class TileSet(object):
self.last_rendertime = config.get('last_rendertime', 0)
self.forcerendertime = config.get('forcerendertime', 0)
self.lastrenderversion = config.get('lastrenderversion', 0)
if "renderchecks" not in self.options:
# renderchecks was not given, this indicates it was not specified
@ -318,20 +321,25 @@ class TileSet(object):
# No persistent config?
if os.path.exists(self.outputdir):
# Somehow there's no config but the output dir DOES exist.
# That's strange!
# That's strange! Run forcerender in case of breaking OV version change
logging.warning(
"For render '%s' I couldn't find any persistent config, "
"but I did find my tile directory already exists. This "
"shouldn't normally happen, something may be up, but I "
"think I can continue...", self.options['name'])
logging.info("Switching to --check-tiles mode")
self.options['renderchecks'] = 1
logging.info("Switching to --forcerender mode")
self.options['renderchecks'] = 2
else:
# This is the typical code path for an initial render, make
# this a "forcerender"
self.options['renderchecks'] = 2
logging.debug("This is the first time rendering %s. Doing "
"a full-render", self.options['name'])
elif self.lastrenderversion != TILESET_VERSION:
# Force render in case there is a version change that is breaking
logging.warning("Re-rendering world due to version change."
"This will avoid any bad rendering between incompatible versions")
self.options['renderchecks'] = 2
elif not os.path.exists(self.outputdir):
# Somehow the outputdir got erased but the metadata file is
# still there. That's strange!
@ -377,6 +385,11 @@ class TileSet(object):
self.options['renderchecks'] = 2
os.mkdir(self.outputdir)
if self.lastrenderversion != TILESET_VERSION and self.options['renderchecks'] not in [2, 3]:
logging.warning("Normally renders from different versions should be"
"overridden or ignored to prevent incompatibilities,"
"but we will honor your decision.")
# must wait until outputdir exists
self.fs_caps = get_fs_caps(self.outputdir)
@ -591,7 +604,8 @@ class TileSet(object):
poititle=self.options.get("poititle"),
showlocationmarker=self.options.get("showlocationmarker"),
center=(self.options.get("center") or self.options.get("spawn")
or [0, 64, 0])
or [0, 64, 0]),
lastrenderversion=TILESET_VERSION
)
d['maxZoom'] = self.options.get('maxzoom', self.treedepth)
if d['maxZoom'] < 0:
@ -1081,7 +1095,7 @@ class TileSet(object):
max_chunk_mtime = 0
for col, row, chunkx, chunky, chunkz, chunk_mtime in chunks:
xpos = -192 + (col - colstart) * 192
ypos = -96 + (row - rowstart) * 96 + (16 - 1 - chunky) * 192
ypos = -96 + (row - rowstart) * 96 + (24 - 1 - chunky) * 192
if chunk_mtime > max_chunk_mtime:
max_chunk_mtime = chunk_mtime
@ -1324,12 +1338,12 @@ def get_tiles_by_chunk(chunkcol, chunkrow):
colrange = (tilecol,)
# If this chunk is in a row divisible by 4, then it touches the
# tile above it as well. Also touches the next 4 tiles down (16
# tile above it as well. Also touches the next 6 tiles down (24
# rows)
if chunkrow % 4 == 0:
rowrange = range(tilerow - 4, tilerow + 32 + 1, 4)
rowrange = range(tilerow - 4, tilerow + 48 + 1, 4)
else:
rowrange = range(tilerow, tilerow + 32 + 1, 4)
rowrange = range(tilerow, tilerow + 48 + 1, 4)
return product(colrange, rowrange)
@ -1360,12 +1374,12 @@ def get_chunks_by_tile(tile, regionset):
# First do the odd. For each chunk in the tile's odd column the tile
# "passes through" three chunk sections.
oddcol_sections = []
for i, y in enumerate(reversed(range(16))):
for i, y in enumerate(reversed(range(24))):
for row in range(tile.row + 3 - i * 2, tile.row - 2 - i * 2, -2):
oddcol_sections.append((tile.col + 1, row, y))
evencol_sections = []
for i, y in enumerate(reversed(range(16))):
for i, y in enumerate(reversed(range(24))):
for row in range(tile.row + 4 - i * 2, tile.row - 3 - i * 2, -2):
evencol_sections.append((tile.col + 2, row, y))
evencol_sections.append((tile.col, row, y))

View File

@ -198,10 +198,10 @@ class World(object):
disp_spawnZ = spawnZ = data['SpawnZ']
## clamp spawnY to a sane value, in-chunk value
if spawnY < 0:
spawnY = 0
if spawnY > 255:
spawnY = 255
if spawnY < -63:
spawnY = -63
if spawnY > 319:
spawnY = 319
## The chunk that holds the spawn location
chunkX = spawnX//16
@ -236,7 +236,7 @@ class World(object):
spawnY += 1
# Next section, start at local 0
inChunkY = 0
return spawnX, 256, spawnZ
return spawnX, 320, spawnZ
class RegionSet(object):
"""This object is the gateway to a particular Minecraft dimension within a