extends Node #var Downloader = preload("res://downloader.gd") var cache = {} var topoChunks = {} var maxheight = 10.783 var minheight = -8.719 signal fileReady signal chunkCached class topoChunk: var chunkPos: Vector2 var filePrefix = "user://topo/" var formatString = "SLDEM2015_%s_%02d%s_%02d%s_%03d_%03d_FLOAT.IMG" var samplesPerLine = 23040 var lines = 15360 var offset = 1737.4*1000 var scaleFact = 1 var resolution = 512 var orientation: String = "N" var latMin = 0 var latMax = 30 var lonMin = 0 var lonMax = 45 var chunkCached = false var fileReady = false var file: File # Called when the node enters the scene tree for the first time. func open(latMinIN, lonMinIN): chunkPos = Vector2(latMinIN, lonMinIN) latMin = (int(latMinIN)/30) * 30 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()) var err = file.open(getFilepath(), File.READ) if err == 7: Downloader.download(getFilename(), "topo") var dl = Downloader.Download.new() while not dl._file_name == getFilepath(): dl = yield(Messenger, "fileDownloaded") file.open(getFilepath(), File.READ) _fileReady() return true elif err != 0: push_error("error opening file err:%s" %err) return false else: fileReady = true return true func getFilename(): # example sldem2015_512_00n_30n_000_045_float.img # "%s/sldem2015_%s_%0*d%s_%0*d%s_%00*d_%00*d_float.img" var properties if orientation == "S": properties = [resolution, abs(latMax), orientation, abs(latMin), orientation, lonMin, lonMax] else: properties = [resolution, latMin, orientation, latMax, orientation, lonMin, lonMax] return formatString % properties func getFilepath(): return filePrefix+getFilename() func _fileReady(): fileReady = true Messenger.emit_signal("fileReady", self) func close(): file.close() #queue_free() func clear(): cache = {} func cacheChunk(chunkPos: Vector2): var tc if topoChunks.has(chunkPos.x) and topoChunks[chunkPos.x].has(chunkPos.y): tc = cache[chunkPos.y][chunkPos.x] return tc tc = topoChunk.new() tc.open(chunkPos.x, chunkPos.y) while tc.get_class() != topoChunk.get_class() and not tc.fileReady and tc.chunkPos != chunkPos: tc = yield(Messenger, "fileReady") var lat = chunkPos.x while lat <= chunkPos.x + 1.0: cache[lat]={} var line = abs(lat)*tc.resolution*tc.samplesPerLine*4 # the origin of each .img file lies in it's upper left corner # so we need to read the files from the end on the northern hemisphere if lat >= 0: var origin = tc.lines*tc.samplesPerLine*4 tc.file.seek((origin - line) + chunkPos.y*tc.resolution*4) else: tc.file.seek(line + chunkPos.y*tc.resolution*4) var lon = chunkPos.y while lon <= chunkPos.y + 1.0: cache[lat][lon] = tc.file.get_float() lon += 1.0/float(tc.resolution) lat += 1.0/float(tc.resolution) tc.chunkCached = true if not topoChunks.has(chunkPos.x): topoChunks[chunkPos.x] = {} topoChunks[chunkPos.x][chunkPos.y] = tc tc.file.close() Messenger.emit_signal("chunkCached", tc) return tc func createHeightmap(chunkPos:Vector2): var minLat:float = chunkPos.x var minLon:float = chunkPos.y var maxLat:float = chunkPos.x + 1.0 var maxLon:float = chunkPos.y + 1.0 var idxX = 0 var idxY = 0 var value = 0.0 var heightmap = Image.new() 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 cache.has(lat) and cache[lat].has(lon): return cache[lat][lon] else: print("out of scope!") #func _validate(lat,lon): # var condition = true # if abs(lat) > latMax: # condition = false # if abs(lat) < latMin: # condition = false # if lon > lonMax: # condition = false # if lon < lonMin: # condition = false # # return condition #if abs(lat) <= latMax and abs(lat) >= latMin and lon <= lonMax and lon >= lonMin: # return true #return false # Called every frame. 'delta' is the elapsed time since the previous frame. #func _process(delta): # pass