extends StaticBody tool onready var mesh_instance = $MeshInstance export(OpenSimplexNoise) var noise = OpenSimplexNoise.new() setget set_noise export var amplitude = 10 setget set_amplitude export var radius = 100 setget set_radius # Called when the node enters the scene tree for the first time. func _ready(): refresh_mesh() if not Engine.editor_hint: mesh_instance.create_trimesh_collision() func refresh_mesh(): if not Engine.editor_hint and not mesh_instance: return var mesh = ArrayMesh.new() var plane = PlaneMesh.new() plane.subdivide_width = 400 plane.subdivide_depth = 400 plane.size = Vector2(400, 400) mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, plane.get_mesh_arrays()) var mdt = MeshDataTool.new() mdt.create_from_surface(mesh, 0) for i in range(mdt.get_vertex_count()): var vertex = mdt.get_vertex(i) var height = noise.get_noise_2d(vertex.x, vertex.z) * amplitude # Outside radius we ramp down var r2_max = radius*radius var r2 = vertex.x * vertex.x + vertex.z * vertex.z if r2 > r2_max: var drop_off_dist = 16000 var delta_h = clamp(r2-r2_max, 0, drop_off_dist)/drop_off_dist*amplitude height -= delta_h vertex.y += height mdt.set_vertex(i, vertex) # Calculate vertex normals, face-by-face. for i in range(mdt.get_face_count()): # Get the index in the vertex array. var a = mdt.get_face_vertex(i, 0) var b = mdt.get_face_vertex(i, 1) var c = mdt.get_face_vertex(i, 2) # Get vertex position using vertex index. var ap = mdt.get_vertex(a) var bp = mdt.get_vertex(b) var cp = mdt.get_vertex(c) # Calculate face normal. var n = (bp - cp).cross(ap - bp).normalized() # Add face normal to current vertex normal. # This will not result in perfect normals, but it will be close. mdt.set_vertex_normal(a, n + mdt.get_vertex_normal(a)) mdt.set_vertex_normal(b, n + mdt.get_vertex_normal(b)) mdt.set_vertex_normal(c, n + mdt.get_vertex_normal(c)) # Run through vertices one last time to normalize normals and # set color to normal. for i in range(mdt.get_vertex_count()): var v = mdt.get_vertex_normal(i).normalized() mdt.set_vertex_normal(i, v) mesh.surface_remove(0) mdt.commit_to_surface(mesh) mesh_instance.mesh = mesh func set_noise(n): noise = n if Engine.editor_hint: refresh_mesh() func set_amplitude(a): amplitude = a if Engine.editor_hint: refresh_mesh() func set_radius(r): radius = r if Engine.editor_hint: refresh_mesh()