0

Merge branch 'master' of https://github.com/jennytoo/Minecraft-Overviewer into jennytoo-master

This commit is contained in:
Andrew Chin
2010-12-18 20:13:11 -05:00
6 changed files with 96 additions and 24 deletions

View File

@@ -112,6 +112,18 @@ def iterate_chunkblocks(xoff,yoff):
transparent_blocks = set([0, 6, 8, 9, 18, 20, 37, 38, 39, 40, 44, 50, 51, 52, 53, transparent_blocks = set([0, 6, 8, 9, 18, 20, 37, 38, 39, 40, 44, 50, 51, 52, 53,
59, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 74, 75, 76, 77, 78, 79, 81, 83, 85]) 59, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 74, 75, 76, 77, 78, 79, 81, 83, 85])
# This set holds block ids that are solid blocks
solid_blocks = set([1, 2, 3, 4, 5, 7, 12, 13, 14, 15, 16, 17, 18, 19, 20, 35,
41, 42, 43, 44, 45, 46, 47, 48, 49, 53, 54, 56, 57, 58, 60, 61, 62, 64, 65,
66, 67, 71, 73, 74, 78, 79, 80, 81, 82, 84, 86, 87, 88, 89, 91])
# This set holds block ids that are fluid blocks
fluid_blocks = set([8,9,10,11])
# This set holds block ids that are not candidates for spawning mobs on
# (glass, half blocks)
nospawn_blocks = set([20,44])
def render_and_save(chunkfile, cachedir, worldobj, cave=False, queue=None): def render_and_save(chunkfile, cachedir, worldobj, cave=False, queue=None):
"""Used as the entry point for the multiprocessing workers (since processes """Used as the entry point for the multiprocessing workers (since processes
can't target bound methods) or to easily render and save one chunk can't target bound methods) or to easily render and save one chunk
@@ -833,6 +845,13 @@ class ChunkRenderer(object):
# block shaded with the current # block shaded with the current
# block's light # block's light
black_coeff, _ = self.get_lighting_coefficient(x, y, z) black_coeff, _ = self.get_lighting_coefficient(x, y, z)
if self.world.spawn and black_coeff > 0.8 and blockid in solid_blocks and not (
blockid in nospawn_blocks or (
z != 127 and (blocks[x,y,z+1] in solid_blocks or blocks[x,y,z+1] in fluid_blocks)
)
):
composite.alpha_over(img, Image.blend(t[0], red_color, black_coeff), (imgx, imgy), t[1])
else:
composite.alpha_over(img, Image.blend(t[0], black_color, black_coeff), (imgx, imgy), t[1]) composite.alpha_over(img, Image.blend(t[0], black_color, black_coeff), (imgx, imgy), t[1])
else: else:
# draw each face lit appropriately, # draw each face lit appropriately,
@@ -841,18 +860,28 @@ class ChunkRenderer(object):
# top face # top face
black_coeff, face_occlude = self.get_lighting_coefficient(x, y, z + 1) black_coeff, face_occlude = self.get_lighting_coefficient(x, y, z + 1)
# Use red instead of black for spawnable blocks
if self.world.spawn and black_coeff > 0.8 and blockid in solid_blocks and not (
blockid in nospawn_blocks or (
z != 127 and (blocks[x,y,z+1] in solid_blocks or blocks[x,y,z+1] in fluid_blocks)
)
):
over_color = red_color
else:
over_color = black_color
if not face_occlude: if not face_occlude:
composite.alpha_over(img, black_color, (imgx, imgy), ImageEnhance.Brightness(facemasks[0]).enhance(black_coeff)) composite.alpha_over(img, over_color, (imgx, imgy), ImageEnhance.Brightness(facemasks[0]).enhance(black_coeff))
# left face # left face
black_coeff, face_occlude = self.get_lighting_coefficient(x - 1, y, z) black_coeff, face_occlude = self.get_lighting_coefficient(x - 1, y, z)
if not face_occlude: if not face_occlude:
composite.alpha_over(img, black_color, (imgx, imgy), ImageEnhance.Brightness(facemasks[1]).enhance(black_coeff)) composite.alpha_over(img, over_color, (imgx, imgy), ImageEnhance.Brightness(facemasks[1]).enhance(black_coeff))
# right face # right face
black_coeff, face_occlude = self.get_lighting_coefficient(x, y + 1, z) black_coeff, face_occlude = self.get_lighting_coefficient(x, y + 1, z)
if not face_occlude: if not face_occlude:
composite.alpha_over(img, black_color, (imgx, imgy), ImageEnhance.Brightness(facemasks[2]).enhance(black_coeff)) composite.alpha_over(img, over_color, (imgx, imgy), ImageEnhance.Brightness(facemasks[2]).enhance(black_coeff))
# Draw edge lines # Draw edge lines
if blockid in (44,): # step block if blockid in (44,): # step block
@@ -921,6 +950,7 @@ def generate_facemasks():
return (top, left, right) return (top, left, right)
facemasks = generate_facemasks() facemasks = generate_facemasks()
black_color = Image.new("RGB", (24,24), (0,0,0)) black_color = Image.new("RGB", (24,24), (0,0,0))
red_color = Image.new("RGB", (24,24), (229,36,38))
# Render 128 different color images for color coded depth blending in cave mode # Render 128 different color images for color coded depth blending in cave mode
def generate_depthcolors(): def generate_depthcolors():

View File

@@ -1,6 +1,5 @@
var config = { var config = {
path: 'tiles',
fileExt: '{imgformat}', fileExt: '{imgformat}',
tileSize: 384, tileSize: 384,
defaultZoom: 1, defaultZoom: 1,
@@ -28,6 +27,21 @@ var signGroups = [
{label: "All", match: function(s) {return true}} {label: "All", match: function(s) {return true}}
]; ];
/* mapTypeData -- a list of alternate map renderings available. At least one rendering must be
* listed. When more than one are provided, controls to switch between them are provided, with
* the first one being the default.
*
* Required:
* label : string. Displayed on the control.
* path : string. Location of the rendered tiles.
*/
var mapTypeData=[
{'label': 'Unlit', 'path': 'tiles'},
// {'label': 'Day', 'path': 'lighting/tiles'},
// {'label': 'Night', 'path': 'night/tiles'},
// {'label': 'Spawn', 'path': 'spawn/tiles'}
];
// Please leave the following variables here: // Please leave the following variables here:
var markerCollection = {}; // holds groups of markers var markerCollection = {}; // holds groups of markers

View File

@@ -51,6 +51,7 @@ def main():
parser.add_option("--chunklist", dest="chunklist", help="A file containing, on each line, a path to a chunkfile to update. Instead of scanning the world directory for chunks, it will just use this list. Normal caching rules still apply.") parser.add_option("--chunklist", dest="chunklist", help="A file containing, on each line, a path to a chunkfile to update. Instead of scanning the world directory for chunks, it will just use this list. Normal caching rules still apply.")
parser.add_option("--lighting", dest="lighting", help="Renders shadows using light data from each chunk.", action="store_true") parser.add_option("--lighting", dest="lighting", help="Renders shadows using light data from each chunk.", action="store_true")
parser.add_option("--night", dest="night", help="Renders shadows using light data from each chunk, as if it were night. Implies --lighting.", action="store_true") parser.add_option("--night", dest="night", help="Renders shadows using light data from each chunk, as if it were night. Implies --lighting.", action="store_true")
parser.add_option("--spawn", dest="spawn", help="Renders shadows using light data from each chunk, as if it were night, while also highlighting areas that are dark enough to spawn mobs. Implies --lighting and --night.", action="store_true")
parser.add_option("--imgformat", dest="imgformat", help="The image output format to use. Currently supported: png(default), jpg. NOTE: png will always be used as the intermediate image format.") parser.add_option("--imgformat", dest="imgformat", help="The image output format to use. Currently supported: png(default), jpg. NOTE: png will always be used as the intermediate image format.")
parser.add_option("--optimize-img", dest="optimizeimg", help="If using png, perform image file size optimizations on the output. Specify 1 for pngcrush, 2 for pngcrush+optipng+advdef. This may double (or more) render times, but will produce up to 30% smaller images. NOTE: requires corresponding programs in $PATH or %PATH%") parser.add_option("--optimize-img", dest="optimizeimg", help="If using png, perform image file size optimizations on the output. Specify 1 for pngcrush, 2 for pngcrush+optipng+advdef. This may double (or more) render times, but will produce up to 30% smaller images. NOTE: requires corresponding programs in $PATH or %PATH%")
parser.add_option("-q", "--quiet", dest="quiet", action="count", default=0, help="Print less output. You can specify this option multiple times.") parser.add_option("-q", "--quiet", dest="quiet", action="count", default=0, help="Print less output. You can specify this option multiple times.")
@@ -123,7 +124,8 @@ def main():
logging.info("Notice: Not using biome data for tinting") logging.info("Notice: Not using biome data for tinting")
# First generate the world's chunk images # First generate the world's chunk images
w = world.WorldRenderer(worlddir, cachedir, chunklist=chunklist, lighting=options.lighting, night=options.night, useBiomeData=useBiomeData) w = world.WorldRenderer(worlddir, cachedir, chunklist=chunklist, lighting=options.lighting, night=options.night, spawn=options.spawn, useBiomeData=useBiomeData)
w.go(options.procs) w.go(options.procs)
# Now generate the tiles # Now generate the tiles

View File

@@ -37,6 +37,7 @@ function drawMapControls() {
compassImg.src="compass.png"; compassImg.src="compass.png";
compassDiv.appendChild(compassImg); compassDiv.appendChild(compassImg);
compassDiv.index = 0;
map.controls[google.maps.ControlPosition.TOP_RIGHT].push(compassDiv); map.controls[google.maps.ControlPosition.TOP_RIGHT].push(compassDiv);
@@ -260,16 +261,23 @@ function initialize() {
if (argname == "zoom") {zoom = parseInt(value);} if (argname == "zoom") {zoom = parseInt(value);}
} }
var mapTyepControlToggle = false
if (mapTypeIds.length > 1) {
mapTyepControlToggle = true
}
var mapOptions = { var mapOptions = {
zoom: zoom, zoom: zoom,
center: new google.maps.LatLng(lat, lng), center: new google.maps.LatLng(lat, lng),
navigationControl: true, navigationControl: true,
scaleControl: false, scaleControl: false,
mapTypeControl: false, mapTypeControl: mapTyepControlToggle,
mapTypeControlOptions: {
mapTypeIds: mapTypeIds
},
mapTypeId: mapTypeIdDefault,
streetViewControl: false, streetViewControl: false,
mapTypeId: 'mcmap'
}; };
map = new google.maps.Map(document.getElementById("mcmap"), mapOptions); map = new google.maps.Map(document.getElementById('mcmap'), mapOptions);
if(config.debug) { if(config.debug) {
map.overlayMapTypes.insertAt(0, new CoordMapType(new google.maps.Size(config.tileSize, config.tileSize))); map.overlayMapTypes.insertAt(0, new CoordMapType(new google.maps.Size(config.tileSize, config.tileSize)));
@@ -287,11 +295,12 @@ function initialize() {
} }
// Now attach the coordinate map type to the map's registry // Now attach the coordinate map type to the map's registry
map.mapTypes.set('mcmap', MCMapType); for (idx in MCMapType) {
map.mapTypes.set('mcmap' + MCMapType[idx].name, MCMapType[idx]);
}
// We can now set the map to use the 'coordinate' map type // We can now set the map to use the 'coordinate' map type
map.setMapTypeId('mcmap'); map.setMapTypeId(mapTypeIdDefault);
// initialize the markers and regions // initialize the markers and regions
initMarkers(); initMarkers();
@@ -370,9 +379,9 @@ function initialize() {
return new google.maps.LatLng(lat, lng); return new google.maps.LatLng(lat, lng);
} }
var MCMapOptions = { function getTileUrlGenerator(path) {
getTileUrl: function(tile, zoom) { return function(tile, zoom) {
var url = config.path; var url = path;
if(tile.x < 0 || tile.x >= Math.pow(2, zoom) || tile.y < 0 || tile.y >= Math.pow(2, zoom)) { if(tile.x < 0 || tile.x >= Math.pow(2, zoom) || tile.y < 0 || tile.y >= Math.pow(2, zoom)) {
url += '/blank'; url += '/blank';
} else if(zoom == 0) { } else if(zoom == 0) {
@@ -390,17 +399,33 @@ function initialize() {
url += '?c=' + Math.floor(d.getTime() / (1000 * 60 * config.cacheMinutes)); url += '?c=' + Math.floor(d.getTime() / (1000 * 60 * config.cacheMinutes));
} }
return(url); return(url);
}, }
}
var MCMapOptions = new Array;
var MCMapType = new Array;
var mapTypeIdDefault = null;
var mapTypeIds = [];
for (idx in mapTypeData) {
var view = mapTypeData[idx];
MCMapOptions[view.label] = {
getTileUrl: getTileUrlGenerator(view.path),
tileSize: new google.maps.Size(config.tileSize, config.tileSize), tileSize: new google.maps.Size(config.tileSize, config.tileSize),
maxZoom: config.maxZoom, maxZoom: config.maxZoom,
minZoom: 0, minZoom: 0,
isPng: !(config.fileExt.match(/^png$/i) == null) isPng: !(config.fileExt.match(/^png$/i) == null)
}; };
var MCMapType = new google.maps.ImageMapType(MCMapOptions); MCMapType[view.label] = new google.maps.ImageMapType(MCMapOptions[view.label]);
MCMapType.name = "MC Map"; MCMapType[view.label].name = view.label;
MCMapType.alt = "Minecraft Map"; MCMapType[view.label].alt = "Minecraft " + view.label + " Map";
MCMapType.projection = new MCMapProjection(); MCMapType[view.label].projection = new MCMapProjection();
if (mapTypeIdDefault == null) {
mapTypeIdDefault = 'mcmap' + view.label;
}
mapTypeIds.push('mcmap' + view.label);
}
function CoordMapType() { function CoordMapType() {
} }

View File

@@ -25,7 +25,7 @@ body { height: 100%; margin: 0px; padding: 0px ; background-color: #000; }
#signControl > div#top { #signControl > div#top {
background-color: #fff; background-color: #fff;
border: 1px solid #000; border: 2px solid #000;
text-align: center; text-align: center;
width: 70px; width: 70px;
font-size: 12px; font-size: 12px;

View File

@@ -95,11 +95,12 @@ class WorldRenderer(object):
files to update. If it includes a trailing newline, it is stripped, so you files to update. If it includes a trailing newline, it is stripped, so you
can pass in file handles just fine. can pass in file handles just fine.
""" """
def __init__(self, worlddir, cachedir, chunklist=None, lighting=False, night=False, useBiomeData=False): def __init__(self, worlddir, cachedir, chunklist=None, lighting=False, night=False, spawn=False, useBiomeData=False):
self.worlddir = worlddir self.worlddir = worlddir
self.caves = False self.caves = False
self.lighting = lighting or night self.lighting = lighting or night or spawn
self.night = night self.night = night or spawn
self.spawn = spawn
self.cachedir = cachedir self.cachedir = cachedir
self.useBiomeData = useBiomeData self.useBiomeData = useBiomeData