You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
societer/utils/map/map.gd

277 lines
10 KiB

extends Reference
# Build Height map, Biome map, Temperature map and Moisture map
class_name Map
var data = {}
var terrain
# Called when the node enters the scene tree for the first time.
func _init(a_terrain):
var texture_colors = {}
var height_gradient
var temperature_gradient
var moisture_gradient
self.terrain = a_terrain
a_terrain.set_data("map",self)
# Read texture colors
var file = File.new()
file.open("res://world/texture_colors.json", File.READ)
var json_data = JSON.parse(file.get_as_text()).result
file.close()
for key in json_data:
print("Texture color : %s" % (key))
texture_colors[key] = Color(
json_data[key]["r"],
json_data[key]["g"],
json_data[key]["b"])
# read gradients
file.open("res://world/maps.json", File.READ)
json_data = JSON.parse(file.get_as_text()).result
file.close()
height_gradient = Gradient.new()
for gradient_point in json_data["gradients"]["height"]:
height_gradient.add_point(gradient_point["offset"], Color(
gradient_point["color"]["r"],
gradient_point["color"]["g"],
gradient_point["color"]["b"]))
temperature_gradient = Gradient.new()
for gradient_point in json_data["gradients"]["temperature"]:
temperature_gradient.add_point(gradient_point["offset"], Color(
gradient_point["color"]["r"],
gradient_point["color"]["g"],
gradient_point["color"]["b"]))
moisture_gradient = Gradient.new()
for gradient_point in json_data["gradients"]["moisture"]:
moisture_gradient.add_point(gradient_point["offset"], Color(
gradient_point["color"]["r"],
gradient_point["color"]["g"],
gradient_point["color"]["b"]))
terrain.set_temp_data("texture_colors", texture_colors)
terrain.set_temp_data("height_gradient", height_gradient)
terrain.set_temp_data("temperature_gradient", temperature_gradient)
terrain.set_temp_data("moisture_gradient", moisture_gradient)
func gen_map():
var max_elevation = null
var min_elevation = null
var max_temperature = null
var min_temperature = null
var max_moisture = null
var min_moisture = null
var texture_colors = terrain.get_temp_data("texture_colors")
var height_gradient = terrain.get_temp_data("height_gradient")
var temperature_gradient = terrain.get_temp_data("temperature_gradient")
var moisture_gradient = terrain.get_temp_data("moisture_gradient")
Global.loadings["world_creation"].new_phase("Generation des cartes...", terrain._points.size())
Global.print_debug("Init data")
data["height"] = {}
data["biome"] = {}
data["temperature"] = {}
data["moisture"] = {}
Global.print_debug("Create images objects")
data["height"]["image"] = Image.new()
data["biome"]["image"] = Image.new()
data["temperature"]["image"] = Image.new()
data["moisture"]["image"] = Image.new()
Global.print_debug("Create images")
data["height"]["image"].create(terrain._width,terrain._height,false,Image.FORMAT_RGBA8)
data["biome"]["image"].create(terrain._width,terrain._height,false,Image.FORMAT_RGBA8)
data["temperature"]["image"].create(terrain._width,terrain._height,false,Image.FORMAT_RGBA8)
data["moisture"]["image"].create(terrain._width,terrain._height,false,Image.FORMAT_RGBA8)
Global.print_debug("Lock images")
data["height"]["image"].lock()
data["biome"]["image"].lock()
data["temperature"]["image"].lock()
data["moisture"]["image"].lock()
Global.print_debug("Fill height map oceans")
data["height"]["image"].fill(texture_colors["ocean"])
Global.print_debug("Fill biome map oceans")
data["biome"]["image"].fill(texture_colors["ocean"])
Global.print_debug("Fill temperature map oceans")
data["temperature"]["image"].fill(texture_colors["ocean"])
Global.print_debug("Fill moisture map oceans")
data["moisture"]["image"].fill(texture_colors["ocean"])
Global.print_debug("Unlock images")
data["height"]["image"].unlock()
data["biome"]["image"].unlock()
data["temperature"]["image"].unlock()
data["moisture"]["image"].unlock()
Global.print_debug("Init paths")
data["height"]["file_name"] = "user://terrain/%s/height_map.png" % (terrain.get_name())
data["biome"]["file_name"] = "user://terrain/%s/biome_map.png" % (terrain.get_name())
data["temperature"]["file_name"] = "user://terrain/%s/temperature_map.png" % (terrain.get_name())
data["moisture"]["file_name"] = "user://terrain/%s/moisture_map.png" % (terrain.get_name())
Global.print_debug("For centers ...")
for center in terrain.get_centers():
if not center.get_data("water"):
var voronoi = center.get_data("voronoi")
var voronoi_bounding_box = center.get_data("voronoi_bounding_box")
var voronoi_image = {}
var color = {}
var elevation = center.get_elevation()
if max_elevation == null:
max_elevation = elevation
min_elevation = elevation
else:
if elevation > max_elevation:
max_elevation = elevation
if elevation < min_elevation:
min_elevation = elevation
var temperature = center.get_data("temperature")
if max_temperature == null:
max_temperature = temperature
min_temperature = temperature
else:
if temperature > max_temperature:
max_temperature = temperature
if temperature < min_temperature:
min_temperature = temperature
var moisture = center.get_data("moisture")
if max_moisture == null:
max_moisture = moisture
min_moisture = moisture
else:
if moisture > max_moisture:
max_moisture = moisture
if moisture < min_moisture:
min_moisture = moisture
# Global.print_debug("Elevation : %f" % (elevation))
# Global.print_debug("Temperature : %f" % (temperature))
# Global.print_debug("Moisture : %f" % (moisture))
voronoi_image["height"] = Image.new()
voronoi_image["biome"] = Image.new()
voronoi_image["temperature"] = Image.new()
voronoi_image["moisture"] = Image.new()
voronoi_image["height"].create(int(voronoi_bounding_box.size.x), int(voronoi_bounding_box.size.y),false,Image.FORMAT_RGBA8)
voronoi_image["biome"].create(int(voronoi_bounding_box.size.x), int(voronoi_bounding_box.size.y),false,Image.FORMAT_RGBA8)
voronoi_image["temperature"].create(int(voronoi_bounding_box.size.x), int(voronoi_bounding_box.size.y),false,Image.FORMAT_RGBA8)
voronoi_image["moisture"].create(int(voronoi_bounding_box.size.x), int(voronoi_bounding_box.size.y),false,Image.FORMAT_RGBA8)
voronoi_image["height"].lock()
voronoi_image["biome"].lock()
voronoi_image["temperature"].lock()
voronoi_image["moisture"].lock()
# Height map
# Global.print_debug("Height map")
color["height"] = height_gradient.interpolate(elevation)
# Biome map
# Global.print_debug("Biome map")
if center.get_data("coast"):
# Coast color
color["biome"] = texture_colors["sand"]
elif center.get_data("snow"):
# Snow color
color["biome"] = texture_colors["snow"]
elif center.get_data("river"):
# River color
color["biome"] = texture_colors["river"]
elif center.get_data("mountain"):
# Montain color
color["biome"] = texture_colors["stone"]
else:
# Grass color
color["biome"] = texture_colors["grass"]
# Temperature map
# Global.print_debug("Temperature map")
color["temperature"] = temperature_gradient.interpolate(range_lerp(temperature,-80.0,50.0,0.001,0.999))
# Moisture map
# Global.print_debug("Moisture map")
color["moisture"] = moisture_gradient.interpolate(range_lerp(moisture,-0.7,0.7,0.001,0.999))
for x in int(voronoi_bounding_box.size.x):
for y in int(voronoi_bounding_box.size.y):
var pixel = []
pixel.append(Vector2(voronoi_bounding_box.position.x + x, voronoi_bounding_box.position.y + y))
pixel.append(Vector2(voronoi_bounding_box.position.x + x + 1, voronoi_bounding_box.position.y + y))
pixel.append(Vector2(voronoi_bounding_box.position.x + x + 1, voronoi_bounding_box.position.y + y + 1))
pixel.append(Vector2(voronoi_bounding_box.position.x + x, voronoi_bounding_box.position.y + y + 1))
var alpha = Global.pixel_area(voronoi, pixel)
color["height"].a = alpha
color["biome"].a = alpha
color["temperature"].a = alpha
color["moisture"].a = alpha
voronoi_image["height"].set_pixel(x,y,color["height"])
voronoi_image["biome"].set_pixel(x,y,color["biome"])
voronoi_image["temperature"].set_pixel(x,y,color["temperature"])
voronoi_image["moisture"].set_pixel(x,y,color["moisture"])
# Global.print_debug("Lock image")
data["height"]["image"].lock()
data["biome"]["image"].lock()
data["temperature"]["image"].lock()
data["moisture"]["image"].lock()
# Global.print_debug("Blend image")
data["height"]["image"].blend_rect(voronoi_image["height"],Rect2(0.0,0.0,voronoi_bounding_box.size.x,voronoi_bounding_box.size.y),voronoi_bounding_box.position)
data["biome"]["image"].blend_rect(voronoi_image["biome"],Rect2(0.0,0.0,voronoi_bounding_box.size.x,voronoi_bounding_box.size.y),voronoi_bounding_box.position)
data["temperature"]["image"].blend_rect(voronoi_image["temperature"],Rect2(0.0,0.0,voronoi_bounding_box.size.x,voronoi_bounding_box.size.y),voronoi_bounding_box.position)
data["moisture"]["image"].blend_rect(voronoi_image["moisture"],Rect2(0.0,0.0,voronoi_bounding_box.size.x,voronoi_bounding_box.size.y),voronoi_bounding_box.position)
# Global.print_debug("Unlock image")
data["height"]["image"].unlock()
data["biome"]["image"].unlock()
data["temperature"]["image"].unlock()
data["moisture"]["image"].unlock()
voronoi_image["height"].unlock()
voronoi_image["biome"].unlock()
voronoi_image["temperature"].unlock()
voronoi_image["moisture"].unlock()
Global.loadings["world_creation"].increment_step()
Global.print_debug("Max elevation : %f" % (max_elevation))
Global.print_debug("Min elevation : %f" % (min_elevation))
Global.print_debug("Max temperature : %f" % (max_temperature))
Global.print_debug("Min temperature : %f" % (min_temperature))
Global.print_debug("Max moisture : %f" % (max_moisture))
Global.print_debug("Min moisture : %f" % (min_moisture))
data["height"]["image"].save_png(data["height"]["file_name"])
data["biome"]["image"].save_png(data["biome"]["file_name"])
data["temperature"]["image"].save_png(data["temperature"]["file_name"])
data["moisture"]["image"].save_png(data["moisture"]["file_name"])
Global.print_debug("Sauvegarde map")