Skip to content

Commit 03cb8ee

Browse files
committed
Merge PR #2012 from greatmastermario
2 parents 7171af5 + f80936c commit 03cb8ee

File tree

10 files changed

+52
-37
lines changed

10 files changed

+52
-37
lines changed

docs/config.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,10 +1101,10 @@ Depth
11011101
**Options**
11021102

11031103
min
1104-
lowest level of blocks to render. Default: 0
1104+
lowest level of blocks to render. Default: -64
11051105

11061106
max
1107-
highest level of blocks to render. Default: 255
1107+
highest level of blocks to render. Default: 319
11081108

11091109
Exposed
11101110
Only renders blocks that are exposed (adjacent to a transparent block).

docs/design/designdoc.rst

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ tiles that can be displayed with a Leaflet interface. This section goes over how
2929
Minecraft worlds work and are stored.
3030

3131
A Minecraft world extends indefinitely along the two horizontal axes, and are
32-
exactly 256 units high. Minecraft worlds are made of voxels (volumetric pixels),
32+
exactly 384 units high. Minecraft worlds are made of voxels (volumetric pixels),
3333
hereby called "blocks", where each block in the world's grid has a type that
3434
determines what it is (grass, stone, ...). This makes worlds relatively
3535
uncomplicated to render, the Overviewer simply determines what blocks to draw
@@ -40,15 +40,15 @@ iteratively.
4040
The coordinate system for Minecraft has three axes. The X and Z axes are the
4141
horizontal axes. They extend indefinitely towards both positive and negative
4242
infinity. (There are practical limits, but no theoretical limits). The Y axis
43-
extends from 0 to 255, which corresponds with the world height limit. Each
43+
extends from -64 to 319, which corresponds with the world height limit. Each
4444
block in Minecraft has a coordinate address, e.g. the block at 15,78,-35 refers
4545
to 15 along the X axis, -35 along the Z axis, and 78 units up from bedrock.
4646

4747
The world is organized in a three-layer hierarchy. At the finest level are the
4848
blocks (voxels). A 16x16x16 array of blocks is called a *chunk section*. A
49-
vertical column of 16 chunk sections makes a *chunk*. A chunk is therefore a 16
49+
vertical column of 24 chunk sections makes a *chunk*. A chunk is therefore a 16
5050
by 16 area of the world that extends from bedrock to sky. In other words, a 16
51-
by 256 by 16 "chunk" of the world. A 32 by 32 area of chunks is called a
51+
by 384 by 16 "chunk" of the world. A 32 by 32 area of chunks is called a
5252
*region*. Regions are stored on disk one per file.
5353

5454
While blocks have a global coordinate (the ones you see in the debug output
@@ -355,7 +355,8 @@ origin being at the left corner.
355355

356356
To ensure that block closer to the viewer are drawn on top while blocks that
357357
should be obstructed are drawn are hidden, the blocks are drawn one layer at a
358-
time from bottom to top (Y=0 to Y=15) and from back to front.
358+
time from bottom to top (Y=0 to Y=23, corresponding to sections Y=-4 to Y=19)
359+
and from back to front.
359360

360361
From the data file on disk, block information in a chunk is a three-dimensional
361362
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
372373
chunks relative to each other.
373374

374375
Before we get started, let's take a moment to remember that one chunk section is
375-
only 1/16th of a chunk:
376+
only 1/24th of a chunk:
376377

377378
.. image:: tilerendering/entirechunk.png
378379
:alt: An entire chunk
379380

380-
A chunk is 16 chunk sections stacked together.
381+
A chunk is 24 chunk sections stacked together.
381382

382383
Since this is pretty tall, the diagrams in this section are simplified to only
383384
show the *top face* of a chunk, as shown in green here:
@@ -504,7 +505,7 @@ pixels.
504505

505506
The rendering routines takes the given range of columns and rows, converts it
506507
back into chunk coordinates, and renders the given 8 chunks plus all chunks from
507-
the 16 rows above the given range (see the note below). The chunks are
508+
the 24 rows above the given range (see the note below). The chunks are
508509
positioned correctly with the above positioning rules, so any chunks that are
509510
out of the bounds get rendered off the tile and don't affect the final image.
510511
(There is therefore no penalty for rendering out-of-bounds chunks for a tile

overviewer_core/data/js_src/util.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -622,7 +622,7 @@ overviewer.util = {
622622
lat += 6 * z * perPixel;
623623

624624
// each block down along Z adds 12px to y
625-
lat += 12 * (256 - y) * perPixel;
625+
lat += 12 * (320 - y) * perPixel;
626626

627627
// add on 12 px to the X coordinate to center our point
628628
lng += 12 * perPixel;
@@ -678,8 +678,8 @@ overviewer.util = {
678678
// only latitude and longitude, so assume Y=64. Since this is lowering
679679
// down from the height of a chunk, it depends on the chunk height as
680680
// so:
681-
point.x += 256-64;
682-
point.z -= 256-64;
681+
point.x += 320-64;
682+
point.z -= 320-64;
683683

684684
if(north_direction == overviewerConfig.CONST.UPPERRIGHT){
685685
temp = point.z;

overviewer_core/rendermodes.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ class HeightFading(RenderPrimitive):
6767
class Depth(RenderPrimitive):
6868
name = "depth"
6969
options = {
70-
"min": ("lowest level of blocks to render", 0),
71-
"max": ("highest level of blocks to render", 255),
70+
"min": ("lowest level of blocks to render", -64),
71+
"max": ("highest level of blocks to render", 319),
7272
}
7373

7474
class Exposed(RenderPrimitive):

overviewer_core/src/iterate.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ bool load_chunk(RenderState* state, int32_t x, int32_t z, uint8_t required) {
178178
if (!ycoord)
179179
continue;
180180

181-
sectiony = PyLong_AsLong(ycoord);
181+
sectiony = PyLong_AsLong(ycoord) + 4;
182182
if (sectiony >= 0 && sectiony < SECTIONS_PER_CHUNK)
183183
load_chunk_section(dest, sectiony, section);
184184
}
@@ -353,7 +353,7 @@ generate_pseudo_data(RenderState* state, uint16_t ancilData) {
353353
/* calculate the global block coordinates of this position */
354354
wx = (state->chunkx * 16) + x;
355355
wz = (state->chunkz * 16) + z;
356-
wy = (state->chunky * 16) + y;
356+
wy = ((state->chunky - 4) * 16) + y;
357357
/* lilypads orientation is obtained with these magic numbers */
358358
/* magic numbers obtained from: */
359359
/* http://llbit.se/?p=1537 */

overviewer_core/src/overviewer.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131

3232
// increment this value if you've made a change to the c extension
3333
// and want to force users to rebuild
34-
#define OVERVIEWER_EXTENSION_VERSION 107
34+
#define OVERVIEWER_EXTENSION_VERSION 109
3535

3636
#include <stdbool.h>
3737
#include <stdint.h>
@@ -78,7 +78,7 @@ PyObject* resize_half_wrap(PyObject* self, PyObject* args);
7878
typedef struct _RenderMode RenderMode;
7979

8080
/* in iterate.c */
81-
#define SECTIONS_PER_CHUNK 16
81+
#define SECTIONS_PER_CHUNK 24
8282
typedef struct {
8383
/* whether this chunk is loaded: use load_chunk to load */
8484
int32_t loaded;

overviewer_core/src/primitives/depth.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ depth_start(void* data, RenderState* state, PyObject* support) {
3737
static bool
3838
depth_hidden(void* data, RenderState* state, int32_t x, int32_t y, int32_t z) {
3939
PrimitiveDepth* self = (PrimitiveDepth*)data;
40-
y += 16 * state->chunky;
40+
y += 16 * (state->chunky - 4);
4141
if (y > self->max || y < self->min) {
4242
return true;
4343
}

overviewer_core/src/primitives/nether.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717

1818
#include "../overviewer.h"
1919

20-
#define NETHER_ROOF 127
20+
#define NETHER_ROOF 191
2121
#define WIDTH 16
2222
#define DEPTH 16
23-
#define HEIGHT 256
23+
#define HEIGHT 384
2424

2525
// add two to these because the primative functions should expect to
2626
// deal with x and z values of -1 and 16

overviewer_core/tileset.py

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@
9292
"""
9393

9494

95+
TILESET_VERSION = 2 # Update this whenever there is a breaking change with tile renders
96+
9597
# small but useful
9698
def iterate_base4(d):
9799
"""Iterates over a base 4 number with d digits"""
@@ -309,6 +311,7 @@ def __init__(self, worldobj, regionsetobj, assetmanagerobj, texturesobj, options
309311

310312
self.last_rendertime = config.get('last_rendertime', 0)
311313
self.forcerendertime = config.get('forcerendertime', 0)
314+
self.lastrenderversion = config.get('lastrenderversion', 0)
312315

313316
if "renderchecks" not in self.options:
314317
# renderchecks was not given, this indicates it was not specified
@@ -318,20 +321,25 @@ def __init__(self, worldobj, regionsetobj, assetmanagerobj, texturesobj, options
318321
# No persistent config?
319322
if os.path.exists(self.outputdir):
320323
# Somehow there's no config but the output dir DOES exist.
321-
# That's strange!
324+
# That's strange! Run forcerender in case of breaking OV version change
322325
logging.warning(
323326
"For render '%s' I couldn't find any persistent config, "
324327
"but I did find my tile directory already exists. This "
325328
"shouldn't normally happen, something may be up, but I "
326329
"think I can continue...", self.options['name'])
327-
logging.info("Switching to --check-tiles mode")
328-
self.options['renderchecks'] = 1
330+
logging.info("Switching to --forcerender mode")
331+
self.options['renderchecks'] = 2
329332
else:
330333
# This is the typical code path for an initial render, make
331334
# this a "forcerender"
332335
self.options['renderchecks'] = 2
333336
logging.debug("This is the first time rendering %s. Doing "
334337
"a full-render", self.options['name'])
338+
elif self.lastrenderversion != TILESET_VERSION:
339+
# Force render in case there is a version change that is breaking
340+
logging.warning("Re-rendering world due to version change."
341+
"This will avoid any bad rendering between incompatible versions")
342+
self.options['renderchecks'] = 2
335343
elif not os.path.exists(self.outputdir):
336344
# Somehow the outputdir got erased but the metadata file is
337345
# still there. That's strange!
@@ -377,6 +385,11 @@ def __init__(self, worldobj, regionsetobj, assetmanagerobj, texturesobj, options
377385
self.options['renderchecks'] = 2
378386
os.mkdir(self.outputdir)
379387

388+
if self.lastrenderversion != TILESET_VERSION and self.options['renderchecks'] not in [2, 3]:
389+
logging.warning("Normally renders from different versions should be"
390+
"overridden or ignored to prevent incompatibilities,"
391+
"but we will honor your decision.")
392+
380393
# must wait until outputdir exists
381394
self.fs_caps = get_fs_caps(self.outputdir)
382395

@@ -591,7 +604,8 @@ def bgcolorformat(color):
591604
poititle=self.options.get("poititle"),
592605
showlocationmarker=self.options.get("showlocationmarker"),
593606
center=(self.options.get("center") or self.options.get("spawn")
594-
or [0, 64, 0])
607+
or [0, 64, 0]),
608+
lastrenderversion=TILESET_VERSION
595609
)
596610
d['maxZoom'] = self.options.get('maxzoom', self.treedepth)
597611
if d['maxZoom'] < 0:
@@ -1081,7 +1095,7 @@ def _render_rendertile(self, tile):
10811095
max_chunk_mtime = 0
10821096
for col, row, chunkx, chunky, chunkz, chunk_mtime in chunks:
10831097
xpos = -192 + (col - colstart) * 192
1084-
ypos = -96 + (row - rowstart) * 96 + (16 - 1 - chunky) * 192
1098+
ypos = -96 + (row - rowstart) * 96 + (24 - 1 - chunky) * 192
10851099

10861100
if chunk_mtime > max_chunk_mtime:
10871101
max_chunk_mtime = chunk_mtime
@@ -1324,12 +1338,12 @@ def get_tiles_by_chunk(chunkcol, chunkrow):
13241338
colrange = (tilecol,)
13251339

13261340
# If this chunk is in a row divisible by 4, then it touches the
1327-
# tile above it as well. Also touches the next 4 tiles down (16
1341+
# tile above it as well. Also touches the next 6 tiles down (24
13281342
# rows)
13291343
if chunkrow % 4 == 0:
1330-
rowrange = range(tilerow - 4, tilerow + 32 + 1, 4)
1344+
rowrange = range(tilerow - 4, tilerow + 48 + 1, 4)
13311345
else:
1332-
rowrange = range(tilerow, tilerow + 32 + 1, 4)
1346+
rowrange = range(tilerow, tilerow + 48 + 1, 4)
13331347

13341348
return product(colrange, rowrange)
13351349

@@ -1360,12 +1374,12 @@ def get_mtime(x, y):
13601374
# First do the odd. For each chunk in the tile's odd column the tile
13611375
# "passes through" three chunk sections.
13621376
oddcol_sections = []
1363-
for i, y in enumerate(reversed(range(16))):
1377+
for i, y in enumerate(reversed(range(24))):
13641378
for row in range(tile.row + 3 - i * 2, tile.row - 2 - i * 2, -2):
13651379
oddcol_sections.append((tile.col + 1, row, y))
13661380

13671381
evencol_sections = []
1368-
for i, y in enumerate(reversed(range(16))):
1382+
for i, y in enumerate(reversed(range(24))):
13691383
for row in range(tile.row + 4 - i * 2, tile.row - 3 - i * 2, -2):
13701384
evencol_sections.append((tile.col + 2, row, y))
13711385
evencol_sections.append((tile.col, row, y))

overviewer_core/world.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -198,10 +198,10 @@ def find_true_spawn(self):
198198
disp_spawnZ = spawnZ = data['SpawnZ']
199199

200200
## clamp spawnY to a sane value, in-chunk value
201-
if spawnY < 0:
202-
spawnY = 0
203-
if spawnY > 255:
204-
spawnY = 255
201+
if spawnY < -63:
202+
spawnY = -63
203+
if spawnY > 319:
204+
spawnY = 319
205205

206206
## The chunk that holds the spawn location
207207
chunkX = spawnX//16
@@ -236,7 +236,7 @@ def find_true_spawn(self):
236236
spawnY += 1
237237
# Next section, start at local 0
238238
inChunkY = 0
239-
return spawnX, 256, spawnZ
239+
return spawnX, 320, spawnZ
240240

241241
class RegionSet(object):
242242
"""This object is the gateway to a particular Minecraft dimension within a

0 commit comments

Comments
 (0)