Index: /issm/trunk-jpl/src/m/plot/applyoptions.js
===================================================================
--- /issm/trunk-jpl/src/m/plot/applyoptions.js	(revision 21172)
+++ /issm/trunk-jpl/src/m/plot/applyoptions.js	(revision 21173)
@@ -332,33 +332,35 @@
 	} //}}}
 	//Atmosphere {{{
-	if (options.exist('atmosphere')) {
-		if (options.getfieldvalue('atmosphere')=='on') {
-			var meshresults = processmesh(md,data,options);
-			var x = meshresults[0]; 
-			var y = meshresults[1]; 
-			var z = meshresults[2]; 
-			var elements = meshresults[3];
-			var is2d = meshresults[4]; 
-			var isplanet = meshresults[5];
-			
-			var modelxlim = [ArrayMin(x),ArrayMax(x)];
-			var modelylim = [ArrayMin(y),ArrayMax(y)];
-			var modelzlim = [ArrayMin(z),ArrayMax(z)];
-			var xlim = options.getfieldvalue('xlim',modelxlim);
-			var ylim = options.getfieldvalue('ylim',modelylim);
-			var zlim = options.getfieldvalue('zlim',modelzlim);
-			xmin = xlim[0];
-			xmax = xlim[1];
-			ymin = ylim[0];
-			ymax = ylim[1];
-			zmin = zlim[0];
-			zmax = zlim[1];
-
-			var scale = 1;
-			var atmosphereScale = 1.25;
-			
-			//Atmosphere
+	if (options.exist('render')) {
+		var meshresults = processmesh(md,data,options);
+		var x = meshresults[0]; 
+		var y = meshresults[1]; 
+		var z = meshresults[2]; 
+		var elements = meshresults[3];
+		var is2d = meshresults[4]; 
+		var isplanet = meshresults[5];
+		
+		var modelxlim = [ArrayMin(x),ArrayMax(x)];
+		var modelylim = [ArrayMin(y),ArrayMax(y)];
+		var modelzlim = [ArrayMin(z),ArrayMax(z)];
+		var xlim = options.getfieldvalue('xlim',modelxlim);
+		var ylim = options.getfieldvalue('ylim',modelylim);
+		var zlim = options.getfieldvalue('zlim',modelzlim);
+		xmin = xlim[0];
+		xmax = xlim[1];
+		ymin = ylim[0];
+		ymax = ylim[1];
+		zmin = zlim[0];
+		zmax = zlim[1];
+		
+		var global = vec3.length([(xmin + xmax) / 2, (ymin + ymax) / 2, (zmin + zmax) / 2]) < 6371000/10; //tolerance for global models = center is 637100 meters away from center of earth
+		var atmosphereScale = 1.25;
+		var translation = global ? [(xmin + xmax) / 2, (ymin + ymax) / 2, (zmin + zmax) / 2] : [(xmin + xmax) / 2, (ymin + ymax) - 6371000, (zmin + zmax) / 2];
+		
+		if (options.getfieldvalue('render',[]).indexOf('sky')!=-1) {	
+			//atmosphere
 			var node = Node(gl,options);
 			canvas.nodes[canvas.nodes.length] = node;
+			node["name"] = "atmosphere";
 			node["shaderName"] = "SkyFromSpace";
 			node["shader"] = gl["shaders"][node["shaderName"]];
@@ -367,12 +369,14 @@
 			node["mesh"] = GL.Mesh.icosahedron({size:6371000*atmosphereScale,subdivisions:6});
 			node["useIndexBuffer"] = false;
-			node["rotation"] = [0,0,0];
-			node["translation"] = [(xmin + xmax) / (-2 / scale), (ymin + ymax) / (-2 / scale), (zmin + zmax) / (2 / scale)];
-			node["scale"] = [scale, scale, scale];
+			node["rotation"] = [0, 0, 0]
+			node["translation"] = translation;
+			node["center"] = [0, 0, 0];
 			node["modelMatrix"] = recalculateModelMatrix(node);
-			
-			//Skysphere
-			var node = Node(gl,options);
+		}
+		if (options.getfieldvalue('render',[]).indexOf('space')!=-1) {	
+			//skysphere
+			node = Node(gl,options);
 			canvas.nodes[canvas.nodes.length] = node;
+			node["name"] = "skysphere";
 			node["shaderName"] = "Textured";
 			node["shader"] = gl["shaders"][node["shaderName"]];
@@ -382,7 +386,7 @@
 			node["texture"] = initTexture(gl,'../../../js/textures/TychoSkymapII_t4_2k.jpg');
 			node["useIndexBuffer"] = false;
-			node["rotation"] = [0,0,0];
-			node["translation"] = [(xmin + xmax) / (-2 / scale), (ymin + ymax) / (-2 / scale), (zmin + zmax) / (2 / scale)];
-			node["scale"] = [scale, scale, scale];
+			node["rotation"] = [0, 0, 0]
+			node["translation"] = translation;
+			node["center"] = [0, 0, 0];
 			node["modelMatrix"] = recalculateModelMatrix(node);
 		}
Index: /issm/trunk-jpl/src/m/plot/plot_mesh.js
===================================================================
--- /issm/trunk-jpl/src/m/plot/plot_mesh.js	(revision 21172)
+++ /issm/trunk-jpl/src/m/plot/plot_mesh.js	(revision 21173)
@@ -61,10 +61,12 @@
 	var node = Node(gl,options);
 	canvas.nodes[canvas.nodes.length] = node;
-	scale = 1;
+	node["name"] = "mesh";
 	node["shaderName"] = "Colored";
 	node["shader"] = gl["shaders"][node["shaderName"]];
 	node["lineWidth"] = options.getfieldvalue('linewidth',1);
-	node["scale"] = [scale, scale, scale * matrixscale];
-	node["translation"] = [(xmin + xmax) / (-2 / scale), (ymin + ymax) / (-2 / scale), (zmin + zmax) / (2 / scale)];
+	node["scale"] = [1, 1, matrixscale];
+	node["rotation"] = [-90, 0, 0];
+	node["translation"] = [(xmin + xmax) / 2, (ymin + ymax) / 2, (zmin + zmax) / 2];
+	node["center"] = [(xmin + xmax) / 2, (ymin + ymax) / 2, (zmin + zmax) / 2];
 	node["modelMatrix"] = recalculateModelMatrix(node);
 	node["drawMode"] = gl.LINES;
Index: /issm/trunk-jpl/src/m/plot/plot_overlay.js
===================================================================
--- /issm/trunk-jpl/src/m/plot/plot_overlay.js	(revision 21172)
+++ /issm/trunk-jpl/src/m/plot/plot_overlay.js	(revision 21173)
@@ -15,5 +15,5 @@
 	var ymin,ymax;
 	var zmin,zmax;
-	var scale,matrixscale,vertexscale;
+	var matrixscale,vertexscale;
 
 	//Process data and model
@@ -61,9 +61,11 @@
 	var node = Node(gl,options);
 	canvas.nodes[canvas.nodes.length] = node;
-	scale = 1;
-	node["shaderName"] = (options.getfieldvalue('atmosphere','off') == 'on') ? "GroundFromSpace" : "Textured";
+	node["name"] = "overlay";
+	node["shaderName"] = (options.getfieldvalue('render',[]).indexOf('ground')!=-1) ? "GroundFromSpace" : "Textured";
 	node["shader"] = gl["shaders"][node["shaderName"]];
-	node["scale"] = [scale, scale, scale * matrixscale];
-	node["translation"] = [(xmin + xmax) / (-2 / scale), (ymin + ymax) / (-2 / scale), (zmin + zmax) / (2 / scale)];
+	node["scale"] = [1, 1, matrixscale];
+	node["rotation"] = [-90, 0, 0];
+	node["translation"] = [(xmin + xmax) / 2, (ymin + ymax) / 2, (zmin + zmax) / 2];
+	node["center"] = [(xmin + xmax) / 2, (ymin + ymax) / 2, (zmin + zmax) / 2];
 	node["modelMatrix"] = recalculateModelMatrix(node);
 	node["texture"] = initTexture(gl,options.getfieldvalue('overlay_image'));
@@ -96,5 +98,5 @@
 		zmax = zlim[1];
 		
-		node["translation"] = [node["translation"][0], node["translation"][1], (zmax) / (-1 / scale)];
+		node["center"] = [node["center"][0], node["center"][1], -zmax];
 	}
 	
Index: /issm/trunk-jpl/src/m/plot/plot_quiver.js
===================================================================
--- /issm/trunk-jpl/src/m/plot/plot_quiver.js	(revision 21172)
+++ /issm/trunk-jpl/src/m/plot/plot_quiver.js	(revision 21173)
@@ -63,10 +63,12 @@
 	var node = Node(gl,options);
 	canvas.nodes[canvas.nodes.length] = node;
-	scale = 1;
+	node["name"] = "quiver";
 	node["shaderName"] = "Colored";
 	node["shader"] = gl["shaders"][node["shaderName"]];
 	node["lineWidth"] = options.getfieldvalue('linewidth',1);
-	node["scale"] = [scale, scale, scale * matrixscale];
-	node["translation"] = [(xmin + xmax) / (-2 / scale), (ymin + ymax) / (-2 / scale), (zmin + zmax) / (2 / scale)];
+	node["scale"] = [1, 1, matrixscale];
+	node["rotation"] = [-90, 0, 0];
+	node["translation"] = [(xmin + xmax) / 2, (ymin + ymax) / 2, (zmin + zmax) / 2];
+	node["center"] = [(xmin + xmax) / 2, (ymin + ymax) / 2, (zmin + zmax) / 2];
 	node["modelMatrix"] = recalculateModelMatrix(node);
 	node["drawMode"] = gl.LINES;
Index: /issm/trunk-jpl/src/m/plot/plot_unit.js
===================================================================
--- /issm/trunk-jpl/src/m/plot/plot_unit.js	(revision 21172)
+++ /issm/trunk-jpl/src/m/plot/plot_unit.js	(revision 21173)
@@ -25,5 +25,5 @@
 	var zmin,zmax;
 	var datamin,datamax,datadelta;
-	var scale,matrixscale,vertexscale;
+	var matrixscale,vertexscale;
 
 	//Compue scaling through matrices for 2d meshes and vertices for 3d meshes
@@ -63,9 +63,11 @@
 	var node = Node(gl,options);
 	canvas.nodes[canvas.nodes.length] = node;
-	scale = 1;
+	node["name"] = "unit";
 	node["shaderName"] = "Textured";
 	node["shader"] = gl["shaders"][node["shaderName"]];
-	node["scale"] = [scale, scale, scale * matrixscale];
-	node["translation"] = [(xmin + xmax) / (-2 / scale), (ymin + ymax) / (-2 / scale), (zmin + zmax) / (2 / scale)];
+	node["scale"] = [1, 1, matrixscale];
+	node["rotation"] = [-90, 0, 0];
+	node["translation"] = [(xmin + xmax) / 2, (ymin + ymax) / 2, (zmin + zmax) / 2];
+	node["center"] = [(xmin + xmax) / 2, (ymin + ymax) / 2, (zmin + zmax) / 2];
 	node["modelMatrix"] = recalculateModelMatrix(node);
 	node["alpha"] = options.getfieldvalue('alpha',1.0);
@@ -75,4 +77,5 @@
 	node["maskColor"] = options.getfieldvalue('innermaskcolor',[0.0,0.0,1.0,1.0]);
 	node["enabled"] = options.getfieldvalue('nodata','off') == 'off';
+	vec3.add(canvas.translation, canvas.translation, node["center"]);
 	
 	switch(datatype){
@@ -236,5 +239,5 @@
 						var buffer = node["mesh"].getBuffer("coords");
 						buffer.data = texcoords[node["movieFrame"]];
-						buffer.upload(gl.DYNAMIC_DRAW);
+						buffer.upload(canvas.gl.DYNAMIC_DRAW);
 					}, node["movieInterval"]);
 				if (canvas["progressBar"]) {
Index: /issm/trunk-jpl/src/m/plot/plotdoc.js
===================================================================
--- /issm/trunk-jpl/src/m/plot/plotdoc.js	(revision 21172)
+++ /issm/trunk-jpl/src/m/plot/plotdoc.js	(revision 21173)
@@ -16,6 +16,7 @@
 	console.log('                  - "mesh": draw mesh using trisurf');
 	console.log('                  - "quiver": quiver plot');
+	console.log('       "2d": renders orthographic camera with view set to [0, 90] (default "off", ex: "on", "off")');
+	console.log('       "backgroundcolor": plot background color. (default "lightcyan", ex: "green","blue")');
 	console.log('       "caxis": modify  colorbar range. (array of type [a, b] where b>=a)');
-	console.log('       "backgroundcolor": plot background color. (default "lightcyan", ex: "green","blue")');
 	console.log('       "colorbar": add colorbar (default "off", ex: "on", "off")');
 	console.log('       "colorbarid": colorbar canvas id (string)');
@@ -29,34 +30,34 @@
 	console.log('       "colorbarheight": multiplier (default 1) to the default height colorbar');
 	console.log('       "colormap": same as standard matlab option (default "jet", ex: "hsv","cool","spring","gray","Ala","Rignot",...)');
+	console.log('       "controlsensitivity": sensitivty of view/zoom changes as a percentage of default (default 1, ex: 0.5, 2.75)');
+	console.log('       "displayview": print view value to console (default "off", ex: "on", "off")');
+	console.log('       "displayzoom": print zoom value to console (default "off", ex: "on", "off")');
 	console.log('       "edgecolor": same as standard matlab option EdgeColor (default "black", ex: color name: "blue" or RGB array: [0.5, 0.2, 0.8])');
+	console.log('       "heightscale": scaling factor to accentuate height. (default 1, ex: 0.5, 100)');
+	console.log('       "linewidth*": line width for mesh, quiver, and contour plots, currently limited by WebGL to 1. (default 1, ex: 2, 5)');
+	console.log('       "log": value of log (default 10, ex: 2, Math.E)');
+	console.log('       "mask": list of flags of size numberofnodes or numberofelements. Only "true" values are plotted ');
+	console.log('       "moviefps": frames per second when displaying transient runs (default 5, ex: 1, 10)');
+	console.log('       "innermask*": Special mask that colors all parts of a data mesh below a height a certain color. provide innermaskheight and innermaskcolor options also (default "off", ex: "on", "off")');
+	console.log('       "outermask*": Special mask that colors all parts of a overlay mesh below a height a certain color. provide outermaskheight and outermaskcolor options also (default "off", ex: "on", "off")');
+	console.log('       "overlay": overlay a radar amplitude image behind (default "off", ex: "on", "off")');
+	console.log('       "overlay_image": path to overlay image (default "off", ex: "on", "off")');
+	console.log('       "scaling": scaling factor used by quiver plots. Default is 0.4');
+	console.log('       "alpha": transparency coefficient 0.0 to 1.0, the lower, the more transparent. (default 1.0, ex: 0.5, 0.25)');
+	console.log('       "azlim": azimuth view limits (ex: [0, 180])');
+	console.log('       "ellim": elevation view limits (ex: [-90, 90])');
+	console.log('       "origin": initial camera offset from model center (default [0,0,0.0], ex: [-2, 1.5, 0.01])');
+	console.log('       "render": toggle sky, ground, and space rendering. (default [], ex: ["sky", "space"], ["ground"])');
 	console.log('       "viewPanning": enable view origin panning with two-finger touch or shift+mouse drag. (default "off", ex: "on", "off")');
 	console.log('       "view": initial azimuth and elevation angles for camera (default [0,90], ex: [90, 180]');
-	console.log('       "zoom": initial camera zoom as a percentage of default (default 1, ex: 1.5, 0.01)');
-	console.log('       "centeroffset": initial camera offset from model center (default [0,0,0.0], ex: [-2, 1.5, 0.01])');
 	console.log('       "xlim": x coordinates to fit inside camera (ex: [0, 500])');
 	console.log('       "ylim": y coordinates to fit inside camera (ex: [0, 500])');
 	console.log('       "zlim": z coordinates to fit inside camera (ex: [0, 500])');
-	console.log('       "azlim": azimuth view limits (ex: [0, 180])');
-	console.log('       "ellim": elevation view limits (ex: [-90, 90])');
 	console.log('       "zoomlim": zoom view limits (ex: [0.05, 10])');
-	console.log('       "displayview": print view value to console');
-	console.log('       "displayzoom": print zoom value to console');
-	console.log('       "controlsensitivity": sensitivty of view/zoom changes as a percentage of default (default 1, ex: 0.5, 2.75)');
-	console.log('       "2d": renders orthographic camera with view set to [0, 90] (default "off", ex: "on", "off")');
-	console.log('       "moviefps": frames per second when displaying transient runs (default 5, ex: 1, 10)');
-	console.log('       "overlay": overlay a radar amplitude image behind (default "off", ex: "on", "off")');
-	console.log('       "overlay_image": path to overlay image (default "off", ex: "on", "off")');
-	console.log('       "atmosphere": toggle atmospheric/skysphere shading. (default "off", ex: "on", "off")');
-	console.log('       "alpha": transparency coefficient 0.0 to 1.0, the lower, the more transparent. (default 1.0, ex: 0.5, 0.25)');
-	console.log('       "heightscale": scaling factor to accentuate height. (default 1, ex: 0.5, 100)');
-	console.log('       "scaling*": scaling factor used by quiver plots. Default is 0.4');
-	console.log('       "linewidth*": line width for mesh, quiver, and contour plots, currently limited by WebGL to 1. (default 1, ex: 2, 5)');
+	console.log('       "zoom": initial camera zoom as a percentage of default (default 1, ex: 1.5, 0.01)');
 	console.log('       "cloud*": plot a cloud of points, given a flat array of 3d coordinates (ex: [0.0, 0.0, 0.0, 1.0, 1.0, 1.0])');
 	console.log('       "expdisp*": plot exp file on top of a data plot. provide exp file as an argument (use a cell of strings if more than one)');
 	console.log('       "textlabels*": plot text labels rendered in 3d space, using an array of text/coordinate pairs (ex: [{"pos":[0.0,0.0,0.0],"text":"origin"}])');
-	console.log('       "outermask*": Special mask that colors all parts of a overlay mesh below a height a certain color. provide outermaskheight and outermaskcolor options also (default "off", ex: "on", "off")');
-	console.log('       "innermask*": Special mask that colors all parts of a data mesh below a height a certain color. provide innermaskheight and innermaskcolor options also (default "off", ex: "on", "off")');
-	console.log('       "mask": list of flags of size numberofnodes or numberofelements. Only "true" values are plotted ');
-	console.log('       "log": value of log');
+	
 	console.log('  ');
 	console.log('   Examples:');
Index: /issm/trunk-jpl/src/m/plot/webgl.js
===================================================================
--- /issm/trunk-jpl/src/m/plot/webgl.js	(revision 21172)
+++ /issm/trunk-jpl/src/m/plot/webgl.js	(revision 21173)
@@ -83,6 +83,8 @@
 } //}}}
 function Node(gl,options) { //{{{
-	//Returns a Node object that contains default display states for webgl object
-	return {buffers:[],
+	//Returns a Node object that contains default display states for webgl object. center represents pivot point of rotation.
+	return {
+		buffers:[],
+		name:"node",
 		shader:gl.shaders["Colored"],
 		draw:null,
@@ -97,7 +99,8 @@
 		drawMode:gl.TRIANGLES,
 		texture:null,
+		scale:vec3.fromValues(1, 1, 1),
+		rotation:vec3.create(),
 		translation:vec3.create(),
-		rotation:vec3.fromValues(-90, 0, 0),
-		scale:vec3.fromValues(1, 1, 1),
+		center:vec3.create(), 
 		modelMatrix:mat4.create(),
 		shaderName:"Colored",
@@ -106,18 +109,25 @@
 		maskHeight:150.0,
 		maskColor:vec4.fromValues(0.0, 0.0, 1.0, 1.0),
-		enabled:true,
+		enabled:true
 	};
 } //}}}
+function displayNodes() {
+	var nodes = $('.sim-canvas')[0].nodes;
+	console.log("Nodes:");
+	for (var node in nodes) {
+		console.log("name", nodes[node]["name"], "translation", nodes[node]["translation"], "center", nodes[node]["center"], "rotation", nodes[node]["rotation"]);
+	}
+}
 function recalculateModelMatrix(node) { //{{{
 	//TODO: move to 0,0,0, rotate,move back to normal space, then apply transform
 	var modelMatrix = mat4.create();
 
+	var translationMatrix = mat4.create();
+	mat4.translate(translationMatrix, translationMatrix, [-node["center"][0],-node["center"][1],-node["center"][2]]); //scale/rotation centering
+	mat4.multiply(modelMatrix, translationMatrix, modelMatrix);
+	
 	var scaleMatrix = mat4.create();
 	mat4.scale(scaleMatrix, scaleMatrix, node["scale"]);
 	mat4.multiply(modelMatrix, scaleMatrix, modelMatrix);
-
-	var translationMatrix = mat4.create();
-	mat4.translate(translationMatrix, translationMatrix, node["translation"]); //relative translation
-	mat4.multiply(modelMatrix, translationMatrix, modelMatrix);
 	
 	var zRotationMatrix = mat4.create();	
@@ -130,5 +140,16 @@
 	mat4.rotate(xRotationMatrix, xRotationMatrix, radians(node["rotation"][0]), [1.0, 0.0, 0.0]);
 	mat4.multiply(modelMatrix, xRotationMatrix, modelMatrix);
-
+	
+	mat4.identity(translationMatrix);
+	mat4.translate(translationMatrix, translationMatrix, node["center"]); //relative translation
+	mat4.multiply(modelMatrix, translationMatrix, modelMatrix);
+	
+	// mat4.identity(translationMatrix);
+	// mat4.translate(translationMatrix, translationMatrix, [-node["translation"][0],-node["translation"][1],-node["translation"][2]]); //absolute translation
+	// mat4.multiply(modelMatrix, translationMatrix, modelMatrix);
+	
+	mat4.identity(translationMatrix);
+	mat4.translate(translationMatrix, translationMatrix, node["translation"]); //absolute translation
+	mat4.multiply(modelMatrix, translationMatrix, modelMatrix);
 	return modelMatrix;
 } //}}}
@@ -153,8 +174,8 @@
 function loadShaders(gl) { //{{{
 	shaders = {};
-	shaders["Colored"] = new Shader.fromURL("/js/shaders/Colored.vsh", "/js/shaders/Colored.fsh");
-	shaders["Textured"] = new Shader.fromURL("/js/shaders/Textured.vsh", "/js/shaders/Textured.fsh");
-	shaders["SkyFromSpace"] = new Shader.fromURL("/js/shaders/SkyFromSpace.vert", "/js/shaders/SkyFromSpace.frag");
-	shaders["GroundFromSpace"] = new Shader.fromURL("/js/shaders/GroundFromSpace.vert", "/js/shaders/GroundFromSpace.frag");
+	shaders["Colored"] = new Shader.fromURL("../../../js/shaders/Colored.vsh", "../../../js/shaders/Colored.fsh");
+	shaders["Textured"] = new Shader.fromURL("../../../js/shaders/Textured.vsh", "../../../js/shaders/Textured.fsh");
+	shaders["SkyFromSpace"] = new Shader.fromURL("../../../js/shaders/SkyFromSpace.vert", "../../../js/shaders/SkyFromSpace.frag");
+	shaders["GroundFromSpace"] = new Shader.fromURL("../../../js/shaders/GroundFromSpace.vert", "../../../js/shaders/GroundFromSpace.frag");
 	return shaders;
 } //}}}
@@ -168,14 +189,14 @@
 	if (ev.srcEvent.shiftKey || ev.pointers.length == 2) {
 		if (!canvas.viewPanning) return;
-		var deltaX = (canvas.lastDeltaX - ev.deltaX) / canvas.clientWidth / canvas.zoom * -2 * canvas.controlSensitivity;
-		var deltaY = (canvas.lastDeltaY - ev.deltaY) / canvas.clientHeight / canvas.zoom * -2 * canvas.controlSensitivity;
+		var deltaX = (canvas.lastDeltaX - ev.deltaX) / canvas.clientWidth / canvas.zoom * -2 * canvas.controlSensitivity * 6371000.0;
+		var deltaY = (canvas.lastDeltaY - ev.deltaY) / canvas.clientHeight / canvas.zoom * -2 * canvas.controlSensitivity * 6371000.0;
 		
 		if (canvas.twod) {
 			canvas.translation[0] += Math.cos(radians(canvas.rotation[0])) * deltaX - Math.sin(radians(0)) * deltaY;
-			canvas.translation[1] += Math.sin(radians(canvas.rotation[0])) * deltaX + Math.cos(radians(0)) * deltaY;
+			canvas.translation[2] += Math.sin(radians(canvas.rotation[0])) * deltaX + Math.cos(radians(0)) * deltaY;
 		}
 		else {
 			canvas.translation[0] += Math.cos(radians(canvas.rotation[0])) * deltaX - Math.sin(radians(canvas.rotation[0])) * deltaY;
-			canvas.translation[1] += Math.sin(radians(canvas.rotation[0])) * deltaX + Math.cos(radians(canvas.rotation[0])) * deltaY;
+			canvas.translation[2] += Math.sin(radians(canvas.rotation[0])) * deltaX + Math.cos(radians(canvas.rotation[0])) * deltaY;
 		}
 	}
@@ -203,13 +224,14 @@
 	}
 	else {
-		canvas.zoom = clamp(ev.scale * canvas.zoomLast, canvas.zoomBounds[0], canvas.zoomBounds[1]);
-		if (displaylog) console.log(canvas.zoom);
+		modifyZoom(ev.scale * canvas.zoomLast, canvas, displaylog);
 	}
 } //}}}
 function onZoom(ev,canvas,displaylog) { //{{{
 	ev.preventDefault();
-	var delta = clamp(ev.scale || ev.wheelDelta || -ev.detail, -1, 1) * canvas.controlSensitivity * canvas.zoom / 20;
-	canvas.zoom = clamp(canvas.zoom + delta, canvas.zoomBounds[0], canvas.zoomBounds[1]);
-	
+	var delta = clamp(ev.scale || ev.wheelDelta || -ev.detail, -1, 1) * canvas.controlSensitivity * canvas.zoom / 10;
+	modifyZoom(canvas.zoom + delta, canvas, displaylog);
+} //}}}
+function modifyZoom(value,canvas,displaylog) { //{{{
+	canvas.zoom = clamp(value, canvas.zoomBounds[0], canvas.zoomBounds[1]);
 	if (displaylog) console.log(canvas.zoom);
 } //}}}
@@ -230,9 +252,9 @@
 	}
 	else {
-		mat4.perspective(pMatrix, 60 * Math.PI / 180, aspectRatio, 1000, 10000000000.0);
+		mat4.perspective(pMatrix, 60 * Math.PI / 180, aspectRatio, 100, 1000000000.0);
 	}
 	
 	//Apply worldspace translation
-	mat4.translate(translateMatrix, translateMatrix, [6371000.0 * canvas.translation[0], 6371000.0 * canvas.translation[2], 6371000.0 * canvas.translation[1]]);
+	mat4.translate(translateMatrix, translateMatrix, [-canvas["translation"][0],-canvas["translation"][1],-canvas["translation"][2]]);
 	mat4.multiply(vMatrix, translateMatrix, vMatrix);
 	
