extends RefCounted ## Boulders for hand-placed rockwork (the cliff tunnel's seam and its faces, ## the Cove's sea cave): the same low-poly rocks as the scenery and the wolf ## den (ProcMesh.rock, rock.gdshader: moss on top, snow up high), each with a ## convex collider that matches it. const ProcMesh = preload("res://scripts/world/proc_mesh.gd") ## The scenery's rock material, for a world's terrain. static func material(terrain: Node3D) -> ShaderMaterial: var m := ShaderMaterial.new() m.shader = preload("res://shaders/rock.gdshader") m.set_shader_parameter("noise_tex", terrain.noise_tex) m.set_shader_parameter("snow_height", terrain.snow_height) return m ## One boulder under `parent` at local `at`, `radii` across (a rock mesh is ## about 1 m round before scaling), turned `turn` radians. Its collider goes ## on `body` (which must share `parent`'s transform), unless `body` is null. static func add(parent: Node3D, body: CollisionObject3D, seed: int, at: Vector3, radii: Vector3, turn: float, mat: Material, tall: bool = false) -> MeshInstance3D: var mesh := ProcMesh.rock(seed, tall) var b := Basis(Vector3.UP, turn).scaled(radii) var mi := MeshInstance3D.new() mi.mesh = mesh mi.material_override = mat mi.transform = Transform3D(b, at) parent.add_child(mi) if body != null: var hull := mesh.create_convex_shape(true, true) as ConvexPolygonShape3D var pts := PackedVector3Array() for p: Vector3 in hull.points: pts.append(b * p) hull.points = pts var cs := CollisionShape3D.new() cs.shape = hull cs.position = at body.add_child(cs) return mi