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/terrain_mesh/TerrainMesh.gd

117 lines
4.1 KiB

extends ArrayMesh
class_name TerrainMesh
var loader
func create_mesh():
var vertices = []
var normals = []
var uvs = []
var factor = Vector3(1, 120, 1)
Global.loadings["world_creation"].new_phase("Construction du modele 3d...", Global.terrain.get_centers().size())
for center in Global.terrain.get_centers():
# Global.loadings["world_creation"].increment_step()
if not center.get_data("water"):
var material_id = Global.materials[center.get_data("material")]
var top_uv = Vector2(0, float(material_id) / (Global.materials.size()-1))
var border_uv = Vector2(1, float(material_id) / (Global.materials.size()-1))
if center.get_data("snow"):
top_uv.y = float(Global.materials["snow"]) / (Global.materials.size()-1)
var corner_number = center.corner_count()
for corner_count in corner_number:
var current_corner = center.corner(corner_count)
var next_corner
if corner_count < corner_number - 1:
next_corner = center.corner(corner_count + 1)
else:
next_corner = center.corner(0)
for i in 3:
normals.append(Vector3.UP)
uvs.append(top_uv)
vertices.append(Vector3(current_corner.point2d().x, center.get_elevation(), current_corner.point2d().y) * factor)
vertices.append(Vector3(next_corner.point2d().x, center.get_elevation(), next_corner.point2d().y) * factor)
vertices.append(Vector3(center.point2d().x, center.get_elevation(), center.point2d().y) * factor)
for edge in center.borders():
if edge.end_center().get_elevation() < edge.start_center().get_elevation():
var top = edge.start_center().get_elevation()
var bottom = edge.end_center().get_elevation()
if edge.end_center().get_data("ocean"):
bottom = 0.0
var a = Vector3(edge.start_corner().point3d().x, bottom, edge.start_corner().point3d().z) * factor
var b = Vector3(edge.end_corner().point3d().x, top, edge.end_corner().point3d().z) * factor
var c = Vector3(edge.start_corner().point3d().x, top, edge.start_corner().point3d().z) * factor
var d = Vector3(edge.end_corner().point3d().x, bottom, edge.end_corner().point3d().z) * factor
var normal = get_triangle_normal(a, b, c)
for i in 6:
normals.append(normal)
uvs.append(border_uv)
vertices.append(a)
vertices.append(b)
vertices.append(c)
vertices.append(a)
vertices.append(d)
vertices.append(b)
Global.loadings["world_creation"].increment_step()
var array_mesh = []
array_mesh.resize(Mesh.ARRAY_MAX)
array_mesh[Mesh.ARRAY_VERTEX] = PoolVector3Array(vertices)
array_mesh[Mesh.ARRAY_NORMAL] = PoolVector3Array(normals)
array_mesh[Mesh.ARRAY_TEX_UV] = PoolVector2Array(uvs)
# var terrain_mesh = TerrainMesh.new()
var mesh = ArrayMesh.new()
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, array_mesh, [], Mesh.ARRAY_COMPRESS_DEFAULT ^ Mesh.ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION)
mesh.surface_set_material(0, load("res://world/materials/world.material"))
save_mesh(array_mesh)
return array_mesh
func get_triangle_normal(a, b, c):
# find the surface normal given 3 vertices
var side1 = b - a
var side2 = c - a
var normal = side1.cross(side2)
return normal
func save_mesh(array_mesh):
var directory = Directory.new()
Global.print_debug("Save mesh : %s" %(Global.terrain_name))
# Goto terrain directory
directory.open("user://")
if not directory.dir_exists("terrain"):
directory.make_dir("terrain")
directory.change_dir("terrain")
if not directory.dir_exists(Global.terrain_name):
directory.make_dir(Global.terrain_name)
directory.change_dir(Global.terrain_name)
var file = File.new()
var file_name = "user://terrain/%s/mesh.save" % (Global.terrain_name)
file.open(file_name, File.WRITE)
file.store_var(array_mesh)
file.close()
func load_mesh():
var file = File.new()
var file_name = "user://terrain/%s/mesh.save" % (Global.terrain_name)
Global.print_debug("Load mesh file : %s" % (file_name))
if file.file_exists(file_name):
file.open(file_name, File.READ)
var array_mesh = file.get_var()
file.close()
return array_mesh
else:
Global.print_debug("The mesh file : %s does not exist" % (file_name))