Quality of life with road lines edge data (lots, buildings, etc.)
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
#include "from_string.h"
|
||||
#include "road_debug.h"
|
||||
#include "road_lines_data.h"
|
||||
#include "buildings_data.h"
|
||||
#include "road_processing.h"
|
||||
|
||||
struct wedge {
|
||||
@@ -53,6 +54,328 @@ struct RoadLinesProcessing {
|
||||
memcpy(nodes.data(), road_lines_nodes.data(),
|
||||
sizeof(Vector3) * road_lines_nodes.size());
|
||||
}
|
||||
Transform get_structure_transform(Vector3 p0, Vector3 p1, Vector3 dir,
|
||||
Vector3 offset_n, float offset,
|
||||
float dir_offset, float y_rotation,
|
||||
float y_offset)
|
||||
{
|
||||
Transform xform(Basis(), p0 + dir * dir_offset +
|
||||
offset_n * offset +
|
||||
Vector3(0, 1, 0) * y_offset);
|
||||
Transform rot(Basis().rotated(Vector3(0, 1, 0),
|
||||
Math::deg2rad(y_rotation)),
|
||||
Vector3());
|
||||
xform.set_look_at(xform.origin, xform.origin + dir * dir_offset,
|
||||
Vector3(0, 1, 0));
|
||||
xform = xform * rot;
|
||||
return xform;
|
||||
}
|
||||
void create_building_structure(const BuildingsData::building &b)
|
||||
{
|
||||
assert(b.key.begins_with("road__"));
|
||||
assert(b.id.length() > 0);
|
||||
assert(b.key.length() > 0);
|
||||
if (BuildingsData::get_singleton()->has_building(b.key)) {
|
||||
BuildingsData::get_singleton()->remove_scene_item(
|
||||
b.id, b.key);
|
||||
BuildingsData::get_singleton()->destroy_building(b.key);
|
||||
}
|
||||
BuildingsData::get_singleton()->create_building(b);
|
||||
if (!BuildingsData::get_singleton()->has_scene(b.id))
|
||||
BuildingsData::get_singleton()->create_scene_data(
|
||||
b.id, b.key);
|
||||
else
|
||||
BuildingsData::get_singleton()->add_scene_item(b.id,
|
||||
b.key);
|
||||
print_line("created building: " + b.key);
|
||||
print_line("at: " + (b.xform.origin.operator String()));
|
||||
}
|
||||
int create_sideroads(const String &line_key, int edge_no,
|
||||
const RoadLinesData::road_edge &edge,
|
||||
const Vector3 &p0, const Vector3 &p1,
|
||||
const Vector3 &dir, const Vector3 left_n,
|
||||
const Vector3 &right_n)
|
||||
{
|
||||
int structures_generated = 0;
|
||||
if (edge.left.sideroad > 0) {
|
||||
Transform xform = get_structure_transform(
|
||||
p0, p1, dir, left_n, edge.left.sideroad_offset,
|
||||
edge.left.sideroad_dir_offset,
|
||||
edge.left.sideroad_y_rotation,
|
||||
edge.left.sideroad_y_offset);
|
||||
BuildingsData::building b;
|
||||
b.key = "road__" + line_key + "__sideroad__" +
|
||||
itos(edge_no) + "__left__sideroad-" +
|
||||
edge.left.sideroad_type;
|
||||
b.id = "sideroad-" + edge.left.sideroad_type;
|
||||
b.generated = true;
|
||||
b.line_name = line_key;
|
||||
b.key_hash = b.key.hash64();
|
||||
b.pattern_id = 0;
|
||||
b.xform = xform;
|
||||
b.worktime[0] = 0;
|
||||
b.worktime[1] = 23;
|
||||
if (edge.left.sideroad_type.length() == 0) {
|
||||
print_error("bad sideroad");
|
||||
goto out;
|
||||
}
|
||||
create_building_structure(b);
|
||||
structures_generated++;
|
||||
out:;
|
||||
}
|
||||
if (edge.right.sideroad > 0) {
|
||||
Transform xform = get_structure_transform(
|
||||
p0, p1, dir, right_n,
|
||||
edge.right.sideroad_offset,
|
||||
edge.right.sideroad_dir_offset,
|
||||
edge.right.sideroad_y_rotation,
|
||||
edge.right.sideroad_y_offset);
|
||||
BuildingsData::building b;
|
||||
b.key = "road__" + line_key + "__sideroad__" +
|
||||
itos(edge_no) + "__right__sideroad-" +
|
||||
edge.right.sideroad_type;
|
||||
b.id = "sideroad-" + edge.right.sideroad_type;
|
||||
b.generated = true;
|
||||
b.line_name = line_key;
|
||||
b.key_hash = b.key.hash64();
|
||||
b.pattern_id = 0;
|
||||
b.xform = xform;
|
||||
b.worktime[0] = 0;
|
||||
b.worktime[1] = 23;
|
||||
if (edge.right.sideroad_type.length() == 0) {
|
||||
print_error("bad sideroad");
|
||||
goto out2;
|
||||
}
|
||||
create_building_structure(b);
|
||||
structures_generated++;
|
||||
out2:;
|
||||
}
|
||||
return structures_generated;
|
||||
}
|
||||
int
|
||||
create_line_building(const String &line_key, int edge_id,
|
||||
const Transform &xform,
|
||||
const struct RoadLinesData::road_edge_side &side,
|
||||
const String &side_name)
|
||||
{
|
||||
int building_no;
|
||||
int structures_generated = 0;
|
||||
for (building_no = 0; building_no < (int)side.buildings.size();
|
||||
building_no++) {
|
||||
const struct RoadLinesData::road_edge_side::buildings
|
||||
&building = side.buildings[building_no];
|
||||
String id = side.buildings[building_no].id;
|
||||
id = id.strip_edges();
|
||||
if (id.length() == 0)
|
||||
continue;
|
||||
Transform rot(
|
||||
Basis().rotated(
|
||||
Vector3(0, 1, 0),
|
||||
Math::deg2rad(building.y_rotation)),
|
||||
building.offsets);
|
||||
Transform building_xform = xform * rot;
|
||||
BuildingsData::building bbuilding;
|
||||
bbuilding.id = id;
|
||||
bbuilding.key = "road__" + line_key + "__lot__" +
|
||||
itos(edge_id) + "__" + side_name +
|
||||
"__" + itos(building_no) +
|
||||
"__building-" + building.id;
|
||||
bbuilding.generated = true;
|
||||
bbuilding.line_name = line_key;
|
||||
bbuilding.key_hash = bbuilding.key.hash64();
|
||||
bbuilding.pattern_id = 0;
|
||||
bbuilding.xform = building_xform;
|
||||
bbuilding.worktime[0] = 0;
|
||||
bbuilding.worktime[1] = 23;
|
||||
create_building_structure(bbuilding);
|
||||
structures_generated++;
|
||||
}
|
||||
return structures_generated;
|
||||
}
|
||||
int create_lots(const String &line_key, int edge_no,
|
||||
const RoadLinesData::road_edge &edge, const Vector3 &p0,
|
||||
const Vector3 &p1, const Vector3 &dir,
|
||||
const Vector3 left_n, const Vector3 &right_n)
|
||||
{
|
||||
int structures_generated = 0;
|
||||
if (edge.left.lot > 0) {
|
||||
Transform xform = get_structure_transform(
|
||||
p0, p1, dir, left_n, edge.left.lot_offset,
|
||||
edge.left.lot_dir_offset,
|
||||
edge.left.lot_y_rotation,
|
||||
edge.left.lot_y_offset);
|
||||
BuildingsData::building b;
|
||||
b.key = "road__" + line_key + "__lot__" +
|
||||
itos(edge_no) + "__left__lot-" +
|
||||
edge.left.lot_type;
|
||||
b.id = "lot-" + edge.left.lot_type;
|
||||
b.generated = true;
|
||||
b.line_name = line_key;
|
||||
b.key_hash = b.key.hash64();
|
||||
b.pattern_id = 0;
|
||||
b.xform = xform;
|
||||
b.worktime[0] = 0;
|
||||
b.worktime[1] = 23;
|
||||
create_building_structure(b);
|
||||
structures_generated++;
|
||||
if (edge.left.buildings.size() > 0) {
|
||||
structures_generated += create_line_building(
|
||||
line_key, edge_no, xform, edge.left,
|
||||
"left");
|
||||
}
|
||||
}
|
||||
if (edge.right.lot > 0) {
|
||||
Transform xform = get_structure_transform(
|
||||
p0, p1, dir, right_n, edge.right.lot_offset,
|
||||
edge.right.lot_dir_offset,
|
||||
edge.right.lot_y_rotation,
|
||||
edge.right.lot_y_offset);
|
||||
BuildingsData::building b;
|
||||
b.key = "road__" + line_key + "__lot__" +
|
||||
itos(edge_no) + "__right__lot-" +
|
||||
edge.right.lot_type;
|
||||
b.id = "lot-" + edge.right.lot_type;
|
||||
b.generated = true;
|
||||
b.line_name = line_key;
|
||||
b.key_hash = b.key.hash64();
|
||||
b.pattern_id = 0;
|
||||
b.xform = xform;
|
||||
b.worktime[0] = 0;
|
||||
b.worktime[1] = 23;
|
||||
create_building_structure(b);
|
||||
structures_generated++;
|
||||
if (edge.right.buildings.size() > 0) {
|
||||
structures_generated += create_line_building(
|
||||
line_key, edge_no, xform, edge.right,
|
||||
"right");
|
||||
}
|
||||
}
|
||||
return structures_generated;
|
||||
}
|
||||
int create_transit_stops(const String &line_key, int edge_no,
|
||||
const RoadLinesData::road_edge &edge,
|
||||
const Vector3 &p0, const Vector3 &p1,
|
||||
const Vector3 &dir, const Vector3 left_n,
|
||||
const Vector3 &right_n)
|
||||
{
|
||||
int j;
|
||||
int structures_generated = 0;
|
||||
float l = p0.distance_to(p1);
|
||||
if (edge.left.transit_stop_count > 0) {
|
||||
print_line("Creating transit stops on the left");
|
||||
float t = 0.0f;
|
||||
float m =
|
||||
l / ((float)(edge.left.transit_stop_count + 1));
|
||||
for (j = 0; j < edge.left.transit_stop_count; j++) {
|
||||
Transform xform = get_structure_transform(
|
||||
p0, p1, dir, left_n,
|
||||
edge.left.transit_stop_offset,
|
||||
t + edge.left.transit_stop_dir_offset,
|
||||
edge.left.transit_stop_y_rotation,
|
||||
0.0f);
|
||||
BuildingsData::building b;
|
||||
b.key = "road__" + line_key +
|
||||
"__transit_stop__" + itos(edge_no) +
|
||||
"__" + itos(j) + "__left__" +
|
||||
edge.left.transit_stop_type;
|
||||
b.id = edge.left.transit_stop_type;
|
||||
b.generated = true;
|
||||
b.line_name = line_key;
|
||||
b.key_hash = b.key.hash64();
|
||||
b.pattern_id = 0;
|
||||
b.xform = xform;
|
||||
b.worktime[0] = 0;
|
||||
b.worktime[1] = 23;
|
||||
create_building_structure(b);
|
||||
t += m;
|
||||
structures_generated++;
|
||||
}
|
||||
}
|
||||
if (edge.right.transit_stop_count > 0) {
|
||||
print_line("Creating transit stops on the right");
|
||||
float t = 0.0f;
|
||||
float m = l /
|
||||
((float)(edge.right.transit_stop_count + 1));
|
||||
for (j = 0; j < edge.right.transit_stop_count; j++) {
|
||||
Transform xform = get_structure_transform(
|
||||
p0, p1, dir, right_n,
|
||||
edge.right.transit_stop_offset,
|
||||
t + edge.right.transit_stop_dir_offset,
|
||||
edge.right.transit_stop_y_rotation,
|
||||
0.0f);
|
||||
BuildingsData::building b;
|
||||
b.key = "road__" + line_key +
|
||||
"__transit_stop__" + itos(edge_no) +
|
||||
"__" + itos(j) + "__right__" +
|
||||
edge.right.transit_stop_type;
|
||||
b.id = edge.right.transit_stop_type;
|
||||
b.generated = true;
|
||||
b.line_name = line_key;
|
||||
b.key_hash = b.key.hash64();
|
||||
b.pattern_id = 0;
|
||||
b.xform = xform;
|
||||
b.worktime[0] = 0;
|
||||
b.worktime[1] = 23;
|
||||
create_building_structure(b);
|
||||
t += m;
|
||||
structures_generated++;
|
||||
}
|
||||
}
|
||||
return structures_generated;
|
||||
}
|
||||
void create_structures()
|
||||
{
|
||||
List<String> keys;
|
||||
RoadLinesData *rld = RoadLinesData::get_singleton();
|
||||
rld->get_road_lines_key_list(&keys);
|
||||
List<String>::Element *e = keys.front();
|
||||
print_line("create structures");
|
||||
print_line("road_lines: " + itos(keys.size()));
|
||||
int structures_generated = 0;
|
||||
while (e) {
|
||||
const String &key = e->get();
|
||||
int i;
|
||||
if (rld->lines(key).points.size() < 2) {
|
||||
e = e->next();
|
||||
continue;
|
||||
}
|
||||
if (rld->lines(key).edges.size() !=
|
||||
rld->lines(key).points.size() - 1) {
|
||||
e = e->next();
|
||||
continue;
|
||||
}
|
||||
print_line("line: " + key + " edges count: " +
|
||||
itos((int)rld->lines(key).edges.size()));
|
||||
for (i = 0; i < (int)rld->lines(key).edges.size();
|
||||
i++) {
|
||||
const RoadLinesData::road_edge &edge =
|
||||
rld->lines(key).edges[i];
|
||||
const Vector3 &p0 =
|
||||
rld->lines(key).points[i].origin;
|
||||
const Vector3 &p1 =
|
||||
rld->lines(key).points[i + 1].origin;
|
||||
Vector3 dir = (p1 - p0).normalized();
|
||||
Vector3 d = dir;
|
||||
Vector3 left_n = Vector3(0, 1, 0).cross(d);
|
||||
Vector3 right_n = -left_n;
|
||||
/* lots */
|
||||
structures_generated +=
|
||||
create_lots(key, i, edge, p0, p1, dir,
|
||||
left_n, right_n);
|
||||
/* sideroads */
|
||||
structures_generated +=
|
||||
create_sideroads(key, i, edge, p0, p1,
|
||||
dir, left_n, right_n);
|
||||
/* bus stops */
|
||||
structures_generated += create_transit_stops(
|
||||
key, i, edge, p0, p1, dir, left_n,
|
||||
right_n);
|
||||
}
|
||||
e = e->next();
|
||||
}
|
||||
print_line("structures generated: " +
|
||||
itos(structures_generated));
|
||||
}
|
||||
void create_edges()
|
||||
{
|
||||
int i;
|
||||
@@ -236,7 +559,7 @@ struct RoadLinesProcessing {
|
||||
if (Vector2(q.x, q.z)
|
||||
.distance_squared_to(
|
||||
Vector2(r.x, r.z)) <
|
||||
0.005f)
|
||||
0.1f)
|
||||
pr = q.linear_interpolate(r,
|
||||
0.5f);
|
||||
else {
|
||||
@@ -819,6 +1142,7 @@ RoadMeshProcessing *RoadMeshProcessing::singleton;
|
||||
|
||||
void RoadProcessing::road_setup(Node *target, int debug_flags)
|
||||
{
|
||||
RoadLinesProcessing::get_singleton()->create_structures();
|
||||
RoadLinesProcessing::get_singleton()->set_debug_flags(debug_flags);
|
||||
RoadLinesProcessing::get_singleton()->road_setup();
|
||||
RoadMeshProcessing::get_singleton()->create_road_meshes(target);
|
||||
|
||||
Reference in New Issue
Block a user