Merge PR #2012 from greatmastermario
This commit is contained in:
commit
03cb8eeaeb
|
@ -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).
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue