Refactoring of lines handling

This commit is contained in:
2024-09-11 15:59:00 +03:00
parent 2f3465350e
commit b3b7cc0d90
8 changed files with 578 additions and 514 deletions

View File

@@ -17,17 +17,10 @@
#include <modules/regex/regex.h>
#include "world_editor.h"
#include "from_string.h"
#include "road_lines_data.h"
#include "road_processing.h"
#include "road_lines_editor.h"
struct road_line {
std::vector<Transform> points;
std::vector<int> indices;
int lanes;
int pattern;
int flags;
Dictionary metadata;
};
static HashMap<String, struct road_line> lines;
static ImmediateGeometry *line_im = nullptr;
static Ref<Material> debug_material;
@@ -484,7 +477,8 @@ Node *RoadLinesEditor::scene()
static String current_line = "";
void RoadLinesEditor::update_line_geometry()
{
if (!lines.has(current_line)) {
RoadLinesData *rld = RoadLinesData::get_singleton();
if (!rld->lines.has(current_line)) {
if (line_im)
line_im->clear();
return;
@@ -498,15 +492,18 @@ void RoadLinesEditor::update_line_geometry()
line_im->set_color(Color(1.0f, 0.0f, 0.0f, 1.0f));
line_im->add_vertex(Vector3(0.0f, 100.0f, 0.0f));
line_im->end();
if (lines[current_line].points.size() > 1) {
if (rld->lines[current_line].points.size() > 1) {
line_im->begin(Mesh::PRIMITIVE_LINES);
for (i = 0;
i < (int)lines[current_line].points.size() - 1;
i <
(int)rld->lines[current_line].points.size() - 1;
i++) {
Vector3 pt1 =
lines[current_line].points[i].origin;
Vector3 pt2 =
lines[current_line].points[i + 1].origin;
Vector3 pt1 = rld->lines[current_line]
.points[i]
.origin;
Vector3 pt2 = rld->lines[current_line]
.points[i + 1]
.origin;
line_im->set_color(
Color(0.0f, 0.0f, 0.5f, 1.0f));
line_im->add_vertex(pt1);
@@ -527,14 +524,16 @@ void RoadLinesEditor::update_line_geometry()
}
void RoadLinesEditor::update_line_index_ui()
{
RoadLinesData *rld = RoadLinesData::get_singleton();
SpinBox *sp_line_index = get_as_node<SpinBox>("%line_index");
sp_line_index->set_max(lines[current_line].points.size() - 1);
sp_line_index->set_max(rld->lines[current_line].points.size() - 1);
sp_line_index->set_min(0);
}
void RoadLinesEditor::select_line(const String &line_name)
{
print_line("selected line: " + line_name);
assert(lines.has(line_name));
RoadLinesData *rld = RoadLinesData::get_singleton();
assert(rld->lines.has(line_name));
if (current_line != line_name) {
current_line = line_name;
update_line_index_ui();
@@ -550,18 +549,20 @@ void RoadLinesEditor::select_line(const String &line_name)
bool RoadLinesEditor::line_exists(const String &line_name)
{
return lines.has(line_name);
RoadLinesData *rld = RoadLinesData::get_singleton();
return rld->lines.has(line_name);
}
void RoadLinesEditor::line_create_point()
{
RoadLinesData *rld = RoadLinesData::get_singleton();
/* Create point in line */
print_line("line_create_point");
Vector3 position = get_cursor_position();
Transform xform(Basis(), position);
int index = get_line_index();
lines[current_line].points.insert(
lines[current_line].points.begin() + index + 1, xform);
rld->lines[current_line].points.insert(
rld->lines[current_line].points.begin() + index + 1, xform);
update_line_geometry();
update_line_index_ui();
SpinBox *sp_line_index = get_as_node<SpinBox>("%line_index");
@@ -574,10 +575,11 @@ void RoadLinesEditor::line_delete_point()
/* Delete point from line */
print_line("line_delete_point");
int index = get_line_index();
if (lines[current_line].points.size() < 2)
RoadLinesData *rld = RoadLinesData::get_singleton();
if (rld->lines[current_line].points.size() < 2)
return;
lines[current_line].points.erase(lines[current_line].points.begin() +
index);
rld->lines[current_line].points.erase(
rld->lines[current_line].points.begin() + index);
update_line_geometry();
update_line_index_ui();
SpinBox *sp_line_index = get_as_node<SpinBox>("%line_index");
@@ -590,13 +592,14 @@ static const String cursor_name = "%line_cursor";
void RoadLinesEditor::set_point_to_cursor()
{
RoadLinesData *rld = RoadLinesData::get_singleton();
print_line("set_point_to_cursor");
Spatial *cursor = get_as_node<Spatial>(cursor_name);
Transform xform = cursor->get_global_transform();
int index = get_line_index();
lines[current_line].points[index].origin = xform.origin;
rld->lines[current_line].points[index].origin = xform.origin;
update_line_geometry();
set_ui_point_position(lines[current_line].points[index].origin);
set_ui_point_position(rld->lines[current_line].points[index].origin);
}
int RoadLinesEditor::get_line_index()
@@ -610,8 +613,9 @@ int RoadLinesEditor::get_line_index()
void RoadLinesEditor::move_cursor_to_point()
{
print_line("move_cursor_to_point");
RoadLinesData *rld = RoadLinesData::get_singleton();
int index = get_line_index();
Transform xform(Basis(), lines[current_line].points[index].origin);
Transform xform(Basis(), rld->lines[current_line].points[index].origin);
set_cursor_position(xform.origin);
set_ui_cursor_position(xform.origin);
}
@@ -685,12 +689,13 @@ int RoadLinesEditor::get_camera_mode() const
void RoadLinesEditor::update_ui()
{
RoadLinesData *rld = RoadLinesData::get_singleton();
get_as_node<Control>("%road_lines_base")->show();
get_as_node<Control>("%road_lines_create_new_line_dlg")->hide();
get_as_node<Control>("%road_lines_edit_metadata_dlg")->hide();
ItemList *lines_list = get_as_node<ItemList>("%lines_list");
List<String> line_keys;
lines.get_key_list(&line_keys);
rld->lines.get_key_list(&line_keys);
List<String>::Element *e = line_keys.front();
lines_list->clear();
if (!re.is_valid())
@@ -722,7 +727,8 @@ void RoadLinesEditor::update_ui()
void RoadLinesEditor::create_new_line_at_cursor(const String &line_name)
{
print_line("creating new line called: " + line_name);
struct road_line rline;
RoadLinesData *rld = RoadLinesData::get_singleton();
struct RoadLinesData::road_line rline;
rline.flags = 0;
rline.indices.resize(0);
rline.lanes = -1;
@@ -732,17 +738,18 @@ 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);
lines[line_name] = rline;
rld->lines[line_name] = rline;
update_line_index_ui();
update_ui();
}
void RoadLinesEditor::delete_current_line()
{
RoadLinesData *rld = RoadLinesData::get_singleton();
String delete_line = current_line;
const String *k = lines.next(&delete_line);
const String *k = rld->lines.next(&delete_line);
current_line = *k;
lines.erase(delete_line);
rld->lines.erase(delete_line);
update_line_index_ui();
update_ui();
}
@@ -763,8 +770,9 @@ void RoadLinesEditor::set_cursor_position(const Vector3 &cursor_position)
}
void RoadLinesEditor::set_point_position(const Vector3 &position)
{
RoadLinesData *rld = RoadLinesData::get_singleton();
int index = get_line_index();
lines[current_line].points[index].origin = position;
rld->lines[current_line].points[index].origin = position;
update_line_geometry();
}
void RoadLinesEditor::set_ui_cursor_position(const Vector3 &cursor_position)
@@ -788,9 +796,10 @@ void RoadLinesEditor::set_ui_point_position(const Vector3 &point_position)
void RoadLinesEditor::set_line_index(int index)
{
assert(lines.has(current_line));
assert(index < (int)lines[current_line].points.size());
Vector3 point_position = lines[current_line].points[index].origin;
RoadLinesData *rld = RoadLinesData::get_singleton();
assert(rld->lines.has(current_line));
assert(index < (int)rld->lines[current_line].points.size());
Vector3 point_position = rld->lines[current_line].points[index].origin;
Vector3 cursor_position = point_position;
set_cursor_position(cursor_position);
set_ui_cursor_position(cursor_position);
@@ -807,7 +816,6 @@ void RoadLinesEditor::line_list_filter_changed(const String &text)
void RoadLinesEditor::activate()
{
assert(!active);
load_data();
print_line("activate::update UI");
update_ui();
if (!line_im) {
@@ -847,7 +855,6 @@ void RoadLinesEditor::deactivate()
NodePath("%lines_list"));
ItemList *lines_list = Object::cast_to<ItemList>(lines_list_node);
lines_list->clear();
lines.clear();
if (line_im) {
line_im->queue_delete();
line_im = nullptr;
@@ -874,52 +881,6 @@ void RoadLinesEditor::deactivate()
active = false;
}
void RoadLinesEditor::load_data()
{
int i;
ConfigFile config;
Error result = config.load("res://config/stream.conf");
ERR_FAIL_COND_MSG(result != OK, "Failed to load config");
String road_lines_path = config.get_value("lines", "road_lines_path");
String road_lines_json =
FileAccess::get_file_as_string(road_lines_path);
Variant json_v;
String es;
int eline;
Error status = JSON::parse(road_lines_json, json_v, es, eline);
ERR_FAIL_COND_MSG(status != OK, "Can't parse json: " + es +
" at line: " + itos(eline));
Dictionary json = json_v;
List<Variant> keys;
json.get_key_list(&keys);
List<Variant>::Element *e = keys.front();
while (e) {
String key = e->get();
struct road_line rline;
Dictionary entry = json.get(key, Dictionary());
Array points = entry.get("points", Array());
Array indices = entry.get("indices", Array());
rline.metadata = entry.get("metadata", Dictionary());
int lanes = entry.get("lanes", -1);
int pattern = entry.get("pattern", -1);
rline.pattern = pattern;
rline.points.resize(points.size());
rline.indices.resize(indices.size());
for (i = 0; i < (int)points.size(); i++) {
String point_s = points[i];
rline.points[i] = from_string<Transform>(point_s);
}
for (i = 0; i < (int)indices.size(); i++) {
int index = indices[i];
rline.indices[i] = index;
}
// TODO: wtf is flags?
rline.lanes = lanes;
lines[key] = rline;
e = e->next();
}
}
void RoadLinesEditor::place_generated_objects()
{
place_zebras();
@@ -1008,56 +969,12 @@ func place_zebras():
}
void RoadLinesEditor::save_data()
{
int i;
ConfigFile config;
Error result = config.load("res://config/stream.conf");
ERR_FAIL_COND_MSG(result != OK, "Failed to load config");
String road_lines_path = config.get_value("road", "road_lines_path");
String road_lines_json =
FileAccess::get_file_as_string(road_lines_path);
Dictionary output;
List<String> keys;
lines.get_key_list(&keys);
List<String>::Element *e = keys.front();
while (e) {
Dictionary pvalues;
Array points, indices;
points.resize(lines[e->get()].points.size());
for (i = 0; i < (int)lines[e->get()].points.size(); i++)
points[i] = to_string(lines[e->get()].points[i]);
indices.resize(lines[e->get()].indices.size());
for (i = 0; i < (int)lines[e->get()].indices.size(); i++)
indices[i] = lines[e->get()].indices[i];
pvalues["points"] = points;
// pvalues["indices"] = indices;
pvalues["metadata"] = lines[e->get()].metadata;
pvalues["lanes"] = lines[e->get()].lanes;
pvalues["pattern"] = lines[e->get()].pattern;
output[e->get()] = pvalues;
e = e->next();
}
print_verbose(JSON::print(output, "\t", false));
Error err = OK;
if (FileAccess::exists(road_lines_path)) {
DirAccess *dir = DirAccess::open("res:///", &err);
assert(dir && err == OK);
err = dir->copy(
road_lines_path,
road_lines_path + "." +
String::num(
Time::get_singleton()
->get_unix_time_from_system()));
}
FileAccess *fd =
FileAccess::open(road_lines_path, FileAccess::WRITE, &err);
if (err == OK) {
fd->store_string(JSON::print(output, "\t", false));
fd->close();
}
RoadLinesData::get_singleton()->save_data();
}
void RoadLinesEditor::update_current_line_metadata(const String &text)
{
assert(lines.has(current_line));
RoadLinesData *rld = RoadLinesData::get_singleton();
assert(rld->lines.has(current_line));
if (!text.begins_with("{"))
return;
String err_s;
@@ -1073,12 +990,13 @@ void RoadLinesEditor::update_current_line_metadata(const String &text)
print_line("Invalid metadata type, should be Dictionary");
return;
}
lines[current_line].metadata = v;
rld->lines[current_line].metadata = v;
}
String RoadLinesEditor::get_current_line_metadata() const
{
assert(lines.has(current_line));
return JSON::print(lines[current_line].metadata, "\t", true);
RoadLinesData *rld = RoadLinesData::get_singleton();
assert(rld->lines.has(current_line));
return JSON::print(rld->lines[current_line].metadata, "\t", true);
}
void RoadLinesEditor::remove_generated_stuff()
{