diff --git a/src/modules/stream/road_lines_data.cpp b/src/modules/stream/road_lines_data.cpp index e5fa95d..8b5c8c6 100644 --- a/src/modules/stream/road_lines_data.cpp +++ b/src/modules/stream/road_lines_data.cpp @@ -38,10 +38,97 @@ public: { return lines_[key]; } - inline struct RoadLinesData::road_line &operator[](const String &key) + inline void set_line(const String &key, + const struct RoadLinesData::road_line &line) { - return lines_[key]; + lines_[key] = line; } + inline void insert_line_point(const String &key, int index, + const Transform &xform) + { + lines_[key].points.insert(lines_[key].points.begin() + index, + xform); + } + inline void erase_line_point(const String &key, int index) + { + lines_[key].points.erase(lines_[key].points.begin() + index); + } + inline void set_line_point_position(const String &key, int index, + const Vector3 &position) + { + lines_[key].points[index].origin = position; + } + inline void clear_all_line_indices() + { + List keys; + get_key_list(&keys); + List::Element *e = keys.front(); + while (e) { + String rkey = e->get(); + clear_line_indices(rkey); + e = e->next(); + } + } + inline void clear_line_indices(const String &key) + { + lines_[key].indices.clear(); + } + inline int get_line_points_count(const String &key) const + { + return lines_[key].points.size(); + } + inline const Vector3 &get_line_point_position(const String &key, + int index) + { + return lines_[key].points[index].origin; + } + inline void add_line_index(const String &key, int id) + { + lines_[key].indices.push_back(id); + } + inline void insert_line_index(const String &key, int index, int id) + { + lines_[key].indices.insert(lines_[key].indices.begin() + index, + id); + } + void update_line_segments(const String &key) + { + int i; + lines_[key].segments.clear(); + lines_[key].segments.resize(get_line_points_count(key) - 1); + float offset = 0.0f; + for (i = 0; i < (int)get_line_points_count(key) - 1; i++) { + struct RoadLinesData::line_segment segment; + segment.p1 = get_line_point_position(key, i); + segment.p2 = get_line_point_position(key, i + 1); + segment.length = segment.p1.distance_to(segment.p2); + segment.dir = (segment.p2 - segment.p1).normalized(); + Vector3 side = segment.dir.cross(Vector3(0, 1, 0)); + side.y = 0; + segment.tangent = side.normalized(); + segment.offset = offset; + lines_[key].segments[i] = segment; + offset += segment.length; + } + } + void line_add_building(const String &key, const String &bkey, + float curve_offset, float normal_offset, + float y_rotation, float y_offset) + { + struct RoadLinesData::line_building_data lb; + lb.building_key = bkey; + lb.building_key_hash = bkey.hash64(); + lb.line_offset = curve_offset; + lb.normal_offset = normal_offset; + lb.y_rotation = y_rotation; + lb.y_offset = y_offset; + lines_[key].buildings.push_back(lb); + } + void set_line_metadata(const String &key, const Dictionary &metadata) + { + lines_[key].metadata = metadata; + } + inline bool has(const String &key) { return lines_.has(key); @@ -75,22 +162,45 @@ RoadLinesData::get_line(const String &key) const { return ::lines[key]; } -struct RoadLinesData::road_line &RoadLinesData::get_line(const String &key) -{ - return ::lines[key]; -} const RoadLinesData::road_line &RoadLinesData::lines(const String &key) const { return ::lines[key]; } -RoadLinesData::road_line &RoadLinesData::lines(const String &key) +void RoadLinesData::set_line(const String &key, const road_line &line) { - return ::lines[key]; + ::lines.set_line(key, line); } bool RoadLinesData::has_line(const String &key) { return ::lines.has(key); } +void RoadLinesData::insert_line_point(const String &key, int index, + const Transform &xform) +{ + ::lines.insert_line_point(key, index, xform); +} +void RoadLinesData::erase_line_point(const String &key, int index) +{ + ::lines.erase_line_point(key, index); +} +void RoadLinesData::set_line_point_position(const String &key, int index, + const Vector3 &position) +{ + ::lines.set_line_point_position(key, index, position); +} +void RoadLinesData::clear_all_line_indices() +{ + ::lines.clear_all_line_indices(); +} +void RoadLinesData::clear_line_indices(const String &key) +{ + ::lines.clear_line_indices(key); +} +void RoadLinesData::set_line_metadata(const String &key, + const Dictionary &metadata) +{ + ::lines.set_line_metadata(key, metadata); +} RoadLinesData *RoadLinesData::get_singleton() { if (!singleton) @@ -190,7 +300,7 @@ void RoadLinesData::load_data() } // TODO: wtf is flags? rline.lanes = lanes; - lines(key) = rline; + set_line(key, rline); e = e->next(); } } @@ -256,15 +366,15 @@ uint32_t RoadLinesData::road_lines_hash(const Vector3 &v) return x ^ (y * 100) ^ (z * 10000); } void RoadLinesData::road_lines_curve_index( - struct RoadLinesData::road_line &rline, + const String &key, std::unordered_map > &road_lines_nodes_hash, std::vector &road_lines_nodes) { int i, j; - rline.indices.clear(); - for (i = 0; i < (int)rline.points.size(); i++) { - Vector3 pt = rline.points[i].origin; + ::lines.clear_line_indices(key); + for (i = 0; i < (int)::lines.get_line_points_count(key); i++) { + Vector3 pt = ::lines.get_line_point_position(key, i); int pt_hash = road_lines_hash(pt); if (road_lines_nodes_hash.find(pt_hash) != road_lines_nodes_hash.end()) { @@ -292,7 +402,7 @@ void RoadLinesData::road_lines_curve_index( road_lines_nodes.begin(), road_lines_nodes.end(), pt); assert(it != road_lines_nodes.end()); int index = it - road_lines_nodes.begin(); - rline.indices.push_back(index); + ::lines.add_line_index(key, index); } } void RoadLinesData::index_lines( @@ -305,15 +415,13 @@ void RoadLinesData::index_lines( List::Element *e = keys.front(); while (e) { String rkey = e->get(); - struct RoadLinesData::road_line &pt = ::lines[rkey]; - pt.indices.clear(); + clear_line_indices(rkey); e = e->next(); } e = keys.front(); while (e) { String rkey = e->get(); - struct RoadLinesData::road_line &pt = ::lines[rkey]; - road_lines_curve_index(pt, road_lines_nodes_hash, + road_lines_curve_index(rkey, road_lines_nodes_hash, road_lines_nodes); e = e->next(); } @@ -378,10 +486,8 @@ void RoadLinesData::insert_close_points(std::vector &road_lines_nodes, distance_squared) { /* split segment and replace road point with a point on segment */ - ::lines[rkey].indices.insert( - ::lines[rkey].indices.begin() + - idx, - idx3); + ::lines.insert_line_index(rkey, idx, + idx3); road_lines_nodes[idx3] = closest; } } @@ -514,15 +620,21 @@ void RoadLinesData::update_road_lines_nodes( assert(std::find(::lines[r].indices.begin(), ::lines[r].indices.end(), nidx) == ::lines[r].indices.end()); + ::lines.insert_line_index(k, i + 1, nidx); + ::lines.insert_line_index(r, j + 1, nidx); +#if 0 +// FIXME: WTF??? ::lines[k].indices.insert( ::lines[k].indices.begin() + i + 1, nidx); ::lines[r].indices.insert( ::lines[k].indices.begin() + j + 1, nidx); +#endif } } } void RoadLinesData::dump_road_lines(const std::vector &road_lines_nodes) { +#if 0 int i; List keys; get_road_lines_key_list(&keys); @@ -540,6 +652,7 @@ void RoadLinesData::dump_road_lines(const std::vector &road_lines_nodes } e = e->next(); } +#endif } ImmediateGeometry *RoadLinesData::get_debug_node() { @@ -582,36 +695,15 @@ int RoadLinesData::get_debug_flags() const void RoadLinesData::update_line_segments(const String &line) { - int i; - ::lines[line].segments.clear(); - ::lines[line].segments.resize(::lines[line].points.size() - 1); - float offset = 0.0f; - for (i = 0; i < (int)::lines[line].points.size() - 1; i++) { - struct line_segment segment; - segment.p1 = ::lines[line].points[i].origin; - segment.p2 = ::lines[line].points[i + 1].origin; - segment.length = segment.p1.distance_to(segment.p2); - segment.dir = (segment.p2 - segment.p1).normalized(); - Vector3 side = segment.dir.cross(Vector3(0, 1, 0)); - side.y = 0; - segment.tangent = side.normalized(); - segment.offset = offset; - ::lines[line].segments[i] = segment; - offset += segment.length; - } + ::lines.update_line_segments(line); } void RoadLinesData::line_add_building(const String &line, const String &key, float curve_offset, float normal_offset, - float y_rotation) + float y_rotation, float y_offset) { - struct line_building_data lb; - lb.building_key = key; - lb.building_key_hash = key.hash64(); - lb.line_offset = curve_offset; - lb.normal_offset = normal_offset; - lb.y_rotation = y_rotation; - ::lines[line].buildings.push_back(lb); + ::lines.line_add_building(line, key, curve_offset, normal_offset, + y_rotation, y_offset); // TODO: save/load BuildingsData::get_singleton()->get_building(key).line_name = line; } @@ -639,6 +731,7 @@ void RoadLinesData::assign_close_buildings(const String &line) float dst = Math_INF; float result_offset = 0.0f; float side = 0.0f; + float yoff = 0.0f; String building_key; /* FIXME: use proper function */ String bkey = e->get(); @@ -700,9 +793,8 @@ void RoadLinesData::assign_close_buildings(const String &line) assert(wdst >= 0); result_offset = ::lines[line].segments[segment_index].offset + wdst; - side = (p - p1).dot(::lines[line].segments[j].tangent); - assert(result_offset >= 0); + side = (p - p1).dot(::lines[line].segments[j].tangent); print_line("key: " + building_key + " dst: " + String::num(dst)); @@ -715,9 +807,11 @@ void RoadLinesData::assign_close_buildings(const String &line) data.xform.basis.xform(reference).normalized(); float angle = reference.signed_angle_to( rotated, Vector3(0, 1, 0)); + yoff = (p - p1).dot(Vector3(0, 1, 0)); + // yoff is relative to p1.y line_add_building(line, building_key, result_offset, - side, angle); + side, angle, yoff); } } } @@ -749,7 +843,7 @@ Vector3 RoadLinesData::get_point_by_offsets(const String &line, float n_offset = dir_offset; int selected_segment = 0; for (i = 0; i < (int)::lines[line].segments.size(); i++) { - struct line_segment *segment = &::lines[line].segments[i]; + const struct line_segment *segment = &::lines[line].segments[i]; if (n_offset < segment->length) { selected_segment = i; break; @@ -838,6 +932,7 @@ void RoadLinesData::line_building_data::from_dict(line_building_data *b, b->line_offset = from.get("line_offset", -1.0f); b->normal_offset = from.get("normal_offset", -1.0f); b->y_rotation = from.get("y_rotation", Math_NAN); + b->y_offset = from.get("y_offset", Math_NAN); } Dictionary RoadLinesData::line_building_data::to_dict() const @@ -847,5 +942,6 @@ Dictionary RoadLinesData::line_building_data::to_dict() const ret["line_offset"] = line_offset; ret["normal_offset"] = normal_offset; ret["y_rotation"] = y_rotation; + ret["y_offset"] = y_offset; return ret; } diff --git a/src/modules/stream/road_lines_data.h b/src/modules/stream/road_lines_data.h index 1fc3863..7d20eb9 100644 --- a/src/modules/stream/road_lines_data.h +++ b/src/modules/stream/road_lines_data.h @@ -21,12 +21,13 @@ public: float line_offset; float normal_offset; float y_rotation; + float y_offset; static void from_dict(struct line_building_data *b, const Dictionary &from); Dictionary to_dict() const; }; -private: +public: struct line_segment { Vector3 p1; Vector3 p2; @@ -57,10 +58,17 @@ private: public: const struct road_line &get_line(const String &key) const; - struct road_line &get_line(const String &key); const struct road_line &lines(const String &key) const; - struct road_line &lines(const String &key); + void set_line(const String &key, const struct road_line &line); bool has_line(const String &key); + void insert_line_point(const String &key, int index, + const Transform &xform); + void erase_line_point(const String &key, int index); + void set_line_point_position(const String &key, int index, + const Vector3 &position); + void clear_all_line_indices(); + void clear_line_indices(const String &key); + void set_line_metadata(const String &key, const Dictionary &metadata); static RoadLinesData *get_singleton(); virtual ~RoadLinesData(); @@ -80,7 +88,7 @@ public: void update_line_segments(const String &line); void line_add_building(const String &line, const String &key, float curve_offset, float normal_offset, - float y_rotation); + float y_rotation, float y_offset); void assign_close_buildings(const String &line); bool line_has_building(const String &line, const String &building_key); Vector3 get_point_by_offsets(const String &line, float dir_offset, @@ -101,7 +109,7 @@ private: void dump_road_lines(const std::vector &road_lines_nodes); void road_lines_curve_index( - struct RoadLinesData::road_line &rline, + const String &key, std::unordered_map > &road_lines_nodes_hash, std::vector &road_lines_nodes); diff --git a/src/modules/stream/road_lines_editor.cpp b/src/modules/stream/road_lines_editor.cpp index 5832d7f..edb8d9a 100644 --- a/src/modules/stream/road_lines_editor.cpp +++ b/src/modules/stream/road_lines_editor.cpp @@ -724,10 +724,7 @@ void RoadLinesEditor::line_create_point() Vector3 position = get_cursor_position(); Transform xform(Basis(), position); int index = get_line_index(); - rld->lines(current_line) - .points.insert(rld->lines(current_line).points.begin() + index + - 1, - xform); + rld->insert_line_point(current_line, index + 1, xform); Array args; args.push_back(current_line); EditorEvent::get_singleton()->event.emit("lines_changed_line", args); @@ -746,8 +743,7 @@ void RoadLinesEditor::line_delete_point() RoadLinesData *rld = RoadLinesData::get_singleton(); if (rld->lines(current_line).points.size() < 2) return; - rld->lines(current_line) - .points.erase(rld->lines(current_line).points.begin() + index); + rld->erase_line_point(current_line, index); Array args; args.push_back(current_line); EditorEvent::get_singleton()->event.emit("lines_changed_line", args); @@ -768,7 +764,7 @@ void RoadLinesEditor::set_point_to_cursor() Spatial *cursor = get_as_node(cursor_name); Transform xform = cursor->get_global_transform(); int index = get_line_index(); - rld->lines(current_line).points[index].origin = xform.origin; + rld->set_line_point_position(current_line, index, xform.origin); Array args; args.push_back(current_line); EditorEvent::get_singleton()->event.emit("lines_changed_line", args); @@ -944,7 +940,7 @@ void RoadLinesEditor::create_new_line_at_cursor(const String &line_name) rline.pattern = 0; Transform cursor_position(Basis(), get_cursor_position()); rline.points.push_back(cursor_position); - rld->lines(line_name) = rline; + rld->set_line(line_name, rline); update_line_index_ui(); update_ui(); } @@ -977,7 +973,7 @@ void RoadLinesEditor::set_point_position(const Vector3 &position) { RoadLinesData *rld = RoadLinesData::get_singleton(); int index = get_line_index(); - rld->lines(current_line).points[index].origin = position; + rld->set_line_point_position(current_line, index, position); Array args; args.push_back(current_line); EditorEvent::get_singleton()->event.emit("lines_changed_line", args); @@ -1244,7 +1240,7 @@ void RoadLinesEditor::update_current_line_metadata(const String &text) print_line("Invalid metadata type, should be Dictionary"); return; } - rld->lines(current_line).metadata = v; + rld->set_line_metadata(current_line, v); } String RoadLinesEditor::get_current_line_metadata() const {