diff --git a/quadtree.py b/quadtree.py index f1c4b1d..fc00b01 100644 --- a/quadtree.py +++ b/quadtree.py @@ -426,9 +426,6 @@ class QuadtreeGen(object): needs_rerender = False get_region_mtime = world.get_region_mtime for col, row, chunkx, chunky, regionfile in chunks: - # don't even check if it's not in the regionlist - if self.world.regionlist and region._filename not in self.world.regionlist: - continue # bail early if forcerender is set if self.forcerender: @@ -439,7 +436,11 @@ class QuadtreeGen(object): region,regionMtime = get_region_mtime(regionfile) if regionMtime <= tile_mtime: continue - + + # don't even check if it's not in the regionlist + if self.world.regionlist and os.path.abspath(region._filename) not in self.world.regionlist: + continue + # checking chunk mtime if region.get_chunk_timestamp(chunkx, chunky) > tile_mtime: needs_rerender = True diff --git a/sample.settings.py b/sample.settings.py index 8c85a3e..3b6aed2 100644 --- a/sample.settings.py +++ b/sample.settings.py @@ -6,7 +6,7 @@ # provide examples of interesting things you can do with the settings file. Most # of the time, a simple 'setting_name = value' will work. -# This file is a python script, so you can import and python module you wish or +# This file is a python script, so you can import any python module you wish or # use any built-in python function, though this is not normally necessary # Lines that start with a hash mark are comments diff --git a/src/rendermode-lighting.c b/src/rendermode-lighting.c index 6285724..2741cf0 100644 --- a/src/rendermode-lighting.c +++ b/src/rendermode-lighting.c @@ -33,21 +33,100 @@ static float calculate_darkness(unsigned char skylight, unsigned char blocklight * was calculated correctly from available light data, it will be true. You * may (and probably should) pass NULL. */ + +inline unsigned char +estimate_blocklevel(RenderModeLighting *self, RenderState *state, + int x, int y, int z, int *authoratative) { + + /* placeholders for later data arrays, coordinates */ + PyObject *blocks = NULL; + PyObject *blocklight = NULL; + int local_x = x, local_y = y, local_z = z; + unsigned char block, blocklevel; + unsigned int average_count = 0, average_gather = 0, coeff = 0; + + /* defaults to "guess" until told otherwise */ + if (authoratative) + *authoratative = 0; + + /* find out what chunk we're in, and translate accordingly */ + if (x >= 0 && y < 16) { + blocks = state->blocks; + blocklight = self->blocklight; + } else if (x < 0) { + local_x += 16; + blocks = state->left_blocks; + blocklight = self->left_blocklight; + } else if (y >= 16) { + local_y -= 16; + blocks = state->right_blocks; + blocklight = self->right_blocklight; + } + + /* make sure we have correctly-ranged coordinates */ + if (!(local_x >= 0 && local_x < 16 && + local_y >= 0 && local_y < 16 && + local_z >= 0 && local_z < 128)) { + + return 0; + } + + /* also, make sure we have enough info to correctly calculate lighting */ + if (blocks == Py_None || blocks == NULL || + blocklight == Py_None || blocklight == NULL) { + + return 0; + } + + block = getArrayByte3D(blocks, local_x, local_y, local_z); + + if (authoratative == NULL) { + int auth; + + /* iterate through all surrounding blocks to take an average */ + int dx, dy, dz, local_block; + for (dx = -1; dx <= 1; dx += 2) { + for (dy = -1; dy <= 1; dy += 2) { + for (dz = -1; dz <= 1; dz += 2) { + coeff = estimate_blocklevel(self, state, x+dx, y+dy, z+dz, &auth); + local_block = getArrayByte3D(blocks, x+dx, y+dy, z+dz); + /* only add if the block is transparent, this seems to look better than + using every block */ + if (auth && is_transparent(local_block)) { + average_gather += coeff; + average_count++; + } + } + } + } + } + + /* only return the average if at least one was authoratative */ + if (average_count > 0) { + return average_gather / average_count; + } + + blocklevel = getArrayByte3D(blocklight, local_x, local_y, local_z); + + /* no longer a guess */ + if (!(block == 44 || block == 53 || block == 67) && authoratative) { + *authoratative = 1; + } + + return blocklevel; +} + inline float get_lighting_coefficient(RenderModeLighting *self, RenderState *state, - int x, int y, int z, int *authoratative) { - + int x, int y, int z) { + /* placeholders for later data arrays, coordinates */ PyObject *blocks = NULL; PyObject *skylight = NULL; PyObject *blocklight = NULL; int local_x = x, local_y = y, local_z = z; unsigned char block, skylevel, blocklevel; - - /* defaults to "guess" until told otherwise */ - if (authoratative) - *authoratative = 0; - + /* find out what chunk we're in, and translate accordingly */ if (x >= 0 && y < 16) { blocks = state->blocks; @@ -64,7 +143,7 @@ get_lighting_coefficient(RenderModeLighting *self, RenderState *state, skylight = self->right_skylight; blocklight = self->right_blocklight; } - + /* make sure we have correctly-ranged coordinates */ if (!(local_x >= 0 && local_x < 16 && local_y >= 0 && local_y < 16 && @@ -72,7 +151,7 @@ get_lighting_coefficient(RenderModeLighting *self, RenderState *state, return self->calculate_darkness(15, 0); } - + /* also, make sure we have enough info to correctly calculate lighting */ if (blocks == Py_None || blocks == NULL || skylight == Py_None || skylight == NULL || @@ -82,49 +161,28 @@ get_lighting_coefficient(RenderModeLighting *self, RenderState *state, } block = getArrayByte3D(blocks, local_x, local_y, local_z); - - /* only do special half-step handling if no authoratative pointer was - passed in, which is a sign that we're recursing */ - if ((block == 44 || block == 53 || block == 67) && authoratative == NULL) { - float average_gather = 0.0f; - unsigned int average_count = 0, upper_block; - int auth; - float coeff; + skylevel = getArrayByte3D(skylight, local_x, local_y, local_z); + blocklevel = getArrayByte3D(blocklight, local_x, local_y, local_z); + + /* special half-step handling */ + if (block == 44 || block == 53 || block == 67) { + unsigned int upper_block; - if (local_z != 127) { /* stairs and half-blocks take the skylevel from the upper block if it's transparent */ + /* stairs and half-blocks take the skylevel from the upper block if it's transparent */ + if (local_z != 127) { upper_block = getArrayByte3D(blocks, local_x, local_y, local_z + 1); if (is_transparent(upper_block)) { skylevel = getArrayByte3D(skylight, local_x, local_y, local_z + 1); } - blocklevel = getArrayByte3D(blocklight, local_x, local_y, local_z); } else { upper_block = 0; skylevel = 15; - blocklevel = getArrayByte3D(blocklight, local_x, local_y, local_z); } + + /* the block has a bad blocklevel, estimate it from neigborhood + /* use given coordinates, no local ones! */ + blocklevel = estimate_blocklevel(self, state, x, y, z, NULL); - if (skylevel) { /* if we have a good skylevel use it, if not iterate */ - return self->calculate_darkness(skylevel, blocklevel); - } else { - - /* iterate through all surrounding blocks to take an average */ - int dx, dy, dz; - for (dx = -1; dx <= 1; dx += 2) { - for (dy = -1; dy <= 1; dy += 2) { - for (dz = -1; dz <= 1; dz += 2) { - coeff = get_lighting_coefficient(self, state, x+dx, y+dy, z+dz, &auth); - if (auth) { - average_gather += coeff; - average_count++; - } - } - } - } - - /* only return the average if at least one was authoratative */ - if (average_count > 0) - return average_gather / average_count; - } } if (block == 10 || block == 11) { @@ -132,13 +190,6 @@ get_lighting_coefficient(RenderModeLighting *self, RenderState *state, return 0.0f; } - skylevel = getArrayByte3D(skylight, local_x, local_y, local_z); - blocklevel = getArrayByte3D(blocklight, local_x, local_y, local_z); - - /* no longer a guess */ - if (authoratative) - *authoratative = 1; - return self->calculate_darkness(skylevel, blocklevel); } @@ -161,7 +212,7 @@ do_shading_with_mask(RenderModeLighting *self, RenderState *state, } } - black_coeff = get_lighting_coefficient(self, state, x, y, z, NULL); + black_coeff = get_lighting_coefficient(self, state, x, y, z); black_coeff *= self->shade_strength; alpha_over_full(state->img, self->black_color, mask, black_coeff, state->imgx, state->imgy, 0, 0); } diff --git a/textures.py b/textures.py index 5171285..5e2db3b 100644 --- a/textures.py +++ b/textures.py @@ -493,13 +493,7 @@ def generate_opaque_mask(img): smallers than 50, and sets every other value to 255. """ alpha = img.split()[3] - pixel = alpha.load() - for x in range(img.size[0]): - for y in range(img.size[1]): - if pixel[x,y] > 25: - pixel[x,y] = 255 - - return alpha + return alpha.point(lambda a: int(min(a, 25.5) * 10)) def generate_texture_tuple(img, blockid): """ This takes an image and returns the needed tuple for the diff --git a/web_assets/overviewer.css b/web_assets/overviewer.css index dc435fa..f4bdd98 100644 --- a/web_assets/overviewer.css +++ b/web_assets/overviewer.css @@ -7,6 +7,10 @@ body { margin: 0px; padding: 0px; background-color: #000; + + font-family: Arial, sans-serif; + font-size: 12px; + line-height: 160%; } #mcmap { @@ -82,7 +86,7 @@ body { } -#link { +#link, #coordsDiv { background-color: #fff; /* fallback */ background-color: rgba(255,255,255,0.55); border: 1px solid rgb(0, 0, 0); diff --git a/web_assets/overviewer.js b/web_assets/overviewer.js index ceeb7dc..ea87a19 100644 --- a/web_assets/overviewer.js +++ b/web_assets/overviewer.js @@ -591,6 +591,17 @@ var overviewer = { overviewer.map.controls[google.maps.ControlPosition.TOP_RIGHT].push(homeControlDiv); } + // Coords box + var coordsDiv = document.createElement('DIV'); + coordsDiv.id = 'coordsDiv'; + coordsDiv.innerHTML = ''; + overviewer.map.controls[google.maps.ControlPosition.BOTTOM_LEFT].push(coordsDiv); + // Update coords on mousemove + google.maps.event.addListener(overviewer.map, 'mousemove', function (event) { + var worldcoords = overviewer.util.fromLatLngToWorld(event.latLng.lat(), event.latLng.lng()); + coordsDiv.innerHTML = "Coords: X " + Math.round(worldcoords.x) + ", Z " + Math.round(worldcoords.z); + }); + // only need to create the control if there are items in the list. // as defined in config.js if (overviewerConfig.objectGroups.signs.length > 0) { diff --git a/world.py b/world.py index 564d193..1344d10 100644 --- a/world.py +++ b/world.py @@ -78,7 +78,10 @@ class World(object): logging.info("Scanning regions") regionfiles = {} self.regions = {} - self.regionlist = regionlist # a list of paths + if regionlist: + self.regionlist = map(os.path.abspath, regionlist) # a list of paths + else: + self.regionlist = None for x, y, regionfile in self._iterate_regionfiles(): mcr = self.reload_region(regionfile) mcr.get_chunk_info()