diff --git a/godot/main/editor.tscn b/godot/main/editor.tscn index 35ac36e..f3671c1 100644 --- a/godot/main/editor.tscn +++ b/godot/main/editor.tscn @@ -262,7 +262,7 @@ margin_right = 167.0 margin_bottom = 20.0 focus_mode = 2 text = "Line" -items = [ "Create", null, 0, false, false, 21, 0, null, "", false, "Delete", null, 0, false, false, 22, 0, null, "", false, "", null, 0, false, false, -1, 0, null, "", true, "Remove Generated", null, 0, false, false, 30, 0, null, "", false, "Edit Line Metadata", null, 0, false, false, 23, 0, null, "", false ] +items = [ "Create", null, 0, false, false, 21, 0, null, "", false, "Delete", null, 0, false, false, 22, 0, null, "", false, "", null, 0, false, false, -1, 0, null, "", true, "Remove Generated", null, 0, false, false, 30, 0, null, "", false, "Place Generated Objects", null, 0, false, false, 31, 0, null, "", false, "Edit Line Metadata", null, 0, false, false, 23, 0, null, "", false ] [node name="HSeparator3" type="HSeparator" parent="VBoxContainer/v_road_lines/road_lines_base/VBoxContainer"] margin_top = 24.0 diff --git a/src/modules/stream/road_lines_editor.cpp b/src/modules/stream/road_lines_editor.cpp index 95bfb39..90fc235 100644 --- a/src/modules/stream/road_lines_editor.cpp +++ b/src/modules/stream/road_lines_editor.cpp @@ -327,6 +327,9 @@ protected: case 30: editor->remove_generated_stuff(); break; + case 31: + editor->place_generated_objects(); + break; case 51: editor->set_point_to_cursor(); break; @@ -917,6 +920,92 @@ void RoadLinesEditor::load_data() e = e->next(); } } +void RoadLinesEditor::place_generated_objects() +{ + place_zebras(); +} +void RoadLinesEditor::place_zebras() +{ + editor->remove_buildings_by_prefix("zebra"); + /* +func place_zebras(): + var road_nodes = SceneComps.get_component("road_nodes2") + var next_index = 0 + var positions = [] + var d = buildings.keys().duplicate() + for k in d: + if buildings[k].id == "zebra": + buildings.erase(k) + for k in buildings.keys(): + if buildings[k].index >= next_index: + next_index = buildings[k].index + 1 + + for k in range(road_nodes.roads_data.nodes.size()): + if !road_nodes.roads_data.edges.has(str(k)): + continue + var e = road_nodes.roads_data.edges[str(k)] + if e.neighbors.size() <= 2: + continue + var pos = str2var(road_nodes.roads_data.nodes[k]) + for n in e.neighbors: + var pne = str2var(road_nodes.roads_data.nodes[n]) + if pos.distance_squared_to(pne) < 50 * 50: + continue +# var ne = road_nodes.roads_data.edges[str(n)] +# var pne = str2var(ne) +# var pt = pos.linear_interpolate(pne, 0.5) + var dir: Vector3 = (pne - pos).normalized() + var nml = dir.rotated(Vector3.UP, PI / 2.0) + var points = [] + var bad = false + for x in range(2): + points.push_back(pos + dir * 30.0 + nml * 4.0 * x) + for x in range(2): + points.push_back(pos + dir * 30.0 - nml * 4.0 * (x + 1)) + for xp in positions: + for lp in points: + if xp.distance_squared_to(lp) < 30 * 30: + bad = true + break + if bad: + points.clear() + for pt in points: + var xform: Transform = Transform(Basis(), pt) + xform = xform.looking_at(pt + nml * 30, Vector3.UP) + positions.push_back(xform.origin) + var key = var2str(xform) + assert(!buildings.has(key)) + buildings[key] = { + "id": "zebra", + "index": next_index, + "residents": [] + } + next_index += 1 + for b in spawned_buildings.keys(): + var sp = spawned_buildings[b] + building_pool.unparent_building(sp[0], sp[1]) + spawned_buildings.clear() + +# for k in road_nodes.roads_data.edges.keys(): +# if road_nodes.roads_data.edges[k].neighbors.size() <= 2: +# continue +# for wk in road_nodes.current_wedges.keys(): +# var wdata = road_nodes.current_wedges[wk] +# var sz = wdata.size() +# if sz <= 2: +# continue +# for w in wdata: +# var pos = w[4].linear_interpolate(w[3], 0.5) +# var xform: Transform = Transform(Basis(), pos) +# xform = xform.looking_at(w[1], Vector3.UP) +# var key = var2str(xform) +# buildings[key] = { +# "id": "zebra", +# "index": next_index, +# "residents": [] +# } + */ +} void RoadLinesEditor::save_data() { int i; diff --git a/src/modules/stream/road_lines_editor.h b/src/modules/stream/road_lines_editor.h index 25ac4ef..7bb7bdd 100644 --- a/src/modules/stream/road_lines_editor.h +++ b/src/modules/stream/road_lines_editor.h @@ -43,10 +43,12 @@ public: void update_current_line_metadata(const String &text); String get_current_line_metadata() const; void remove_generated_stuff(); + void place_generated_objects(); protected: void activate(); void deactivate(); void load_data(); + void place_zebras(); }; #endif \ No newline at end of file diff --git a/src/modules/stream/stream.cpp b/src/modules/stream/stream.cpp index 0805436..4615f24 100644 --- a/src/modules/stream/stream.cpp +++ b/src/modules/stream/stream.cpp @@ -521,13 +521,36 @@ void StreamWorld::run_command(const String &command, const Array &args) print_line("changed building: " + itos(id) + " from: " + old_type + " to: " + new_type); } else if (command == "remove_building") { - /* TODO: implement */ if (args.size() == 0) { print_error("bad command: not enough args: " + command); return; } int id = args[0]; remove_building(id); + } else if (command == "remove_buildings_by_prefix") { + if (args.size() == 0) { + print_error("bad command: not enough args: " + command); + return; + } + std::vector erased_indices; + erased_indices.reserve(buildings.size()); + String prefix = args[0]; + int i, j; + for (i = 0; i < (int)buildings.size(); i++) { + if (buildings[i].id.begins_with(prefix)) + erased_indices.push_back(i); + } + print_line("delete buildings: " + itos(erased_indices.size()) + + " prefix: " + prefix); + for (i = erased_indices.size() - 1; i >= 0; i--) { + int index = erased_indices[i]; + unload_building(index); + buildings.erase(buildings.begin() + index); + for (j = index; j < (int)buildings.size(); j++) + item_nodes[j] = item_nodes[j + 1]; + item_nodes.erase(buildings.size()); + } + update_items(); } else if (command == "remove_generated_stuff") { remove_generated_stuff(); update_items(); diff --git a/src/modules/stream/world_editor.cpp b/src/modules/stream/world_editor.cpp index f12356a..a425b07 100644 --- a/src/modules/stream/world_editor.cpp +++ b/src/modules/stream/world_editor.cpp @@ -443,6 +443,13 @@ void WorldEditor::delete_building_handler() stream_world->run_command("get_closest_building", args2); } +void WorldEditor::remove_buildings_by_prefix(const String &prefix) +{ + Array args; + args.push_back(prefix); + stream_world->run_command("remove_buildings_by_prefix", args); +} + void WorldEditor::_bind_methods() { ClassDB::bind_method(D_METHOD("editor_command", "command", "args"), diff --git a/src/modules/stream/world_editor.h b/src/modules/stream/world_editor.h index e5c5a3c..60668bb 100644 --- a/src/modules/stream/world_editor.h +++ b/src/modules/stream/world_editor.h @@ -44,5 +44,6 @@ public: int get_selected_building() const; Transform get_selected_building_xform() const; void select_building(const Transform &xform, int id, const String &mid); + void remove_buildings_by_prefix(const String &prefix); }; #endif