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];
}
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)
{
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<uint32_t, std::vector<Vector3> >
&road_lines_nodes_hash,
std::vector<Vector3> &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<String>::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<Vector3> &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<Vector3> &road_lines_nodes)
{
#if 0
int i;
List<String> 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();
}
#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;
}

View File

@@ -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<Vector3> &road_lines_nodes);
void road_lines_curve_index(
struct RoadLinesData::road_line &rline,
const String &key,
std::unordered_map<uint32_t, std::vector<Vector3> >
&road_lines_nodes_hash,
std::vector<Vector3> &road_lines_nodes);

View File

@@ -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<Spatial>(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
{