diff --git a/Debug.gd b/Debug.gd new file mode 100644 index 0000000..443ed0c --- /dev/null +++ b/Debug.gd @@ -0,0 +1,7 @@ +extends Control + + +func _process(delta): + $Label.text = "" + $Label.text += "FPS: %d\n" % Engine.get_frames_per_second() + $Label.text += "BuildingPlacer.is_buildable: %s" % [$"../Tools/BuildingTool".is_buildable] diff --git a/Test_RoadSystem.tscn b/Test_RoadSystem.tscn index e56e8c5..f69e0f9 100644 --- a/Test_RoadSystem.tscn +++ b/Test_RoadSystem.tscn @@ -1,7 +1,8 @@ -[gd_scene load_steps=20 format=2] +[gd_scene load_steps=23 format=2] [ext_resource path="res://addons/zylann.hterrain/hterrain.gd" type="Script" id=1] [ext_resource path="res://addons/zylann.hterrain/hterrain_texture_set.gd" type="Script" id=2] +[ext_resource path="res://Debug.gd" type="Script" id=3] [ext_resource path="res://addons/sairam.quadtree/QuadTreeNode.gd" type="Script" id=4] [ext_resource path="res://_terrain_data/data.hterrain" type="Resource" id=5] [ext_resource path="res://Road.tres" type="Material" id=6] @@ -14,6 +15,7 @@ [ext_resource path="res://roads_system/RoadUpgrade.gd" type="Script" id=13] [ext_resource path="res://building_system/building_placer.gd" type="Script" id=14] [ext_resource path="res://FullScreen.gd" type="Script" id=15] +[ext_resource path="res://building_system/building_remover.gd" type="Script" id=16] [sub_resource type="Resource" id=1] script = ExtResource( 2 ) @@ -30,6 +32,10 @@ flags_unshaded = true vertex_color_use_as_albedo = true albedo_color = Color( 1, 0, 0, 1 ) +[sub_resource type="SpatialMaterial" id=6] +flags_unshaded = true +vertex_color_use_as_albedo = true + [sub_resource type="SpatialMaterial" id=4] flags_transparent = true albedo_color = Color( 0, 1, 1, 0.501961 ) @@ -58,6 +64,7 @@ shader_params/u_triplanar = false shader_params/u_tile_reduction = Plane( 0, 0, 0, 0 ) [node name="RoadNetwork" type="Spatial" parent="HTerrain"] +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 128, 0, 128 ) script = ExtResource( 7 ) use_astar = true immediate_geo_node = NodePath("ImmediateGeometry") @@ -67,21 +74,21 @@ quad_tree_edge_bezier_node_path = NodePath("QuadTreeNodeEdgeBezier") auto_clear_when_draw = false [node name="GlobalRoadSystemDrawer" type="MeshInstance" parent="HTerrain/RoadNetwork"] -transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.01, 0 ) +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -128, 0.01, -128 ) material_override = ExtResource( 6 ) script = ExtResource( 11 ) immediate_geometry_node_path = NodePath("../RoadSystemGeometry") [node name="ImmediateGeometry" type="ImmediateGeometry" parent="HTerrain/RoadNetwork"] -transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.01, 0 ) +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -128, 0.01, -128 ) material_override = SubResource( 2 ) [node name="RoadSystemGeometry" type="ImmediateGeometry" parent="HTerrain/RoadNetwork"] -transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.3, 0 ) +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -128, 0.3, -128 ) material_override = SubResource( 2 ) [node name="QuadTreeNode" type="Spatial" parent="HTerrain/RoadNetwork"] -transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 128, 0, 128 ) +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -128, 0, -128 ) script = ExtResource( 4 ) extents = Vector3( 256, 5.464, 256 ) capacity = 6 @@ -92,7 +99,7 @@ immediate_geo_node_path = NodePath("QuadTreeGeometry") material_override = SubResource( 3 ) [node name="QuadTreeNodeEdges" type="Spatial" parent="HTerrain/RoadNetwork"] -transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 128, 0, 128 ) +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -128, 0, -128 ) script = ExtResource( 4 ) extents = Vector3( 256, 5.464, 256 ) capacity = 6 @@ -103,7 +110,7 @@ immediate_geo_node_path = NodePath("QuadTreeGeometry") material_override = SubResource( 3 ) [node name="QuadTreeNodeEdgeBezier" type="Spatial" parent="HTerrain/RoadNetwork"] -transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 128, 0, 128 ) +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -128, 0, -128 ) script = ExtResource( 4 ) extents = Vector3( 256, 5.464, 256 ) capacity = 6 @@ -113,19 +120,20 @@ immediate_geo_node_path = NodePath("QuadTreeGeometry") [node name="QuadTreeGeometry" type="ImmediateGeometry" parent="HTerrain/RoadNetwork/QuadTreeNodeEdgeBezier"] [node name="BuildingNetwork" type="Spatial" parent="HTerrain"] -transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.02, 0 ) +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 128, 0.02, 128 ) [node name="Buildings" type="Spatial" parent="HTerrain/BuildingNetwork"] -[node name="QuadTreeBuilding" type="Spatial" parent="HTerrain/BuildingNetwork/Buildings"] -transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 128, 0, 128 ) +[node name="QuadTreeBuilding" type="Spatial" parent="HTerrain/BuildingNetwork"] +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -128, 0, -128 ) script = ExtResource( 4 ) extents = Vector3( 256, 5.464, 256 ) capacity = 6 max_levels = 12 immediate_geo_node_path = NodePath("QuadTreeGeometry") -[node name="QuadTreeGeometry" type="ImmediateGeometry" parent="HTerrain/BuildingNetwork/Buildings/QuadTreeBuilding"] +[node name="QuadTreeGeometry" type="ImmediateGeometry" parent="HTerrain/BuildingNetwork/QuadTreeBuilding"] +material_override = SubResource( 6 ) [node name="Camera" parent="." instance=ExtResource( 8 )] transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 20, 3, 20 ) @@ -210,14 +218,30 @@ transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.1, 0 ) script = ExtResource( 14 ) road_network_path = NodePath("../../HTerrain/RoadNetwork") buildings_path = NodePath("../../HTerrain/BuildingNetwork/Buildings") -quad_tree_path = NodePath("../../HTerrain/BuildingNetwork/Buildings/QuadTreeBuilding") +quad_tree_path = NodePath("../../HTerrain/BuildingNetwork/QuadTreeBuilding") [node name="ImmediateGeometry" type="ImmediateGeometry" parent="Tools/BuildingTool"] +[node name="BuildingRemover" type="Spatial" parent="Tools"] +script = ExtResource( 16 ) + [node name="DirectionalLight" type="DirectionalLight" parent="."] transform = Transform( 1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 0, 0 ) shadow_enabled = true +[node name="Control" type="Control" parent="."] +anchor_right = 1.0 +anchor_bottom = 1.0 +mouse_filter = 1 +script = ExtResource( 3 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Label" type="Label" parent="Control"] +margin_right = 40.0 +margin_bottom = 14.0 + [connection signal="graph_changed" from="HTerrain/RoadNetwork" to="HTerrain/RoadNetwork/GlobalRoadSystemDrawer" method="_on_RoadNetwork_graph_changed"] [connection signal="graph_changed" from="Tools/RoadTool/RoadNetwork" to="Tools/RoadTool/RoadNetwork/RoadRenderer" method="_on_RoadNetwork_graph_changed"] [connection signal="graph_changed" from="Tools/RoadRemover/RoadNetwork" to="Tools/RoadRemover/RoadNetwork/RoadRenderer" method="_on_RoadNetwork_graph_changed"] diff --git a/building_system/buildable.tres b/building_system/buildable.tres new file mode 100644 index 0000000..a055d17 --- /dev/null +++ b/building_system/buildable.tres @@ -0,0 +1,5 @@ +[gd_resource type="SpatialMaterial" format=2] + +[resource] +flags_transparent = true +albedo_color = Color( 0, 1, 1, 0.247059 ) diff --git a/building_system/building_instance.gd b/building_system/building_instance.gd index dfa734c..56dd63f 100644 --- a/building_system/building_instance.gd +++ b/building_system/building_instance.gd @@ -4,12 +4,22 @@ class_name BuildingInstance var building var id +var _mesh_child_index_array = [] +var _collision_child_index_array = [] + func get_aabb(): var aabb: AABB - for child in get_children(): + for child in get_child(0).get_children(): if child is MeshInstance: if !aabb: aabb = child.get_transformed_aabb() else: - aabb.merge(child.get_transformed_aabb()) + aabb = aabb.merge(child.get_transformed_aabb()) return aabb + +func _ready(): + for child in get_child(0).get_children(): + if child is MeshInstance: + _mesh_child_index_array.append(child.get_index()) + elif child is CollisionShape: + _collision_child_index_array.append(child.get_index()) diff --git a/building_system/building_network.gd b/building_system/building_network.gd new file mode 100644 index 0000000..bf7cb4b --- /dev/null +++ b/building_system/building_network.gd @@ -0,0 +1,28 @@ +extends Node + + +export(NodePath) var quadtree_pth +onready var quad_tree = get_node(quadtree_pth) as QuadTreeNode + +func get_closest_building(to_position: Vector3, distance: int = 0.5): + pass + +func add_building(transform: Transform, building: BuildingInstance): + pass + +func remove_building(building: BuildingInstance): + pass + +func _get_aabb_for_query(position: Vector3, radius: int = 10, height: int = 20) -> AABB: + var mesh_inst = MeshInstance.new() + var cylinder = CylinderMesh.new() + cylinder.top_radius = radius + cylinder.bottom_radius = radius + cylinder.height = height + mesh_inst.mesh = cylinder + var aabb = mesh_inst.get_aabb() + aabb.position.x += position.x + aabb.position.y += position.y + aabb.position.z += position.z + mesh_inst.free() + return aabb diff --git a/building_system/building_placer.gd b/building_system/building_placer.gd index bab57b4..b0acf44 100644 --- a/building_system/building_placer.gd +++ b/building_system/building_placer.gd @@ -6,7 +6,9 @@ onready var road_network = get_node(road_network_path) as RoadNetwork export(NodePath) var buildings_path onready var buildings = get_node(buildings_path) export(NodePath) var quad_tree_path -onready var quad_tree = get_node(quad_tree_path) +onready var quad_tree = get_node(quad_tree_path) as QuadTreeNode + +var is_buildable = false var ghost_instance: Spatial var enabled @@ -31,24 +33,41 @@ func _input(event): buildings.remove_child(ghost_instance) ghost_instance.queue_free() ghost_instance = current_building.instance() + ghost_instance.scale += Vector3(0.01, 0.01, 0.01) buildings.add_child(ghost_instance) if event is InputEventMouseMotion: if current_building: var building_point = _cast_ray_to(event.position) building_point = building_point.snapped(Vector3(0.25, 0, 0.25)) + var aabb = get_aabb() + aabb.position.y += -99 + aabb.size.y += 99 + is_buildable = quad_tree.query(aabb) +# $ImmediateGeometry.clear() +# DrawingUtils.draw_box_with_aabb($ImmediateGeometry, get_aabb()) + if !is_buildable: + # material overlay + ghost_instance.get_child(0).get_child(0).material_overlay = preload("res://building_system/buildable.tres") + else: + ghost_instance.get_child(0).get_child(0).material_overlay = preload("res://building_system/non_buildable.tres") +# test_and_set_material_overlay(preload("res://building_system/non_buildable.tres")) + +# quad_tree.draw() if is_vec_nan(building_point): return # print(building_point) - var segment = road_network.get_closest_segment(building_point) + var segment = road_network.get_closest_segment(building_point, 1) if segment: var closest_point = segment.project_point(building_point) var direction = (closest_point - building_point).normalized() var point: Vector3 = closest_point + direction * (-segment.road_network_info.width/2 + -1) + var building_transform = Transform.IDENTITY point.y = 0.02 + var b_scale = ghost_instance.global_transform.basis.get_scale() building_transform.origin = point var a = closest_point - point @@ -58,7 +77,7 @@ func _input(event): var angle = angle_b - angle_a building_transform.basis = building_transform.basis.rotated(Vector3.UP, angle) - + building_transform.basis = building_transform.basis.scaled(b_scale) ghost_instance.global_transform = building_transform else: @@ -82,7 +101,7 @@ func _input(event): var building_transform = Transform.IDENTITY point.y = 0.02 building_transform.origin = point - + var a = closest_point - point var b = current_building.door_face_direction var angle_a = atan2(a.z, a.x) @@ -92,10 +111,41 @@ func _input(event): building_transform.basis = building_transform.basis.rotated(Vector3.UP, angle) var new_building = current_building.instance() buildings.add_child(new_building) + + var b_scale = new_building.global_transform.basis.get_scale() + building_transform.basis = building_transform.basis.scaled(b_scale) + new_building.global_transform = building_transform + quad_tree.add_body(new_building, new_building.get_aabb()) - var expanded_aabb = new_building.get_aabb() - DrawingUtils.draw_box_with_aabb($"ImmediateGeometry", expanded_aabb) +# var expanded_aabb = new_building.get_aabb() +# DrawingUtils.draw_box_with_aabb($"ImmediateGeometry", expanded_aabb) + +func get_aabb(): + + return ghost_instance.get_aabb() + +func test_and_set_material(p_material): + var test_mesh = ghost_instance.get_child(0).get_child(ghost_instance._mesh_child_index_array[randi() % ghost_instance._mesh_child_index_array.size()]).mesh as Mesh + var test_material = test_mesh.surface_get_material(randi() % test_mesh.get_surface_count()) + if test_material == p_material: + for index in current_building._mesh_child_index_array: + var child = ghost_instance.get_child(0).get_child(index) as MeshInstance + for material_index in range(child.get_surface_material_count()): + var material = child.mesh.surface_get_material(material_index) + material = p_material + child.mesh.surface_set_material(material_index, material) + +func test_and_set_material_overlay(p_material): + var test_mesh = ghost_instance.get_child(0).get_child(ghost_instance._mesh_child_index_array[randi() % ghost_instance._mesh_child_index_array.size()]).mesh as Mesh + var test_material = test_mesh.surface_get_material(randi() % test_mesh.get_surface_count()) + if test_material == p_material: + for index in current_building._mesh_child_index_array: + var child = ghost_instance.get_child(0).get_child(index) as MeshInstance + for material_index in range(child.get_surface_material_count()): + var material = child.mesh.surface_get_material(material_index) + material.next_pass = p_material + child.mesh.surface_set_material(material_index, material) #func _process(delta): # print("------------------------------------------") diff --git a/building_system/building_remover.gd b/building_system/building_remover.gd new file mode 100644 index 0000000..2f57a85 --- /dev/null +++ b/building_system/building_remover.gd @@ -0,0 +1,12 @@ +extends Spatial + + +var enabled +func _input(event): + if event is InputEventKey: + if event.scancode == KEY_Y and event.pressed: + enabled = !enabled + + if event is InputEventMouseMotion: + pass + diff --git a/building_system/non_buildable.tres b/building_system/non_buildable.tres new file mode 100644 index 0000000..ee4596a --- /dev/null +++ b/building_system/non_buildable.tres @@ -0,0 +1,5 @@ +[gd_resource type="SpatialMaterial" format=2] + +[resource] +flags_transparent = true +albedo_color = Color( 1, 0, 0, 0.247059 ) diff --git a/project.godot b/project.godot index b6290a0..da3d3ec 100644 --- a/project.godot +++ b/project.godot @@ -85,52 +85,52 @@ left_click={ } camera_forward={ "deadzone": 0.5, -"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":87,"unicode":0,"echo":false,"script":null) +"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":87,"physical_scancode":0,"unicode":0,"echo":false,"script":null) ] } camera_back={ "deadzone": 0.5, -"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":83,"unicode":0,"echo":false,"script":null) +"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":83,"physical_scancode":0,"unicode":0,"echo":false,"script":null) ] } camera_left={ "deadzone": 0.5, -"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":65,"unicode":0,"echo":false,"script":null) +"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":65,"physical_scancode":0,"unicode":0,"echo":false,"script":null) ] } camera_right={ "deadzone": 0.5, -"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":68,"unicode":0,"echo":false,"script":null) +"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":68,"physical_scancode":0,"unicode":0,"echo":false,"script":null) ] } camera_rotate_x={ "deadzone": 0.5, -"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":81,"unicode":0,"echo":false,"script":null) +"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":81,"physical_scancode":0,"unicode":0,"echo":false,"script":null) ] } camera_rotate_-x={ "deadzone": 0.5, -"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":69,"unicode":0,"echo":false,"script":null) +"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":69,"physical_scancode":0,"unicode":0,"echo":false,"script":null) ] } camera_tilt_y={ "deadzone": 0.5, -"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":82,"unicode":0,"echo":false,"script":null) +"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":82,"physical_scancode":0,"unicode":0,"echo":false,"script":null) ] } camera_tilt_-y={ "deadzone": 0.5, -"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":70,"unicode":0,"echo":false,"script":null) +"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":70,"physical_scancode":0,"unicode":0,"echo":false,"script":null) ] } camera_zoom_in={ "deadzone": 0.5, -"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":90,"unicode":0,"echo":false,"script":null) +"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":90,"physical_scancode":0,"unicode":0,"echo":false,"script":null) ] } camera_zoom_out={ "deadzone": 0.5, -"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":88,"unicode":0,"echo":false,"script":null) +"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":88,"physical_scancode":0,"unicode":0,"echo":false,"script":null) ] } diff --git a/roads_system/RoadNetwork.gd b/roads_system/RoadNetwork.gd index b1754ba..4e45e07 100644 --- a/roads_system/RoadNetwork.gd +++ b/roads_system/RoadNetwork.gd @@ -665,7 +665,7 @@ func upgrade_connection(start_intersection: RoadIntersection, end_intersection: func _generate_id(road_intersection: Vector3): var _position: Vector3 = road_intersection # _position -= Vector3(-4096, -4096, -4096) - return int((_position.x + _position.y + _position.z)) + return int((_position.x + _position.y + _position.z)+4098) func subdivide_intersections(start_intersection: RoadIntersection, end_intersection: RoadIntersection, road_net_info: RoadNetworkInfo): var segment = get_connection(start_intersection, end_intersection) @@ -806,6 +806,7 @@ func _get_aabb_for_query(position: Vector3, radius: int = 10, height: int = 20) aabb.position.x += position.x aabb.position.y += position.y aabb.position.z += position.z + mesh_inst.free() return aabb #func _ready():