class_name DustGeometry extends RefCounted const MODEL := "res://assets/scan/dust2/dust2.glb" # Source uses 1.719419 cm per GoldSrc unit; normalize to 2.5 cm/unit. const SCALE := 0.025 / 0.0171941924 const OFFSET := Vector3(8, 4.8, 28) static func build(parent: Node3D, source: NavigationMeshSourceGeometryData3D = null) -> void: var imported := (load(MODEL) as PackedScene).instantiate() as Node3D parent.add_child(imported) for original: MeshInstance3D in imported.find_children("*", "MeshInstance3D", true, false): var pose := Transform3D(Basis.IDENTITY.scaled(Vector3.ONE * SCALE), OFFSET) * original.global_transform var mesh := MeshInstance3D.new() mesh.name = original.name mesh.mesh = original.mesh mesh.transform = pose parent.add_child(mesh) for surface in mesh.mesh.get_surface_count(): var material := mesh.mesh.surface_get_material(surface) as StandardMaterial3D var file := "res://assets/scan/dust2/" + material.resource_name + ".tres" if ResourceLoader.exists(file): mesh.set_surface_override_material(surface, load(file)) var body := StaticBody3D.new() body.name = "MapCollision_" + str(original.name) body.collision_layer = 1 body.collision_mask = 0 var collider := CollisionShape3D.new() var shape := ConcavePolygonShape3D.new() shape.backface_collision = true shape.set_faces(pose * mesh.mesh.get_faces()) collider.shape = shape body.add_child(collider) parent.add_child(body) if source != null: source.add_faces(pose * mesh.mesh.get_faces(), Transform3D.IDENTITY) imported.free()