0

Merge remote branch 'origin/master'

This commit is contained in:
Andrew Chin
2010-09-26 01:32:16 -04:00
3 changed files with 146 additions and 1 deletions

View File

@@ -22,6 +22,7 @@ import functools
import re import re
import shutil import shutil
import collections import collections
import json
from PIL import Image from PIL import Image
@@ -119,6 +120,11 @@ class QuadtreeGen(object):
with open(os.path.join(self.destdir, "index.html"), 'w') as output: with open(os.path.join(self.destdir, "index.html"), 'w') as output:
output.write(html) output.write(html)
with open(os.path.join(self.destdir, "markers.js"), 'w') as output:
output.write("var markerData=%s" % json.dumps(self.world.POI))
def _get_cur_depth(self): def _get_cur_depth(self):
"""How deep is the quadtree currently in the destdir? This glances in """How deep is the quadtree currently in the destdir? This glances in
index.html to see what maxZoom is set to. index.html to see what maxZoom is set to.

View File

@@ -7,6 +7,7 @@
body { height: 100%; margin: 0px; padding: 0px ; background-color: #000; } body { height: 100%; margin: 0px; padding: 0px ; background-color: #000; }
#mcmap { height: 100% } #mcmap { height: 100% }
</style> </style>
<script type="text/javascript" src="markers.js"></script>
<script type="text/javascript" <script type="text/javascript"
src="http://maps.google.com/maps/api/js?sensor=false"> src="http://maps.google.com/maps/api/js?sensor=false">
</script> </script>
@@ -74,7 +75,57 @@
}; };
var map; var map;
var prot;
var markersInit = false;
function convertCoords (x,y,z) {
var imgx = 0;
var imgy = 0;
imgx = imgx + (12*x);
imgy = imgy - (6*x);
imgx = imgx + (12 * y);
imgy = imgy + (6* y);
imgy = imgy - (12*z);
// this math is mysterious. i don't fully understand it
// but the idea is to assume that block 0,0,0 in chunk 0,0
// is drawn in the very middle of the gmap at (192,192)
return [192*Math.pow(2,config.maxZoom)+imgx, 192*Math.pow(2,config.maxZoom)+imgy+768+768];
}
function initMarkers() {
if (markersInit) { return; }
markersInit = true;
prot = map.getProjection();
for (i in markerData) {
var item = markerData[i];
var converted = convertCoords(item.x-16, item.z, item.y);
var x = converted[0] / Math.pow(2, config.maxZoom);
var y = converted[1] / Math.pow(2, config.maxZoom);
var p = new google.maps.Point(x,y);
var marker = new google.maps.Marker({
position: prot.fromPointToLatLng(p),
map: map,
title:item.msg
});
}
}
function initialize() { function initialize() {
var mapOptions = { var mapOptions = {
zoom: config.defaultZoom, zoom: config.defaultZoom,
@@ -89,12 +140,33 @@
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)));
} }
// 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); map.mapTypes.set('mcmap', MCMapType);
// 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('mcmap');
prot = map.getProjection();
if (config.debug)
google.maps.event.addListener(map, 'click', function(event) {
console.log("latLng: " + event.latLng.lat() + ", " + event.latLng.lng());
var pnt = prot.fromLatLngToPoint(event.latLng);
console.log("point: " + pnt);//
var pxx = pnt.x * Math.pow(2,config.maxZoom);
var pxy = pnt.y * Math.pow(2,config.maxZoom);
console.log("pixel: " + pxx + ", " + pxy);
});
google.maps.event.addListener(map, 'projection_changed', function(event) {
initMarkers();
});
} }
</script> </script>
</head> </head>

View File

@@ -17,6 +17,7 @@ import functools
import os import os
import os.path import os.path
import multiprocessing import multiprocessing
import numpy
from PIL import Image from PIL import Image
@@ -57,6 +58,29 @@ def _convert_coords(chunks):
return mincol, maxcol, minrow, maxrow, chunks_translated return mincol, maxcol, minrow, maxrow, chunks_translated
def base36encode(number, alphabet='0123456789abcdefghijklmnopqrstuvwxyz'):
'''
Convert an integer to a base36 string.
'''
if not isinstance(number, (int, long)):
raise TypeError('number must be an integer')
newn = abs(number)
# Special case for zero
if number == 0:
return '0'
base36 = ''
while newn != 0:
newn, i = divmod(newn, len(alphabet))
base36 = alphabet[i] + base36
if number < 0:
return "-" + base36
return base36
class WorldRenderer(object): class WorldRenderer(object):
"""Renders a world's worth of chunks. """Renders a world's worth of chunks.
worlddir is the path to the minecraft world worlddir is the path to the minecraft world
@@ -67,6 +91,47 @@ class WorldRenderer(object):
self.caves = False self.caves = False
self.cachedir = cachedir self.cachedir = cachedir
# stores Points Of Interest to be mapped with markers
# a list of dictionaries, see below for an example
self.POI = []
def findTrueSpawn(self):
"""Adds the true spawn location to self.POI. The spawn Y coordinate
is almost always the default of 64. Find the first air block above
that point for the true spawn location"""
## read spawn info from level.dat
data = nbt.load(os.path.join(self.worlddir, "level.dat"))[1]
spawnX = data['Data']['SpawnX']
spawnY = data['Data']['SpawnY']
spawnZ = data['Data']['SpawnZ']
## The chunk that holds the spawn location
chunkX = spawnX/16
chunkY = spawnZ/16
## The filename of this chunk
chunkFile = "%s/%s/c.%s.%s.dat" % (base36encode(chunkX % 64),
base36encode(chunkY % 64),
base36encode(chunkX),
base36encode(chunkY))
data=nbt.load(os.path.join(self.worlddir, chunkFile))[1]
level = data['Level']
blockArray = numpy.frombuffer(level['Blocks'], dtype=numpy.uint8).reshape((16,16,128))
## The block for spawn *within* the chunk
inChunkX = spawnX - (chunkX*16)
inChunkZ = spawnZ - (chunkY*16)
## find the first air block
while (blockArray[inChunkX, inChunkZ, spawnY] != 0):
spawnY += 1
self.POI.append( dict(x=spawnX, y=spawnY, z=spawnZ, msg="Spawn"))
def go(self, procs): def go(self, procs):
"""Starts the render. This returns when it is finished""" """Starts the render. This returns when it is finished"""
@@ -84,6 +149,8 @@ class WorldRenderer(object):
self.minrow = minrow self.minrow = minrow
self.maxrow = maxrow self.maxrow = maxrow
self.findTrueSpawn()
def _find_chunkfiles(self): def _find_chunkfiles(self):
"""Returns a list of all the chunk file locations, and the file they """Returns a list of all the chunk file locations, and the file they
correspond to. correspond to.