2 コミット 569f34f5be ... e9020a37e3

作者 SHA1 メッセージ 日付
  Malf e9020a37e3 ground tiling is fishy 2 年 前
  Malf ac58d2a1ef add texture download 2 年 前
共有12 個のファイルを変更した139 個の追加27 個の削除を含む
  1. 3 1
      ChunkSystem.gd
  2. 1 0
      Downloader_UI.gd
  3. 1 1
      Main.gd
  4. 1 1
      Main.tscn
  5. 14 5
      Player.gd
  6. 21 3
      TextureLoader.gd
  7. 26 4
      Tile.gd
  8. 38 5
      TopoLoader.gd
  9. 6 0
      chunk.gd
  10. 17 7
      downloader.gd
  11. 5 0
      project.godot
  12. 6 0
      shader/ground_shader.tres

+ 3 - 1
ChunkSystem.gd

@@ -6,7 +6,7 @@ onready var Player = $"../Player"
 var resolution = 512
 var scaleFact = 1000
 var radius = 1737.4*scaleFact
-var renderDistance = 3
+var renderDistance = 2
 
 var chunkIndex = {}
 
@@ -21,6 +21,8 @@ func _process(delta):
 	var playerChunkPos = posToChunPos(playerSpos)
 	var playerInterChunkPos = Vector2(playerSpos.x - playerChunkPos.x, playerSpos.y - playerChunkPos.y)
 	
+	add_chunk(playerChunkPos)
+	
 	for lon in range(playerChunkPos.y-renderDistance, playerChunkPos.y+renderDistance):
 		for lat in range(playerChunkPos.x-renderDistance, playerChunkPos.x+renderDistance):
 			if not (chunkIndex.has(lon) and chunkIndex[lon].has(lat)):

+ 1 - 0
Downloader_UI.gd

@@ -11,6 +11,7 @@ var last_update=OS.get_ticks_msec()
 # Called when the node enters the scene tree for the first time.
 func _ready():
 	Messenger.connect("statusUpdate", self, "_on_status_updated")
+	hide()
 
 
 # Called every frame. 'delta' is the elapsed time since the previous frame.

+ 1 - 1
Main.gd

@@ -16,7 +16,7 @@ extends Spatial
 
 #var resolution = 512
 var radius = 1737.4*1000
-var startPos = Vector3(0,354,radius)
+var startPos = Vector3(10, 10,radius + 500)
 
 #var curlat = 0
 #var curlon = 0

+ 1 - 1
Main.tscn

@@ -33,7 +33,7 @@ height = 14.0
 material = ExtResource( 5 )
 size = Vector2( 20, 20 )
 
-[node name="root" type="Spatial"]
+[node name="Main" type="Spatial"]
 script = ExtResource( 1 )
 __meta__ = {
 "_edit_lock_": true

+ 14 - 5
Player.gd

@@ -38,8 +38,13 @@ onready var up = global_transform.origin.normalized()
 onready var forward = global_transform.basis.y
 onready var right = forward.cross(up).normalized()
 
+var maxheight = 10.783
+var minheight = -8.719
+var radius = 1737.4
+
 export (int) var move_mode = 0
 enum moveMode {MODE_NORMAL, MODE_HOVER, MODE_FLY}
+var height_over_ground = 0
 
 func _ready():
 	if mouse_captured:
@@ -48,7 +53,7 @@ func _ready():
 	
 func moveTo(pos = Vector3()):
 	if pos.z == 0:
-		pos.z = 1737.4
+		pos.z = radius
 	move_and_slide(Common.latLonToGlobal(Vector3(pos.x,pos.y,pos.z)), Vector3.UP)
 
 func getSpos():
@@ -62,6 +67,7 @@ func _process(delta):
 	.get_parent().get_node("UI/2").text="latlonhight: "+str(getSpos())+","+str(pos.length())
 	.get_parent().get_node("UI/3").text="vel: %s" % velocity
 	.get_parent().get_node("UI/4").text="mode: %s" % move_mode
+	height_over_ground = pos.length() - radius*1000
 
 	#floor_normal = pos.normalized()
 	#gravaty_vector = floor_normal * -1
@@ -83,7 +89,7 @@ func _physics_process(delta):
 		moveMode.MODE_FLY:
 			horDir = forward
 		moveMode.MODE_HOVER:
-			horDir = -velocity * 0.5
+			horDir = -velocity * 0.1
 	
 	if can_move and (is_on_floor() or allow_fall_input):
 		
@@ -117,11 +123,14 @@ func _physics_process(delta):
 		#Sprint toggle
 		if can_sprint and Input.is_action_just_pressed("move_sprint"): #and is_on_floor():
 			move_sprint = true
-			move_speed_max = 600
-			
+		
 		if can_sprint and not Input.is_action_pressed("move_sprint"): #and is_on_floor():
 			move_sprint = false
-			move_speed_max = 200
+		
+		if move_sprint:
+			move_speed_max = 600 + 2000 * inverse_lerp(minheight*1000, maxheight*1000, height_over_ground)
+		else:
+			move_speed_max = 200 + 800 * inverse_lerp(minheight*1000, maxheight*1000, height_over_ground)# height_over_ground * 100 + 400
 			
 		#Hover toggle
 		if Input.is_action_just_pressed("hover_mode"):

+ 21 - 3
TextureLoader.gd

@@ -3,13 +3,31 @@ extends Reference
 
 var filePrexif = "user://colorTiles"
 
+var lat = 0
+var lon = 0
 
 # Called when the node enters the scene tree for the first time.
 func _ready():
 	pass # Replace with function body.
 
-func loadTexture(lat, lon):
-	var texName = getTexName(lat, lon)
+# this function essentially checks if the file exists and starts a download if not
+func open(latIN, lonIN):
+	lat = latIN
+	lon = lonIN
+	var file = File.new()
+	var err = file.open(getTexName(), File.READ)
+	if err == 7:
+		Downloader.download(getTexName(), "color")
+		return false
+	elif err != OK:
+		print("error opening tex ", err)
+		return false
+	else:
+		file.close()
+		return true
+
+func loadTexture():
+	var texName = getTexName()
 	print("opening texture "+texName)
 	var image = Image.new()
 	var err = image.load(texName)
@@ -19,7 +37,7 @@ func loadTexture(lat, lon):
 	tex.create_from_image(image, 0)
 	return tex
 	
-func getTexName(lat, lon):
+func getTexName():
 	return "%s/m-%s-%s.png" % [filePrexif, (int(lat)+90)%180, (int(lon)+180)%360]
 	#return "res://tex/grid.png"
 

+ 26 - 4
Tile.gd

@@ -4,6 +4,7 @@ var Point = preload("res://point.tscn")
 var TopoLoader = preload("res://TopoLoader.gd")
 var tl
 var TextureLoader = preload("res://TextureLoader.gd")
+var texl
 
 var groundShader = preload("res://shader/ground_shader.tres") as ShaderMaterial
 
@@ -18,6 +19,10 @@ var scaleFact:int = 1
 var origin:Vector3
 var center:Vector3
 
+var heightmap:Image
+var overlay_heightmap = false
+var mat:ShaderMaterial
+
 var initialized = false
 
 func initialize(latMinIN, latMaxIN, lonMinIN, lonMaxIN, resolutionIN, radiusIN:float, scaleIN):	
@@ -42,6 +47,16 @@ func _ready():
 	#genMesh called from chunk
 	#self.genMesh()
 	
+func initTexture():
+	texl = TextureLoader.new()
+	var exists = texl.open(latMin, lonMin)
+	return exists
+	
+func _process(delta):
+	if Input.is_action_just_pressed("overlay"):
+		overlay_heightmap = not overlay_heightmap
+		mat.set_shader_param("overlay_heightmap", overlay_heightmap)
+	
 func genMesh():
 	#print("generating Mesh:")
 	#print("latMin: " + str(latMin))
@@ -59,10 +74,13 @@ func genMesh():
 	arr[Mesh.ARRAY_INDEX] = genIndex()
 	mesh = Mesh.new()
 	mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arr)
-	var mat = groundShader.duplicate()
+	mat = groundShader.duplicate()
 	#mat.albedo_color = Color(0.7,0.7,0.7,1)
-	var texl = TextureLoader.new()
-	mat.set_shader_param("texture_albedo_big", texl.loadTexture(latMin, lonMin))
+	mat.set_shader_param("texture_albedo_big", texl.loadTexture())
+	heightmap = tl.createHeightmap()
+	var heighttex = ImageTexture.new()
+	heighttex.create_from_image(heightmap, 0)
+	mat.set_shader_param("texture_heightmap", heighttex)
 	mesh.surface_set_material(0,mat)
 	.create_trimesh_collision()
 	
@@ -150,7 +168,11 @@ func genSphereCoords():
 		for x in range(0,resolution+1):
 			var lat = latMin+latStep*y
 			var lon = lonMin+lonStep*x
-			verts[v_idx] = Vector3(lat, lon, radius+tl.read(lat,lon)*scaleFact)
+			var height = tl.read(lat,lon)
+			if not height and height != 0:
+				push_error("could not get height")
+				return
+			verts[v_idx] = Vector3(lat, lon, radius+height*scaleFact)
 			v_idx+=1
 	tl.close()
 	return verts

+ 38 - 5
TopoLoader.gd

@@ -12,6 +12,8 @@ var offset = 1737.4*1000
 var scaleFact = 1
 var resolution = 512
 var orientation: String = "N"
+var maxheight = 10.783
+var minheight = -8.719
 
 var latMin = 0
 var latMax = 30
@@ -22,18 +24,21 @@ var cache = {}
 var file: File
 var fileReady = false
 
+onready var heightmap = Image.new()
+
 signal fileReady
 
 # Called when the node enters the scene tree for the first time.
 func open(latMinIN, lonMinIn):
 	latMin = (int(latMinIN)/30) * 30
-	latMax = latMin+30
-	lonMin = (int(lonMinIn)/45) * 45
-	lonMax = lonMin+45
 	if latMinIN >= 0:
 		orientation = "N"
+		latMax = latMin+30
 	else:
 		orientation = "S"
+		latMax = latMin-30
+	lonMin = (int(lonMinIn)/45) * 45
+	lonMax = lonMin+45
 		
 	file = File.new()
 	print("opening topo: "+getFilepath())
@@ -73,7 +78,7 @@ func cacheArea(latMinIN, latMaxIN, lonMinIN, lonMaxIN):
 		return
 	
 	if not file.is_open():
-		file.open(getFilepath(), File.READ)
+		var err = file.open(getFilepath(), File.READ)
 		
 	var lat = latMinIN
 	while lat <= latMaxIN:
@@ -93,6 +98,34 @@ func cacheArea(latMinIN, latMaxIN, lonMinIN, lonMaxIN):
 		lat += 1.0/float(resolution)
 	return
 	
+func createHeightmap():
+	var minLat
+	var minLon
+	var maxLat
+	var maxLon
+	var idxX = 0
+	var idxY = 0
+	var value = 0.0
+	heightmap.create(len(cache[cache.keys()[0]]), len(cache), false, Image.FORMAT_RF)
+	heightmap.lock()
+	for y in cache.keys():
+		if not minLat:
+			minLat = y
+		for x in cache[y].keys():
+			if not minLon:
+				minLon = x
+			value = inverse_lerp(minheight, maxheight, cache[y][x])
+			heightmap.set_pixel(idxX, idxY, Color(value,0,0))#Color(cache[y][x],0,0))
+			maxLon = x
+			idxX += 1
+		maxLat = y
+		idxY += 1
+		idxX = 0
+	heightmap.unlock()
+	var heightmapfilepath = "user://heightmap/%s:%s-%s:%s.png"%[minLat, minLon, maxLat, maxLon]
+	heightmap.save_png(heightmapfilepath)
+	return heightmap
+
 func read(lat,lon):
 	if _validate(lat,lon):
 		return cache[lat][lon]
@@ -121,7 +154,7 @@ func getFilename():
 	#     "%s/sldem2015_%s_%0*d%s_%0*d%s_%00*d_%00*d_float.img"
 	var properties
 	if orientation == "S":
-		properties = [resolution, latMax, orientation, latMin, orientation, lonMin, lonMax]
+		properties = [resolution, abs(latMax), orientation, abs(latMin), orientation, lonMin, lonMax]
 	else:
 		properties = [resolution, latMin, orientation, latMax, orientation, lonMin, lonMax]
 	return formatString % properties

+ 6 - 0
chunk.gd

@@ -39,6 +39,12 @@ func initialize():
 		while not download._file_name == .get_node("Mesh").tl.getFilepath():
 			print("awaiting file download for %s" %.get_node("Mesh").tl.getFilepath())
 			download = yield(Messenger, "fileDownloaded")
+	var texInitialized = .get_node("Mesh").initTexture()
+	if not texInitialized:
+		var dl = Downloader.Download.new()
+		while not dl._file_name == .get_node("Mesh").texl.getTexName():
+			print("awaiting file download for %s" %.get_node("Mesh").texl.getTexName())
+			dl = yield(Messenger, "fileDownloaded")
 	.get_node("Mesh").genMesh()
 	.get_node("Origin").transform.origin = .get_node("Mesh").origin
 	.get_node("Center").transform.origin = .get_node("Mesh").center

+ 17 - 7
downloader.gd

@@ -2,12 +2,14 @@ extends HTTPRequest
 
 var kinds = {
 	"topo": "http://imbrium.mit.edu/DATA/SLDEM2015/TILES/FLOAT_IMG/%s",
-	"color": "" 
+	"color": "https://nextcloud.alfi.li/nextcloud/index.php/s/dMELm8P8sPxbC5f/download?path=%2F&files=%s" 
 }
 
 var downloads = {}
 var downloading = false
 
+onready var UI = get_node("/root/Main/UI/Downloader")
+
 signal file_downloaded
 signal downloads_finished
 signal stats_updated
@@ -53,6 +55,7 @@ func _downloads_done() -> void:
 	emit_signal("downloads_finished", currentDownload)
 	_reset()
 	downloading = false
+	UI.hide()
 	
 func _update_stats() -> void:
 	if blind_mode == false:
@@ -80,6 +83,7 @@ func _download():
 	_send_head_request()
 	print("downloading %s" %currentDownload._current_url)
 	downloading = true
+	UI.show()
 
 func ensureFolder(kind):
 	var dir = Directory.new()
@@ -130,6 +134,9 @@ func _on_request_completed(p_result,
 						   p_headers,
 						   _p_body) -> void:
 	if p_result == RESULT_SUCCESS:
+		if _p_response_code != 200:
+			push_error("Download HTTP Error %s:%s" %[_p_response_code,_p_body])
+			return
 		if _last_method == HTTPClient.METHOD_HEAD and blind_mode == false:
 			var regex = "(?i)content-length: [0-9]*"
 			var size  = _extract_regex_from_header(regex, p_headers.join(' '))
@@ -146,22 +153,25 @@ func _on_request_completed(p_result,
 			emit_signal("file_downloaded", currentDownload)
 			Messenger._on_file_downloaded(currentDownload)
 			downloading = false
-			downloads[currentDownload._kind].erase(currentDownload._file_name)
-			if len(downloads[currentDownload._kind]) == 0:
-				downloads.erase(currentDownload._kind)
-			if len(downloads) == 0:
-				_downloads_done()
+			remove_download()
 				
 	elif p_result == RESULT_DOWNLOAD_FILE_CANT_OPEN:
 		push_error("Download cannot open file %s" %currentDownload._file_name)
 	else:
 		print("HTTP Request error: ", p_result)
 
+func remove_download():
+	downloads[currentDownload._kind].erase(currentDownload._file_name)
+	if len(downloads[currentDownload._kind]) == 0:
+		downloads.erase(currentDownload._kind)
+	if len(downloads) == 0:
+		_downloads_done()
+
 func _calculate_percentage() -> void:
 	var error : int
 	error = _file.open(download_file, File.READ)
 
-	if error == OK:
+	if error == OK and currentDownload._file_size > 0:
 		currentDownload._downloaded_size    = _file.get_len()
 		currentDownload._downloaded_percent = (currentDownload._downloaded_size / currentDownload._file_size) *100
 		

+ 5 - 0
project.godot

@@ -72,6 +72,11 @@ fly_mode={
 "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":70,"unicode":0,"echo":false,"script":null)
  ]
 }
+overlay={
+"deadzone": 0.5,
+"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":79,"unicode":0,"echo":false,"script":null)
+ ]
+}
 
 [physics]
 

+ 6 - 0
shader/ground_shader.tres

@@ -14,6 +14,7 @@ render_mode blend_mix,depth_draw_opaque,cull_back,diffuse_burley,specular_schlic
 uniform vec4 albedo : hint_color;
 uniform sampler2D texture_albedo_big;
 uniform sampler2D texture_albedo : hint_albedo;
+uniform sampler2D texture_heightmap;
 uniform float specular;
 uniform float roughness : hint_range(0,1);
 uniform float point_size : hint_range(0,128);
@@ -33,6 +34,7 @@ uniform vec3 uv1_scale;
 uniform vec3 uv1_offset;
 uniform vec2 uv2_scale;
 uniform vec3 uv2_offset;
+uniform bool overlay_heightmap;
 
 vec4 soft_light(vec4 base, vec4 blend){
 	vec4 limit = step(0.5, blend);
@@ -89,6 +91,9 @@ void fragment() {
 	vec4 albedo_tex_big = texture(texture_albedo_big,base_uv);
 	//ALBEDO = albedo.rgb * (albedo_tex.rgb + albedo_tex_big.rgb);
 	ALBEDO = screen(albedo_tex, albedo_tex_big).rgb;
+	if(overlay_heightmap){
+		ALBEDO.r = ALBEDO.r + texture(texture_heightmap, base_uv).r;
+	}
 	float roughness_tex = dot(texture(texture_roughness,scaled_uv),roughness_texture_channel);
 	ROUGHNESS = roughness_tex * roughness;
 	SPECULAR = specular;
@@ -117,6 +122,7 @@ shader_param/uv1_scale = Vector3( 1, 1, 1 )
 shader_param/uv1_offset = Vector3( 0, 0, 0 )
 shader_param/uv2_scale = Vector2( 512, 512 )
 shader_param/uv2_offset = Vector3( 0, 0, 0 )
+shader_param/overlay_heightmap = null
 shader_param/texture_albedo = ExtResource( 6 )
 shader_param/texture_roughness = ExtResource( 4 )
 shader_param/texture_normal = ExtResource( 5 )