Worked on buildings in lines
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
#include <scene/3d/immediate_geometry.h>
|
||||
#include <scene/main/viewport.h>
|
||||
#include "from_string.h"
|
||||
#include "buildings_data.h"
|
||||
#include "road_lines_data.h"
|
||||
|
||||
ImmediateGeometry *RoadLinesData::debug_im = nullptr;
|
||||
@@ -62,7 +63,6 @@ RoadLinesData::RoadLinesData()
|
||||
e = e->next();
|
||||
}
|
||||
}
|
||||
|
||||
RoadLinesData *RoadLinesData::singleton = nullptr;
|
||||
RoadLinesData *RoadLinesData::get_singleton()
|
||||
{
|
||||
@@ -70,7 +70,6 @@ RoadLinesData *RoadLinesData::get_singleton()
|
||||
singleton = memnew(RoadLinesData);
|
||||
return singleton;
|
||||
}
|
||||
|
||||
RoadLinesData::~RoadLinesData()
|
||||
{
|
||||
#if 0
|
||||
@@ -80,18 +79,15 @@ RoadLinesData::~RoadLinesData()
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void RoadLinesData::cleanup()
|
||||
{
|
||||
memdelete(singleton);
|
||||
singleton = nullptr;
|
||||
}
|
||||
|
||||
String RoadLinesData::get_road_lines_path()
|
||||
{
|
||||
return road_lines_path;
|
||||
}
|
||||
|
||||
void RoadLinesData::get_road_lines_key_list(List<String> *keys)
|
||||
{
|
||||
List<String> line_keys;
|
||||
@@ -234,8 +230,7 @@ void RoadLinesData::create_segments(const String &road,
|
||||
std::vector<int> &segments)
|
||||
{
|
||||
int i;
|
||||
RoadLinesData *rld = RoadLinesData::get_singleton();
|
||||
for (i = 0; i < (int)rld->lines[road].indices.size() - 1; i++) {
|
||||
for (i = 0; i < (int)lines[road].indices.size() - 1; i++) {
|
||||
segments.push_back(i);
|
||||
segments.push_back(i + 1);
|
||||
}
|
||||
@@ -296,14 +291,12 @@ void RoadLinesData::insert_close_points(std::vector<Vector3> &road_lines_nodes,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RoadLinesData::update_road_lines_nodes(
|
||||
std::vector<Vector3> &road_lines_nodes)
|
||||
{
|
||||
List<String> keys;
|
||||
RoadLinesData *rld = RoadLinesData::get_singleton();
|
||||
|
||||
rld->get_road_lines_key_list(&keys);
|
||||
get_road_lines_key_list(&keys);
|
||||
std::unordered_map<uint32_t, std::tuple<String, String> > kcmp;
|
||||
{
|
||||
List<String>::Element *k = keys.front();
|
||||
@@ -335,25 +328,22 @@ void RoadLinesData::update_road_lines_nodes(
|
||||
std::tuple<String, String> data = kcmp[it->first];
|
||||
const String &k = std::get<0>(data);
|
||||
const String &r = std::get<1>(data);
|
||||
if (rld->lines[k].indices.size() < 2)
|
||||
if (lines[k].indices.size() < 2)
|
||||
continue;
|
||||
if (rld->lines[r].indices.size() < 2)
|
||||
if (lines[r].indices.size() < 2)
|
||||
continue;
|
||||
for (i = 0; i < (int)rld->lines[k].indices.size() - 1; i++) {
|
||||
for (j = 0; j < (int)rld->lines[k].indices.size() - 1;
|
||||
j++) {
|
||||
for (i = 0; i < (int)lines[k].indices.size() - 1; i++) {
|
||||
for (j = 0; j < (int)lines[k].indices.size() - 1; j++) {
|
||||
uint32_t key = k.hash() ^ i ^ r.hash() ^ j ^
|
||||
2147483137;
|
||||
uint32_t key2 = r.hash() ^ j ^ k.hash() ^ i ^
|
||||
2147463167;
|
||||
if (checks.find(key) == checks.end() &&
|
||||
checks.find(key2) == checks.end()) {
|
||||
int idx_a1 = rld->lines[k].indices[i];
|
||||
int idx_a2 =
|
||||
rld->lines[k].indices[i + 1];
|
||||
int idx_b1 = rld->lines[k].indices[j];
|
||||
int idx_b2 =
|
||||
rld->lines[k].indices[j + 1];
|
||||
int idx_a1 = lines[k].indices[i];
|
||||
int idx_a2 = lines[k].indices[i + 1];
|
||||
int idx_b1 = lines[k].indices[j];
|
||||
int idx_b2 = lines[k].indices[j + 1];
|
||||
std::vector<int> cmp1 = { idx_a1,
|
||||
idx_a2 };
|
||||
if (std::find(cmp1.begin(), cmp1.end(),
|
||||
@@ -419,16 +409,16 @@ void RoadLinesData::update_road_lines_nodes(
|
||||
int nidx = road_lines_nodes.size();
|
||||
road_lines_nodes.push_back(pxt);
|
||||
// int il = (int)road_lines[k].indices.size();
|
||||
assert(std::find(rld->lines[k].indices.begin(),
|
||||
rld->lines[k].indices.end(),
|
||||
nidx) == rld->lines[k].indices.end());
|
||||
assert(std::find(rld->lines[r].indices.begin(),
|
||||
rld->lines[r].indices.end(),
|
||||
nidx) == rld->lines[r].indices.end());
|
||||
rld->lines[k].indices.insert(
|
||||
rld->lines[k].indices.begin() + i + 1, nidx);
|
||||
rld->lines[r].indices.insert(
|
||||
rld->lines[k].indices.begin() + j + 1, nidx);
|
||||
assert(std::find(lines[k].indices.begin(),
|
||||
lines[k].indices.end(),
|
||||
nidx) == lines[k].indices.end());
|
||||
assert(std::find(lines[r].indices.begin(),
|
||||
lines[r].indices.end(),
|
||||
nidx) == lines[r].indices.end());
|
||||
lines[k].indices.insert(
|
||||
lines[k].indices.begin() + i + 1, nidx);
|
||||
lines[r].indices.insert(
|
||||
lines[k].indices.begin() + j + 1, nidx);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -436,12 +426,11 @@ void RoadLinesData::dump_road_lines(const std::vector<Vector3> &road_lines_nodes
|
||||
{
|
||||
int i;
|
||||
List<String> keys;
|
||||
RoadLinesData *rld = RoadLinesData::get_singleton();
|
||||
rld->get_road_lines_key_list(&keys);
|
||||
get_road_lines_key_list(&keys);
|
||||
List<String>::Element *e = keys.front();
|
||||
while (e) {
|
||||
String rkey = e->get();
|
||||
struct RoadLinesData::road_line &pt = rld->lines[rkey];
|
||||
struct RoadLinesData::road_line &pt = lines[rkey];
|
||||
String outline = rkey + ": ";
|
||||
for (i = 0; i < (int)pt.indices.size(); i++) {
|
||||
outline += " " + itos(pt.indices[i]);
|
||||
@@ -453,7 +442,6 @@ void RoadLinesData::dump_road_lines(const std::vector<Vector3> &road_lines_nodes
|
||||
e = e->next();
|
||||
}
|
||||
}
|
||||
|
||||
ImmediateGeometry *RoadLinesData::get_debug_node()
|
||||
{
|
||||
if (!debug_im) {
|
||||
@@ -474,7 +462,6 @@ ImmediateGeometry *RoadLinesData::get_debug_node()
|
||||
}
|
||||
return debug_im;
|
||||
}
|
||||
|
||||
void RoadLinesData::process_lines(
|
||||
std::unordered_map<uint32_t, std::vector<Vector3> >
|
||||
&road_lines_nodes_hash,
|
||||
@@ -485,13 +472,181 @@ void RoadLinesData::process_lines(
|
||||
update_road_lines_nodes(road_lines_nodes);
|
||||
dump_road_lines(road_lines_nodes);
|
||||
}
|
||||
|
||||
void RoadLinesData::set_debug_flags(int debug_flags)
|
||||
{
|
||||
this->debug_flags = debug_flags;
|
||||
}
|
||||
|
||||
int RoadLinesData::get_debug_flags() const
|
||||
{
|
||||
return debug_flags;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
void RoadLinesData::line_add_building(const String &line, const String &key,
|
||||
float curve_offset, float normal_offset)
|
||||
{
|
||||
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();
|
||||
lb.line_offset = curve_offset;
|
||||
lb.normal_offset = normal_offset;
|
||||
lines[line].buildings.push_back(lb);
|
||||
// TODO: save/load
|
||||
BuildingsData::get_singleton()->buildings[index].line_name = line;
|
||||
}
|
||||
|
||||
void RoadLinesData::assign_close_buildings(const String &line)
|
||||
{
|
||||
int i, j;
|
||||
print_line("assign_close_buildings: " + line);
|
||||
if (!lines.has(line))
|
||||
return;
|
||||
if (!line.ends_with("_buildings"))
|
||||
return;
|
||||
if (lines[line].points.size() < 2)
|
||||
return;
|
||||
update_line_segments(line);
|
||||
if (lines[line].segments.size() == 0)
|
||||
return;
|
||||
print_line("assign_close_buildings: processing: " +
|
||||
itos(BuildingsData::get_singleton()->buildings.size()) +
|
||||
" buildings");
|
||||
for (i = 0; i < (int)BuildingsData::get_singleton()->buildings.size();
|
||||
i++) {
|
||||
float dst = Math_INF;
|
||||
float result_offset = 0.0f;
|
||||
float side = 0.0f;
|
||||
String building_key;
|
||||
struct BuildingsData::building &data =
|
||||
BuildingsData::get_singleton()->buildings[i];
|
||||
// manually placed
|
||||
if (!data.generated)
|
||||
continue;
|
||||
// already assigned to another line
|
||||
const String &building_line =
|
||||
BuildingsData::get_singleton()->buildings[i].line_name;
|
||||
if (building_line != line && building_line != "")
|
||||
continue;
|
||||
if (line_has_building(line, data.key))
|
||||
continue;
|
||||
Vector3 p = data.xform.origin;
|
||||
Vector3 segment_point;
|
||||
int segment_index = -1;
|
||||
|
||||
for (j = 0; j < (int)lines[line].segments.size(); j++) {
|
||||
Vector3 seg[] = { lines[line].segments[j].p1,
|
||||
lines[line].segments[j].p2 };
|
||||
Vector3 closest =
|
||||
Geometry::get_closest_point_to_segment(p, seg);
|
||||
Vector3 xp = p;
|
||||
xp.y = p.y;
|
||||
float tmpdst = xp.distance_squared_to(closest);
|
||||
if (closest.is_equal_approx(
|
||||
lines[line].segments[j].p1) ||
|
||||
closest.is_equal_approx(
|
||||
lines[line].segments[j].p2)) {
|
||||
float w = closest.dot(
|
||||
lines[line].segments[j].dir);
|
||||
float wt = xp.dot(lines[line].segments[j].dir);
|
||||
if (wt - w > 0.1f || wt - w < -0.1f)
|
||||
continue;
|
||||
}
|
||||
if (dst > tmpdst) {
|
||||
dst = tmpdst;
|
||||
building_key = data.key;
|
||||
segment_index = j;
|
||||
segment_point = closest;
|
||||
}
|
||||
}
|
||||
if (segment_index < 0)
|
||||
continue;
|
||||
|
||||
const Vector3 &p1 = lines[line].segments[segment_index].p1;
|
||||
const Vector3 &p2 = lines[line].segments[segment_index].p2;
|
||||
const Vector3 &dir = lines[line].segments[segment_index].dir;
|
||||
assert(segment_index >= 0);
|
||||
// assert(!segment_point.is_equal_approx(p1));
|
||||
// assert(!segment_point.is_equal_approx(p2));
|
||||
assert((segment_point - p1).dot(dir) >= 0);
|
||||
float wdst = (p - p1).dot(dir);
|
||||
print_line("wdst=" + String::num(wdst));
|
||||
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);
|
||||
|
||||
print_line("key: " + building_key +
|
||||
" dst: " + String::num(dst));
|
||||
if (dst < 16 * 16) {
|
||||
print_line("adding: key: " + building_key +
|
||||
" dst: " + String::num(dst));
|
||||
assert(result_offset >= 0);
|
||||
line_add_building(line, building_key, result_offset,
|
||||
side);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool RoadLinesData::line_has_building(const String &line,
|
||||
const String &building_key)
|
||||
{
|
||||
uint64_t key_hash = building_key.hash64();
|
||||
bool ret = false;
|
||||
int i;
|
||||
for (i = 0; i < (int)lines[line].buildings.size(); i++)
|
||||
if (lines[line].buildings[i].building_key_hash == key_hash) {
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
Vector3 RoadLinesData::get_point_by_offsets(const String &line,
|
||||
float dir_offset,
|
||||
float normal_offset)
|
||||
{
|
||||
Vector3 ret;
|
||||
int i;
|
||||
print_verbose("line: " + line +
|
||||
" line_offset: " + String::num(dir_offset) +
|
||||
" normal_offset: " + String::num(normal_offset));
|
||||
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];
|
||||
if (n_offset < segment->length) {
|
||||
selected_segment = i;
|
||||
break;
|
||||
}
|
||||
n_offset -= segment->length;
|
||||
}
|
||||
ret = lines[line].segments[selected_segment].p1 +
|
||||
lines[line].segments[selected_segment].dir * n_offset +
|
||||
lines[line].segments[selected_segment].tangent * normal_offset;
|
||||
return ret;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user