Accessor is ready for ECS

This commit is contained in:
2024-10-02 23:09:01 +03:00
parent 794857209d
commit b0613d9ad1
3 changed files with 166 additions and 66 deletions

View File

@@ -38,10 +38,97 @@ public:
{ {
return lines_[key]; 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<String> keys;
get_key_list(&keys);
List<String>::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) inline bool has(const String &key)
{ {
return lines_.has(key); return lines_.has(key);
@@ -75,22 +162,45 @@ RoadLinesData::get_line(const String &key) const
{ {
return ::lines[key]; 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 const RoadLinesData::road_line &RoadLinesData::lines(const String &key) const
{ {
return ::lines[key]; 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) bool RoadLinesData::has_line(const String &key)
{ {
return ::lines.has(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() RoadLinesData *RoadLinesData::get_singleton()
{ {
if (!singleton) if (!singleton)
@@ -190,7 +300,7 @@ void RoadLinesData::load_data()
} }
// TODO: wtf is flags? // TODO: wtf is flags?
rline.lanes = lanes; rline.lanes = lanes;
lines(key) = rline; set_line(key, rline);
e = e->next(); e = e->next();
} }
} }
@@ -256,15 +366,15 @@ uint32_t RoadLinesData::road_lines_hash(const Vector3 &v)
return x ^ (y * 100) ^ (z * 10000); return x ^ (y * 100) ^ (z * 10000);
} }
void RoadLinesData::road_lines_curve_index( void RoadLinesData::road_lines_curve_index(
struct RoadLinesData::road_line &rline, const String &key,
std::unordered_map<uint32_t, std::vector<Vector3> > std::unordered_map<uint32_t, std::vector<Vector3> >
&road_lines_nodes_hash, &road_lines_nodes_hash,
std::vector<Vector3> &road_lines_nodes) std::vector<Vector3> &road_lines_nodes)
{ {
int i, j; int i, j;
rline.indices.clear(); ::lines.clear_line_indices(key);
for (i = 0; i < (int)rline.points.size(); i++) { for (i = 0; i < (int)::lines.get_line_points_count(key); i++) {
Vector3 pt = rline.points[i].origin; Vector3 pt = ::lines.get_line_point_position(key, i);
int pt_hash = road_lines_hash(pt); int pt_hash = road_lines_hash(pt);
if (road_lines_nodes_hash.find(pt_hash) != if (road_lines_nodes_hash.find(pt_hash) !=
road_lines_nodes_hash.end()) { road_lines_nodes_hash.end()) {
@@ -292,7 +402,7 @@ void RoadLinesData::road_lines_curve_index(
road_lines_nodes.begin(), road_lines_nodes.end(), pt); road_lines_nodes.begin(), road_lines_nodes.end(), pt);
assert(it != road_lines_nodes.end()); assert(it != road_lines_nodes.end());
int index = it - road_lines_nodes.begin(); int index = it - road_lines_nodes.begin();
rline.indices.push_back(index); ::lines.add_line_index(key, index);
} }
} }
void RoadLinesData::index_lines( void RoadLinesData::index_lines(
@@ -305,15 +415,13 @@ void RoadLinesData::index_lines(
List<String>::Element *e = keys.front(); List<String>::Element *e = keys.front();
while (e) { while (e) {
String rkey = e->get(); String rkey = e->get();
struct RoadLinesData::road_line &pt = ::lines[rkey]; clear_line_indices(rkey);
pt.indices.clear();
e = e->next(); e = e->next();
} }
e = keys.front(); e = keys.front();
while (e) { while (e) {
String rkey = e->get(); String rkey = e->get();
struct RoadLinesData::road_line &pt = ::lines[rkey]; road_lines_curve_index(rkey, road_lines_nodes_hash,
road_lines_curve_index(pt, road_lines_nodes_hash,
road_lines_nodes); road_lines_nodes);
e = e->next(); e = e->next();
} }
@@ -378,10 +486,8 @@ void RoadLinesData::insert_close_points(std::vector<Vector3> &road_lines_nodes,
distance_squared) { distance_squared) {
/* split segment and replace road /* split segment and replace road
point with a point on segment */ point with a point on segment */
::lines[rkey].indices.insert( ::lines.insert_line_index(rkey, idx,
::lines[rkey].indices.begin() + idx3);
idx,
idx3);
road_lines_nodes[idx3] = closest; road_lines_nodes[idx3] = closest;
} }
} }
@@ -514,15 +620,21 @@ void RoadLinesData::update_road_lines_nodes(
assert(std::find(::lines[r].indices.begin(), assert(std::find(::lines[r].indices.begin(),
::lines[r].indices.end(), ::lines[r].indices.end(),
nidx) == ::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.insert(
::lines[k].indices.begin() + i + 1, nidx); ::lines[k].indices.begin() + i + 1, nidx);
::lines[r].indices.insert( ::lines[r].indices.insert(
::lines[k].indices.begin() + j + 1, nidx); ::lines[k].indices.begin() + j + 1, nidx);
#endif
} }
} }
} }
void RoadLinesData::dump_road_lines(const std::vector<Vector3> &road_lines_nodes) void RoadLinesData::dump_road_lines(const std::vector<Vector3> &road_lines_nodes)
{ {
#if 0
int i; int i;
List<String> keys; List<String> keys;
get_road_lines_key_list(&keys); get_road_lines_key_list(&keys);
@@ -540,6 +652,7 @@ void RoadLinesData::dump_road_lines(const std::vector<Vector3> &road_lines_nodes
} }
e = e->next(); e = e->next();
} }
#endif
} }
ImmediateGeometry *RoadLinesData::get_debug_node() ImmediateGeometry *RoadLinesData::get_debug_node()
{ {
@@ -582,36 +695,15 @@ int RoadLinesData::get_debug_flags() const
void RoadLinesData::update_line_segments(const String &line) void RoadLinesData::update_line_segments(const String &line)
{ {
int i; ::lines.update_line_segments(line);
::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;
}
} }
void RoadLinesData::line_add_building(const String &line, const String &key, void RoadLinesData::line_add_building(const String &line, const String &key,
float curve_offset, float normal_offset, float curve_offset, float normal_offset,
float y_rotation) float y_rotation, float y_offset)
{ {
struct line_building_data lb; ::lines.line_add_building(line, key, curve_offset, normal_offset,
lb.building_key = key; y_rotation, y_offset);
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);
// TODO: save/load // TODO: save/load
BuildingsData::get_singleton()->get_building(key).line_name = line; 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 dst = Math_INF;
float result_offset = 0.0f; float result_offset = 0.0f;
float side = 0.0f; float side = 0.0f;
float yoff = 0.0f;
String building_key; String building_key;
/* FIXME: use proper function */ /* FIXME: use proper function */
String bkey = e->get(); String bkey = e->get();
@@ -700,9 +793,8 @@ void RoadLinesData::assign_close_buildings(const String &line)
assert(wdst >= 0); assert(wdst >= 0);
result_offset = result_offset =
::lines[line].segments[segment_index].offset + wdst; ::lines[line].segments[segment_index].offset + wdst;
side = (p - p1).dot(::lines[line].segments[j].tangent);
assert(result_offset >= 0); assert(result_offset >= 0);
side = (p - p1).dot(::lines[line].segments[j].tangent);
print_line("key: " + building_key + print_line("key: " + building_key +
" dst: " + String::num(dst)); " dst: " + String::num(dst));
@@ -715,9 +807,11 @@ void RoadLinesData::assign_close_buildings(const String &line)
data.xform.basis.xform(reference).normalized(); data.xform.basis.xform(reference).normalized();
float angle = reference.signed_angle_to( float angle = reference.signed_angle_to(
rotated, Vector3(0, 1, 0)); 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, 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; float n_offset = dir_offset;
int selected_segment = 0; int selected_segment = 0;
for (i = 0; i < (int)::lines[line].segments.size(); i++) { 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) { if (n_offset < segment->length) {
selected_segment = i; selected_segment = i;
break; 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->line_offset = from.get("line_offset", -1.0f);
b->normal_offset = from.get("normal_offset", -1.0f); b->normal_offset = from.get("normal_offset", -1.0f);
b->y_rotation = from.get("y_rotation", Math_NAN); 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 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["line_offset"] = line_offset;
ret["normal_offset"] = normal_offset; ret["normal_offset"] = normal_offset;
ret["y_rotation"] = y_rotation; ret["y_rotation"] = y_rotation;
ret["y_offset"] = y_offset;
return ret; return ret;
} }

View File

@@ -21,12 +21,13 @@ public:
float line_offset; float line_offset;
float normal_offset; float normal_offset;
float y_rotation; float y_rotation;
float y_offset;
static void from_dict(struct line_building_data *b, static void from_dict(struct line_building_data *b,
const Dictionary &from); const Dictionary &from);
Dictionary to_dict() const; Dictionary to_dict() const;
}; };
private: public:
struct line_segment { struct line_segment {
Vector3 p1; Vector3 p1;
Vector3 p2; Vector3 p2;
@@ -57,10 +58,17 @@ private:
public: public:
const struct road_line &get_line(const String &key) const; 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; 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); 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(); static RoadLinesData *get_singleton();
virtual ~RoadLinesData(); virtual ~RoadLinesData();
@@ -80,7 +88,7 @@ public:
void update_line_segments(const String &line); void update_line_segments(const String &line);
void line_add_building(const String &line, const String &key, void line_add_building(const String &line, const String &key,
float curve_offset, float normal_offset, float curve_offset, float normal_offset,
float y_rotation); float y_rotation, float y_offset);
void assign_close_buildings(const String &line); void assign_close_buildings(const String &line);
bool line_has_building(const String &line, const String &building_key); bool line_has_building(const String &line, const String &building_key);
Vector3 get_point_by_offsets(const String &line, float dir_offset, Vector3 get_point_by_offsets(const String &line, float dir_offset,
@@ -101,7 +109,7 @@ private:
void dump_road_lines(const std::vector<Vector3> &road_lines_nodes); void dump_road_lines(const std::vector<Vector3> &road_lines_nodes);
void road_lines_curve_index( void road_lines_curve_index(
struct RoadLinesData::road_line &rline, const String &key,
std::unordered_map<uint32_t, std::vector<Vector3> > std::unordered_map<uint32_t, std::vector<Vector3> >
&road_lines_nodes_hash, &road_lines_nodes_hash,
std::vector<Vector3> &road_lines_nodes); std::vector<Vector3> &road_lines_nodes);

View File

@@ -724,10 +724,7 @@ void RoadLinesEditor::line_create_point()
Vector3 position = get_cursor_position(); Vector3 position = get_cursor_position();
Transform xform(Basis(), position); Transform xform(Basis(), position);
int index = get_line_index(); int index = get_line_index();
rld->lines(current_line) rld->insert_line_point(current_line, index + 1, xform);
.points.insert(rld->lines(current_line).points.begin() + index +
1,
xform);
Array args; Array args;
args.push_back(current_line); args.push_back(current_line);
EditorEvent::get_singleton()->event.emit("lines_changed_line", args); EditorEvent::get_singleton()->event.emit("lines_changed_line", args);
@@ -746,8 +743,7 @@ void RoadLinesEditor::line_delete_point()
RoadLinesData *rld = RoadLinesData::get_singleton(); RoadLinesData *rld = RoadLinesData::get_singleton();
if (rld->lines(current_line).points.size() < 2) if (rld->lines(current_line).points.size() < 2)
return; return;
rld->lines(current_line) rld->erase_line_point(current_line, index);
.points.erase(rld->lines(current_line).points.begin() + index);
Array args; Array args;
args.push_back(current_line); args.push_back(current_line);
EditorEvent::get_singleton()->event.emit("lines_changed_line", args); EditorEvent::get_singleton()->event.emit("lines_changed_line", args);
@@ -768,7 +764,7 @@ void RoadLinesEditor::set_point_to_cursor()
Spatial *cursor = get_as_node<Spatial>(cursor_name); Spatial *cursor = get_as_node<Spatial>(cursor_name);
Transform xform = cursor->get_global_transform(); Transform xform = cursor->get_global_transform();
int index = get_line_index(); 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; Array args;
args.push_back(current_line); args.push_back(current_line);
EditorEvent::get_singleton()->event.emit("lines_changed_line", args); 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; rline.pattern = 0;
Transform cursor_position(Basis(), get_cursor_position()); Transform cursor_position(Basis(), get_cursor_position());
rline.points.push_back(cursor_position); rline.points.push_back(cursor_position);
rld->lines(line_name) = rline; rld->set_line(line_name, rline);
update_line_index_ui(); update_line_index_ui();
update_ui(); update_ui();
} }
@@ -977,7 +973,7 @@ void RoadLinesEditor::set_point_position(const Vector3 &position)
{ {
RoadLinesData *rld = RoadLinesData::get_singleton(); RoadLinesData *rld = RoadLinesData::get_singleton();
int index = get_line_index(); int index = get_line_index();
rld->lines(current_line).points[index].origin = position; rld->set_line_point_position(current_line, index, position);
Array args; Array args;
args.push_back(current_line); args.push_back(current_line);
EditorEvent::get_singleton()->event.emit("lines_changed_line", args); 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"); print_line("Invalid metadata type, should be Dictionary");
return; return;
} }
rld->lines(current_line).metadata = v; rld->set_line_metadata(current_line, v);
} }
String RoadLinesEditor::get_current_line_metadata() const String RoadLinesEditor::get_current_line_metadata() const
{ {