diff --git a/src/modules/stream/buildings_data.cpp b/src/modules/stream/buildings_data.cpp index 8541cce..9fbac8e 100644 --- a/src/modules/stream/buildings_data.cpp +++ b/src/modules/stream/buildings_data.cpp @@ -91,12 +91,13 @@ void BuildingsData::build_building_aabbs() } } -void BuildingsData::update_building_transform(int index, const Transform &xform) +void BuildingsData::update_building_transform(const String &key, + const Transform &xform) { - buildings_[index].xform = xform; + get_building(key).xform = xform; } -int BuildingsData::get_closest_building(const Transform &xform) +String BuildingsData::get_closest_building(const Transform &xform) { int i; float dst = Math_INF; @@ -111,7 +112,7 @@ int BuildingsData::get_closest_building(const Transform &xform) id = i; } } - return id; + return buildings_[id].key; } void BuildingsData::cleanup() diff --git a/src/modules/stream/buildings_data.h b/src/modules/stream/buildings_data.h index eb9982a..0615a7b 100644 --- a/src/modules/stream/buildings_data.h +++ b/src/modules/stream/buildings_data.h @@ -61,10 +61,10 @@ public: private: std::vector buildings_; struct building *get_building_ptr(int index); - -public: const struct building &get_building(int index) const; struct building &get_building(int index); + +public: struct building &get_building(const String &building_key); const struct building &get_building(const String &building_key) const; struct callme { @@ -135,8 +135,9 @@ public: void undo(); void fill_door_locations(); void build_building_aabbs(); - void update_building_transform(int index, const Transform &xform); - int get_closest_building(const Transform &xform); + void update_building_transform(const String &key, + const Transform &xform); + String get_closest_building(const Transform &xform); static BuildingsData *get_singleton(); static void cleanup(); int get_building_by_key(const String &key) const; diff --git a/src/modules/stream/road_lines_data.cpp b/src/modules/stream/road_lines_data.cpp index 17d0028..bd79d27 100644 --- a/src/modules/stream/road_lines_data.cpp +++ b/src/modules/stream/road_lines_data.cpp @@ -523,9 +523,6 @@ void RoadLinesData::line_add_building(const String &line, const String &key, float curve_offset, float normal_offset, float y_rotation) { - int index = BuildingsData::get_singleton()->get_building_by_key(key); - if (index < 0) - return; struct line_building_data lb; lb.building_key = key; lb.building_key_hash = key.hash64(); @@ -534,7 +531,7 @@ void RoadLinesData::line_add_building(const String &line, const String &key, lb.y_rotation = y_rotation; lines[line].buildings.push_back(lb); // TODO: save/load - BuildingsData::get_singleton()->get_building(index).line_name = line; + BuildingsData::get_singleton()->get_building(key).line_name = line; } void RoadLinesData::assign_close_buildings(const String &line) @@ -553,21 +550,24 @@ void RoadLinesData::assign_close_buildings(const String &line) print_line("assign_close_buildings: processing: " + itos(BuildingsData::get_singleton()->get_building_count()) + " buildings"); - for (i = 0; - i < (int)BuildingsData::get_singleton()->get_building_count(); - i++) { + List bkeys; + BuildingsData::get_singleton()->get_building_keys_list(&bkeys); + List::Element *e; + for (e = bkeys.front(); e; e = e->next()) { float dst = Math_INF; float result_offset = 0.0f; float side = 0.0f; String building_key; + /* FIXME: use proper function */ + String bkey = e->get(); struct BuildingsData::building &data = - BuildingsData::get_singleton()->get_building(i); + BuildingsData::get_singleton()->get_building(bkey); // manually placed if (!data.generated) continue; // already assigned to another line const String &building_line = BuildingsData::get_singleton() - ->get_building(i) + ->get_building(bkey) .line_name; if (building_line != line && building_line != "") continue; @@ -694,64 +694,47 @@ void RoadLinesData::update_buildings_from_lines() const uint64_t &building_key_hash = lines[line].buildings[i].building_key_hash; bool found = false; - int index = -1; - for (j = 0; j < (int)bd->get_building_count(); j++) { - if (bd->get_building(j).key_hash == - building_key_hash) { - found = true; - index = j; - break; - } + int index = bd->get_building_by_key( + lines[line].buildings[i].building_key); + if (index >= 0) + found = true; + if (found) { struct BuildingsData::building &b = - bd->get_building(index); - if (found) { - Vector3 pt = get_point_by_offsets( - line, - lines[line] - .buildings[i] - .line_offset, - lines[line] - .buildings[i] - .normal_offset); - Basis basis = Basis().rotated( - Vector3(0, 1, 0), - lines[line] - .buildings[i] - .y_rotation); - b.xform.origin = pt; - b.xform.basis = basis; - Array args; - args.push_back(index); - EditorEvent::get_singleton()->event.emit( - "building_updated", args); - } else { - Vector3 pt = get_point_by_offsets( - line, - lines[line] - .buildings[i] - .line_offset, - lines[line] - .buildings[i] - .normal_offset); - Basis basis = Basis().rotated( - Vector3(0, 1, 0), - lines[line] - .buildings[i] - .y_rotation); - struct BuildingsData::building nb; - Dictionary data; - data["id"] = - lines[line].buildings[i].id; - data["xform"] = Transform(basis, pt); - BuildingsData::building::from_dict( - &nb, data); - index = bd->get_building_count(); - bd->create_building(nb); - Array args; - args.push_back(index); - EditorEvent::get_singleton()->event.emit( - "building_created", args); - } + bd->get_building(lines[line] + .buildings[i] + .building_key); + Vector3 pt = get_point_by_offsets( + line, + lines[line].buildings[i].line_offset, + lines[line].buildings[i].normal_offset); + Basis basis = Basis().rotated( + Vector3(0, 1, 0), + lines[line].buildings[i].y_rotation); + b.xform.origin = pt; + b.xform.basis = basis; + Array args; + args.push_back(index); + EditorEvent::get_singleton()->event.emit( + "building_updated", args); + } else { + Vector3 pt = get_point_by_offsets( + line, + lines[line].buildings[i].line_offset, + lines[line].buildings[i].normal_offset); + Basis basis = Basis().rotated( + Vector3(0, 1, 0), + lines[line].buildings[i].y_rotation); + struct BuildingsData::building nb; + Dictionary data; + data["id"] = lines[line].buildings[i].id; + data["xform"] = Transform(basis, pt); + BuildingsData::building::from_dict(&nb, data); + index = bd->get_building_count(); + bd->create_building(nb); + Array args; + args.push_back(index); + EditorEvent::get_singleton()->event.emit( + "building_created", args); } } e = e->next(); diff --git a/src/modules/stream/road_lines_editor.cpp b/src/modules/stream/road_lines_editor.cpp index 7b4c0d7..bde8d62 100644 --- a/src/modules/stream/road_lines_editor.cpp +++ b/src/modules/stream/road_lines_editor.cpp @@ -796,10 +796,11 @@ void RoadLinesEditor::move_cursor_to_closest_building() { print_line("move_cursor_to_closest_building"); Vector3 pt = get_cursor_position(); - int index = BuildingsData::get_singleton()->get_closest_building( - Transform(Basis(), pt)); + const String &key = + BuildingsData::get_singleton()->get_closest_building( + Transform(Basis(), pt)); const Transform &xform = - BuildingsData::get_singleton()->get_building(index).xform; + BuildingsData::get_singleton()->get_building(key).xform; set_cursor_position(xform.origin); Spatial *cursor = get_as_node(cursor_name); if (!cursor->is_visible()) diff --git a/src/modules/stream/stream.cpp b/src/modules/stream/stream.cpp index 28fc02b..86713ca 100644 --- a/src/modules/stream/stream.cpp +++ b/src/modules/stream/stream.cpp @@ -16,7 +16,24 @@ void StreamWorld::create_tilemap() { - int i; + data()->for_each_building( + [this](const String &key, void *hdata) { + int tile_x = data()->get_building(key).xform.origin.x / + tile_size; + int tile_z = data()->get_building(key).xform.origin.z / + tile_size; + std::tuple tkey = + std::make_tuple(tile_x, tile_z); + int index = data()->get_building_by_key(key); + if (tiles.find(tkey) != tiles.end()) + tiles[tkey].push_back(index); + else { + std::vector data = { index }; + tiles[tkey] = data; + } + }, + nullptr); +#if 0 for (i = 0; i < (int)data()->get_building_count(); i++) { int tile_x = data()->get_building(i).xform.origin.x / tile_size; int tile_z = data()->get_building(i).xform.origin.z / tile_size; @@ -28,6 +45,7 @@ void StreamWorld::create_tilemap() tiles[key] = data; } } +#endif print_line("Tile count: " + itos(tiles.size())); } @@ -137,7 +155,7 @@ void StreamWorld::load_tile(int tx, int ty) const std::vector &items = tiles[key]; for (i = 0; i < (int)items.size(); i++) { print_line("load item: " + itos(i) + ": " + itos(items[i]) + - ": " + data()->get_building(items[i]).id); + ": " /* + data()->get_building(items[i]).id */); load_building(items[i]); } } @@ -149,7 +167,7 @@ void StreamWorld::erase_tile(int tx, int ty) const std::vector &items = tiles[key]; for (i = 0; i < (int)items.size(); i++) { print_line("unload item: " + itos(i) + ": " + itos(items[i]) + - ": " + data()->get_building(items[i]).id); + ": " /* + data()->get_building(items[i]).id */); unload_building(items[i]); } } @@ -166,8 +184,8 @@ void StreamWorld::unload_building(int id) void StreamWorld::request_item(int type, int item) { - String id = data()->get_building(item).id; const String &bkey = data()->item_nodes_get_key(item); + String id = data()->get_building(bkey).id; if (id == "empty") return; switch (type) { @@ -238,15 +256,15 @@ void StreamWorld::run_command(const String &command, const Array &args) return; } const Transform &xform = args[0]; - int id = data()->get_closest_building(xform); + String key = data()->get_closest_building(xform); Array ret_data; ret_data.resize(5); - ret_data[0] = data()->get_building(id).xform; + ret_data[0] = data()->get_building(key).xform; ret_data[1] = xform.origin.distance_squared_to( - data()->get_building(id).xform.origin); - ret_data[2] = data()->get_building(id).key; - ret_data[3] = id; - ret_data[4] = data()->get_building(id).id; + data()->get_building(key).xform.origin); + ret_data[2] = key; + ret_data[3] = data()->get_building_by_key(key); + ret_data[4] = data()->get_building(key).id; emit_signal("command_result", command, ret_data); } else if (command == "get_building_id_for_key") { if (args.size() == 0) { @@ -254,15 +272,9 @@ void StreamWorld::run_command(const String &command, const Array &args) return; } String key = args[1]; - uint64_t khash = key.hash64(); Array ret_data; ret_data.resize(1); - int id = -1, i; - for (i = 0; i < (int)data()->get_building_count(); i++) - if (data()->get_building(i).key.hash64() == khash) { - id = i; - break; - } + int id = data()->get_building_by_key(key); ret_data[0] = id; emit_signal("command_result", command, ret_data); } else if (command == "update_building_transform") { @@ -273,8 +285,8 @@ void StreamWorld::run_command(const String &command, const Array &args) int id = args[0]; if (id < 0 || id >= (int)data()->get_building_count()) return; - data()->update_building_transform(id, args[1]); const String &key = data()->item_nodes_get_key(id); + data()->update_building_transform(key, args[1]); Node *node = data()->item_nodes_get_node(key); Spatial *bnode = Object::cast_to(node); if (bnode) @@ -306,9 +318,10 @@ void StreamWorld::run_command(const String &command, const Array &args) print_error("unknown building type: " + new_type); return; } - String old_type = data()->get_building(id).id; + String key = data()->item_nodes_get_key(id); + String old_type = data()->get_building(key).id; unload_building(id); - data()->get_building(id).id = new_type; + data()->get_building(key).id = new_type; load_building(id); update_items(); print_line("changed building: " + itos(id) + @@ -341,10 +354,18 @@ void StreamWorld::run_command(const String &command, const Array &args) erased_indices.reserve(data()->get_building_count()); String prefix = args[0]; int i; - for (i = 0; i < (int)data()->get_building_count(); i++) { - if (data()->get_building(i).id.begins_with(prefix)) - erased_indices.push_back(i); - } + data()->for_each_building( + [&erased_indices, prefix](const String &key, + void *data) { + if (data()->get_building(key).id.begins_with( + prefix)) { + int index = data()->get_building_by_key( + key); + assert(index >= 0); + erased_indices.push_back(index); + } + }, + nullptr); print_line("delete buildings: " + itos(erased_indices.size()) + " prefix: " + prefix); for (i = erased_indices.size() - 1; i >= 0; i--) { @@ -465,10 +486,15 @@ void StreamWorld::remove_generated_stuff() std::vector erased_indices; erased_indices.reserve(data()->get_building_count()); int i; - for (i = 0; i < data()->get_building_count(); i++) { - if (data()->get_building(i).generated) - erased_indices.push_back(i); - } + data()->for_each_building( + [&erased_indices](const String &key, void *mdata) { + if (data()->get_building(key).generated) { + int index = data()->get_building_by_key(key); + assert(index >= 0); + erased_indices.push_back(index); + } + }, + nullptr); for (i = erased_indices.size() - 1; i >= 0; i--) { int index = erased_indices[i]; unload_building(index);