Update - fixed lots generation, now can save lots polygons
This commit is contained in:
@@ -10,7 +10,6 @@ env_stream.module_obj = []
|
||||
env_stream.Prepend(CPPPATH=["../../meshoptimizer/src"])
|
||||
env_stream.Prepend(CPPPATH=["event"])
|
||||
env_stream.add_source_files(env_stream.module_obj, "*.cpp")
|
||||
env_stream.add_source_files(env_stream.module_obj, "flecs/*.c")
|
||||
env.modules_sources += env_stream.module_obj
|
||||
|
||||
SConscript("buildings/SCsub")
|
||||
@@ -18,6 +17,7 @@ SConscript("rtree/SCsub")
|
||||
SConscript("ui/SCsub")
|
||||
SConscript("npc/SCsub")
|
||||
SConscript("event/SCsub")
|
||||
SConscript("flecs/SCsub")
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -181,7 +181,7 @@ void BuildingsData::read_buildings_json(const String &buildings_path)
|
||||
while (e) {
|
||||
struct building b;
|
||||
String key = e->get();
|
||||
if (!key.begins_with("road::")) {
|
||||
if (!key.begins_with("road::") && !key.begins_with("road__")) {
|
||||
Dictionary entry = json[key];
|
||||
String id = entry.get("id", "empty");
|
||||
if (id == "empty") {
|
||||
@@ -216,7 +216,7 @@ void BuildingsData::save_buildings_json(const String &buildings_path)
|
||||
ecs().each([&index, &json](const CBuildingData &b) {
|
||||
String key = b.building.key;
|
||||
/* do not save roadside generated stuff */
|
||||
if (!key.begins_with("road::")) {
|
||||
if (!key.begins_with("road::") && !key.begins_with("road__")) {
|
||||
Dictionary dict = b.building.to_dict();
|
||||
dict["index"] = index;
|
||||
json[key] = dict;
|
||||
@@ -712,7 +712,6 @@ const struct BuildingsData::building &
|
||||
BuildingsData::get_building(const String &building_key) const
|
||||
{
|
||||
String ename = "base:" + building_key;
|
||||
print_line("get_building: " + ename);
|
||||
flecs::entity e = lookup(ename);
|
||||
assert(e.is_valid());
|
||||
return e.get<CBuildingData>()->building;
|
||||
@@ -722,7 +721,6 @@ struct BuildingsData::building &
|
||||
BuildingsData::get_building(const String &building_key)
|
||||
{
|
||||
String ename = "base:" + building_key;
|
||||
print_line("get_building: " + ename);
|
||||
flecs::entity e = lookup(ename);
|
||||
assert(e.is_valid());
|
||||
return e.get_mut<CBuildingData>()->building;
|
||||
|
||||
12
src/modules/stream/event/SCsub
Normal file
12
src/modules/stream/event/SCsub
Normal file
@@ -0,0 +1,12 @@
|
||||
Import("env")
|
||||
Import("env_modules")
|
||||
|
||||
env_stream = env_modules.Clone()
|
||||
env_stream.stream_building_sources = []
|
||||
|
||||
env_stream.add_source_files(env_stream.stream_building_sources, "*.cpp")
|
||||
|
||||
lib = env_stream.add_library("event", env_stream.stream_building_sources)
|
||||
env.Append(LIBS=[lib])
|
||||
env_stream.Prepend(CPPPATH=[".."])
|
||||
env_stream.Prepend(CPPPATH=["../../../meshoptimizer/src"])
|
||||
32
src/modules/stream/event/editor_event.cpp
Normal file
32
src/modules/stream/event/editor_event.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
#undef NDEBUG
|
||||
#include <cassert>
|
||||
|
||||
#include "editor_event.h"
|
||||
|
||||
EditorEvent *EditorEvent::singleton = nullptr;
|
||||
|
||||
EditorEvent::EditorEvent()
|
||||
{
|
||||
}
|
||||
|
||||
EditorEvent::~EditorEvent()
|
||||
{
|
||||
}
|
||||
|
||||
EditorEvent *EditorEvent::get_singleton()
|
||||
{
|
||||
if (!singleton)
|
||||
singleton = memnew(EditorEvent);
|
||||
return singleton;
|
||||
}
|
||||
|
||||
void EditorEvent::EventHelper::emit(const String &event,
|
||||
const Vector<Variant> &args)
|
||||
{
|
||||
auto evl = listeners.begin();
|
||||
while (evl != listeners.end()) {
|
||||
const event_listener_ptrs &xev = *evl;
|
||||
xev.execute(event, args);
|
||||
evl++;
|
||||
}
|
||||
}
|
||||
81
src/modules/stream/event/editor_event.h
Normal file
81
src/modules/stream/event/editor_event.h
Normal file
@@ -0,0 +1,81 @@
|
||||
#ifndef EDITOR_EVENT_H
|
||||
#define EDITOR_EVENT_H
|
||||
#include <core/ustring.h>
|
||||
#include <list>
|
||||
class EditorEvent {
|
||||
public:
|
||||
class EventHelper {
|
||||
class event_listener_ptrs {
|
||||
public:
|
||||
class H {};
|
||||
H *obj;
|
||||
void (H::*method)(const String &event,
|
||||
const Vector<Variant> &args);
|
||||
void execute(const String &event,
|
||||
const Vector<Variant> &args) const
|
||||
{
|
||||
(obj->*method)(event, args);
|
||||
}
|
||||
};
|
||||
std::list<event_listener_ptrs> listeners;
|
||||
typedef event_listener_ptrs::H *obj_t;
|
||||
typedef void (event_listener_ptrs::H::*method_t)(
|
||||
const String &event, const Vector<Variant> &args);
|
||||
|
||||
public:
|
||||
template <class T>
|
||||
void
|
||||
add_listener(T *obj,
|
||||
void (T::*method)(const String &event,
|
||||
const Vector<Variant> &args));
|
||||
template <class T>
|
||||
void
|
||||
remove_listener(T *obj,
|
||||
void (T::*method)(const String &event,
|
||||
const Vector<Variant> &args));
|
||||
void emit(const String &event, const Vector<Variant> &args);
|
||||
};
|
||||
EventHelper event;
|
||||
|
||||
private:
|
||||
static EditorEvent *singleton;
|
||||
EditorEvent();
|
||||
virtual ~EditorEvent();
|
||||
|
||||
public:
|
||||
static EditorEvent *get_singleton();
|
||||
};
|
||||
template <class T>
|
||||
void EditorEvent::EventHelper::remove_listener(
|
||||
T *obj,
|
||||
void (T::*method)(const String &event, const Vector<Variant> &args))
|
||||
{
|
||||
listeners.remove_if([obj, method](const event_listener_ptrs &e) {
|
||||
return e.obj == reinterpret_cast<obj_t>(obj) &&
|
||||
e.method == reinterpret_cast<method_t>(method);
|
||||
});
|
||||
}
|
||||
template <class T>
|
||||
void EditorEvent::EventHelper::add_listener(
|
||||
T *obj,
|
||||
void (T::*method)(const String &event, const Vector<Variant> &args))
|
||||
{
|
||||
auto evl = listeners.begin();
|
||||
bool bad = false;
|
||||
while (evl != listeners.end()) {
|
||||
const event_listener_ptrs &xev = *evl;
|
||||
if (xev.obj == reinterpret_cast<obj_t>(obj) &&
|
||||
xev.method == reinterpret_cast<method_t>(method)) {
|
||||
bad = true;
|
||||
break;
|
||||
}
|
||||
evl++;
|
||||
}
|
||||
if (bad)
|
||||
return;
|
||||
event_listener_ptrs ev;
|
||||
ev.obj = reinterpret_cast<obj_t>(obj);
|
||||
ev.method = reinterpret_cast<method_t>(method);
|
||||
listeners.push_back(ev);
|
||||
}
|
||||
#endif
|
||||
31
src/modules/stream/event/game_event.cpp
Normal file
31
src/modules/stream/event/game_event.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#undef NDEBUG
|
||||
#include <cassert>
|
||||
|
||||
#include "game_event.h"
|
||||
GameEvent *GameEvent::singleton = nullptr;
|
||||
|
||||
GameEvent::GameEvent()
|
||||
{
|
||||
}
|
||||
|
||||
GameEvent::~GameEvent()
|
||||
{
|
||||
}
|
||||
|
||||
GameEvent *GameEvent::get_singleton()
|
||||
{
|
||||
if (!singleton)
|
||||
singleton = memnew(GameEvent);
|
||||
return singleton;
|
||||
}
|
||||
|
||||
void GameEvent::EventHelper::emit(const String &event,
|
||||
const Vector<Variant> &args)
|
||||
{
|
||||
auto evl = listeners.begin();
|
||||
while (evl != listeners.end()) {
|
||||
const event_listener_ptrs &xev = *evl;
|
||||
xev.execute(event, args);
|
||||
evl++;
|
||||
}
|
||||
}
|
||||
83
src/modules/stream/event/game_event.h
Normal file
83
src/modules/stream/event/game_event.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/* ~/godot-projects/streaming_world/src/modules/stream/game_event.h */
|
||||
#ifndef GAME_EVENT_H_
|
||||
#define GAME_EVENT_H_
|
||||
#include <core/ustring.h>
|
||||
#include <list>
|
||||
class GameEvent {
|
||||
public:
|
||||
class EventHelper {
|
||||
class event_listener_ptrs {
|
||||
public:
|
||||
class H {};
|
||||
H *obj;
|
||||
void (H::*method)(const String &event,
|
||||
const Vector<Variant> &args);
|
||||
void execute(const String &event,
|
||||
const Vector<Variant> &args) const
|
||||
{
|
||||
(obj->*method)(event, args);
|
||||
}
|
||||
};
|
||||
std::list<event_listener_ptrs> listeners;
|
||||
typedef event_listener_ptrs::H *obj_t;
|
||||
typedef void (event_listener_ptrs::H::*method_t)(
|
||||
const String &event, const Vector<Variant> &args);
|
||||
|
||||
public:
|
||||
template <class T>
|
||||
void
|
||||
add_listener(T *obj,
|
||||
void (T::*method)(const String &event,
|
||||
const Vector<Variant> &args));
|
||||
template <class T>
|
||||
void
|
||||
remove_listener(T *obj,
|
||||
void (T::*method)(const String &event,
|
||||
const Vector<Variant> &args));
|
||||
void emit(const String &event, const Vector<Variant> &args);
|
||||
};
|
||||
EventHelper event;
|
||||
|
||||
private:
|
||||
static GameEvent *singleton;
|
||||
GameEvent();
|
||||
virtual ~GameEvent();
|
||||
|
||||
public:
|
||||
static GameEvent *get_singleton();
|
||||
};
|
||||
template <class T>
|
||||
void GameEvent::EventHelper::remove_listener(
|
||||
T *obj,
|
||||
void (T::*method)(const String &event, const Vector<Variant> &args))
|
||||
{
|
||||
listeners.remove_if([obj, method](const event_listener_ptrs &e) {
|
||||
return e.obj == reinterpret_cast<obj_t>(obj) &&
|
||||
e.method == reinterpret_cast<method_t>(method);
|
||||
});
|
||||
}
|
||||
template <class T>
|
||||
void GameEvent::EventHelper::add_listener(
|
||||
T *obj,
|
||||
void (T::*method)(const String &event, const Vector<Variant> &args))
|
||||
{
|
||||
auto evl = listeners.begin();
|
||||
bool bad = false;
|
||||
while (evl != listeners.end()) {
|
||||
const event_listener_ptrs &xev = *evl;
|
||||
if (xev.obj == reinterpret_cast<obj_t>(obj) &&
|
||||
xev.method == reinterpret_cast<method_t>(method)) {
|
||||
bad = true;
|
||||
break;
|
||||
}
|
||||
evl++;
|
||||
}
|
||||
if (bad)
|
||||
return;
|
||||
event_listener_ptrs ev;
|
||||
ev.obj = reinterpret_cast<obj_t>(obj);
|
||||
ev.method = reinterpret_cast<method_t>(method);
|
||||
listeners.push_back(ev);
|
||||
}
|
||||
|
||||
#endif // GAME_EVENT_H_
|
||||
@@ -78,12 +78,86 @@ public:
|
||||
const struct CLine *cl = e.get<CLine>();
|
||||
return &cl->line;
|
||||
}
|
||||
inline struct RoadLinesData::road_line &get_line(const String &key)
|
||||
inline const struct RoadLinesData::road_edge &
|
||||
get_line_edge(const String &key, int edge) const
|
||||
{
|
||||
flecs::entity e = lookup(key);
|
||||
const struct CLine *cl = e.get<CLine>();
|
||||
return cl->line.edges[edge];
|
||||
}
|
||||
void set_line_edge(const String &key, int edge_id,
|
||||
const struct RoadLinesData::road_edge &edge)
|
||||
{
|
||||
flecs::entity e = lookup(key);
|
||||
struct CLine *cl = e.get_mut<CLine>();
|
||||
cl->line.edges[edge_id] = edge;
|
||||
e.modified<CLine>();
|
||||
}
|
||||
inline int get_line_edge_count(const String &key) const
|
||||
{
|
||||
flecs::entity e = lookup(key);
|
||||
const struct CLine *cl = e.get<CLine>();
|
||||
return cl->line.edges.size();
|
||||
}
|
||||
void
|
||||
set_line_edge_left(const String &key, int edge_id,
|
||||
const struct RoadLinesData::road_edge_side &side)
|
||||
{
|
||||
// print_line("set_line_edge_left: " + key + " " + itos(edge_id) +
|
||||
// " lot: " + itos(side.lot));
|
||||
flecs::entity e = lookup(key);
|
||||
struct CLine *cl = e.get_mut<CLine>();
|
||||
cl->line.edges[edge_id].left = side;
|
||||
e.modified<CLine>();
|
||||
cl = e.get_mut<CLine>();
|
||||
assert(cl->line.edges[edge_id].left.lot == side.lot);
|
||||
}
|
||||
void
|
||||
set_line_edge_right(const String &key, int edge_id,
|
||||
const struct RoadLinesData::road_edge_side &side)
|
||||
{
|
||||
// print_line("set_line_edge_right: " + key + " " + itos(edge_id) +
|
||||
// " lot: " + itos(side.lot));
|
||||
flecs::entity e = lookup(key);
|
||||
struct CLine *cl = e.get_mut<CLine>();
|
||||
cl->line.edges[edge_id].right = side;
|
||||
e.modified<CLine>();
|
||||
cl = e.get_mut<CLine>();
|
||||
assert(cl->line.edges[edge_id].right.lot == side.lot);
|
||||
}
|
||||
struct RoadLinesData::road_edge_side
|
||||
get_line_edge_left(const String &key, int edge_id) const
|
||||
{
|
||||
flecs::entity e = lookup(key);
|
||||
const struct CLine *cl = e.get<CLine>();
|
||||
return cl->line.edges[edge_id].left;
|
||||
}
|
||||
struct RoadLinesData::road_edge_side
|
||||
get_line_edge_right(const String &key, int edge_id) const
|
||||
{
|
||||
flecs::entity e = lookup(key);
|
||||
const struct CLine *cl = e.get<CLine>();
|
||||
return cl->line.edges[edge_id].right;
|
||||
}
|
||||
inline struct RoadLinesData::road_line get_line(const String &key)
|
||||
{
|
||||
flecs::entity e = lookup(key);
|
||||
const struct CLine *cl = e.get<CLine>();
|
||||
return cl->line;
|
||||
}
|
||||
inline const Transform &get_line_point_transform(const String &key,
|
||||
int point_index)
|
||||
{
|
||||
flecs::entity e = lookup(key);
|
||||
const struct CLine *cl = e.get<CLine>();
|
||||
return cl->line.points[point_index];
|
||||
}
|
||||
inline const Vector3 &get_line_point(const String &key, int point_index)
|
||||
{
|
||||
flecs::entity e = lookup(key);
|
||||
const struct CLine *cl = e.get<CLine>();
|
||||
return cl->line.points[point_index].origin;
|
||||
}
|
||||
inline const struct RoadLinesData::road_line &
|
||||
operator[](const String &key) const
|
||||
{
|
||||
@@ -99,6 +173,12 @@ public:
|
||||
CLine *cl = e.get_mut<CLine>();
|
||||
if (cl->line.edges.size() != cl->line.points.size() - 1)
|
||||
cl->line.edges.resize(cl->line.points.size() - 1);
|
||||
e.modified<CLine>();
|
||||
}
|
||||
void update_line(const String &key)
|
||||
{
|
||||
flecs::entity e = lookup_create(key);
|
||||
e.modified<CLine>();
|
||||
}
|
||||
inline void insert_line_point(const String &key, int index,
|
||||
const Transform &xform)
|
||||
@@ -294,6 +374,71 @@ RoadLinesData::get_line(const String &key) const
|
||||
{
|
||||
return ::lines[key];
|
||||
}
|
||||
const struct RoadLinesData::road_line *
|
||||
RoadLinesData::get_line_ptr(const String &key) const
|
||||
{
|
||||
return ::lines.get_line_ptr(key);
|
||||
}
|
||||
RoadLinesData::road_edge RoadLinesData::get_line_edge(const String &key,
|
||||
int edge) const
|
||||
{
|
||||
return ::lines.get_line_ptr(key)->edges[edge];
|
||||
}
|
||||
RoadLinesData::road_edge_side
|
||||
RoadLinesData::get_line_edge_left(const String &key, int edge) const
|
||||
{
|
||||
return ::lines.get_line_edge_left(key, edge);
|
||||
}
|
||||
RoadLinesData::road_edge_side
|
||||
RoadLinesData::get_line_edge_right(const String &key, int edge) const
|
||||
{
|
||||
return ::lines.get_line_edge_right(key, edge);
|
||||
}
|
||||
RoadLinesData::road_edge_side
|
||||
RoadLinesData::get_line_edge_side(const String &key, int edge, int side) const
|
||||
{
|
||||
switch (side) {
|
||||
case 0:
|
||||
return get_line_edge_left(key, edge);
|
||||
break;
|
||||
case 1:
|
||||
return get_line_edge_right(key, edge);
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
assert(false);
|
||||
/* should never happen */
|
||||
return RoadLinesData::road_edge_side(get_line_edge(key, edge));
|
||||
}
|
||||
void RoadLinesData::set_line_edge_left(const String &key, int edge,
|
||||
road_edge_side &side)
|
||||
{
|
||||
::lines.set_line_edge_left(key, edge, side);
|
||||
assert(::lines.get_line_edge(key, edge).left.lot == side.lot);
|
||||
}
|
||||
void RoadLinesData::set_line_edge_right(const String &key, int edge,
|
||||
road_edge_side &side)
|
||||
{
|
||||
::lines.set_line_edge_right(key, edge, side);
|
||||
assert(::lines.get_line_edge(key, edge).right.lot == side.lot);
|
||||
}
|
||||
void RoadLinesData::set_line_edge(const String &key, int edge_id,
|
||||
const road_edge &edge)
|
||||
{
|
||||
::lines.set_line_edge(key, edge_id, edge);
|
||||
assert(::lines.get_line_edge(key, edge_id).left.lot == edge.left.lot);
|
||||
assert(::lines.get_line_edge(key, edge_id).right.lot == edge.right.lot);
|
||||
}
|
||||
int RoadLinesData::get_line_edge_count(const String &key) const
|
||||
{
|
||||
return ::lines.get_line_edge_count(key);
|
||||
}
|
||||
const Vector3 &RoadLinesData::get_line_point(const String &key, int index) const
|
||||
{
|
||||
return ::lines.get_line_point(key, index);
|
||||
}
|
||||
const RoadLinesData::road_line &RoadLinesData::lines(const String &key) const
|
||||
{
|
||||
return ::lines[key];
|
||||
@@ -307,6 +452,15 @@ void RoadLinesData::set_line(const String &key, const road_line &line)
|
||||
{
|
||||
::lines.set_line(key, line);
|
||||
}
|
||||
void RoadLinesData::update_line(const String &key)
|
||||
{
|
||||
::lines.update_line(key);
|
||||
}
|
||||
const Transform &RoadLinesData::get_line_point_transform(const String &key,
|
||||
int index) const
|
||||
{
|
||||
return ::lines.get_line_point_transform(key, index);
|
||||
}
|
||||
bool RoadLinesData::has_line(const String &key)
|
||||
{
|
||||
return ::lines.has(key);
|
||||
@@ -446,6 +600,7 @@ void RoadLinesData::load_data()
|
||||
::lines.get_key_list(&tkeys);
|
||||
assert(!tkeys.empty());
|
||||
}
|
||||
update_line_edges();
|
||||
initialized = true;
|
||||
}
|
||||
void RoadLinesData::save_data()
|
||||
@@ -895,3 +1050,40 @@ Vector3 RoadLinesData::get_point_by_offsets(const String &line,
|
||||
print_verbose("data: " + (ret.operator String()));
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool RoadLinesData::road_edge_side::test(
|
||||
const struct RoadLinesData::test_edge &other)
|
||||
{
|
||||
float dst = Geometry::get_closest_distance_between_segments(
|
||||
test_p[0], test_p[1], other.p0, other.p1);
|
||||
if (dst < 4.0f) {
|
||||
print_line("dst: " + String::num(dst));
|
||||
print_line(test_p[0].operator String() + " " +
|
||||
test_p[1].operator String());
|
||||
print_line(other.p0.operator String() + " " +
|
||||
other.p1.operator String());
|
||||
print_line("index: " + itos(other.edge_index));
|
||||
return false;
|
||||
}
|
||||
if (other.left.lot > 0) {
|
||||
dst = Geometry::get_closest_distance_between_segments(
|
||||
test_p[0], test_p[1], other.left.test_p[0],
|
||||
other.left.test_p[1]);
|
||||
if (dst < 4.0f)
|
||||
return false;
|
||||
}
|
||||
if (other.right.lot > 0) {
|
||||
dst = Geometry::get_closest_distance_between_segments(
|
||||
test_p[0], test_p[1], other.right.test_p[0],
|
||||
other.right.test_p[1]);
|
||||
if (dst < 4.0f)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void RoadLinesData::road_edge_side::update_test_points(
|
||||
const RoadLinesData::road_edge &edge)
|
||||
{
|
||||
test_p[1] = test_p[0] + normal * lot_depth;
|
||||
}
|
||||
|
||||
@@ -27,7 +27,15 @@ public:
|
||||
};
|
||||
|
||||
public:
|
||||
struct test_edge;
|
||||
struct road_edge;
|
||||
struct road_line;
|
||||
struct road_edge_side {
|
||||
const RoadLinesData::road_edge &edge;
|
||||
Vector3 normal;
|
||||
Vector3 pmid[2];
|
||||
Vector3 pside[2];
|
||||
Vector3 test_p[2];
|
||||
int transit_stop_count;
|
||||
String transit_stop_type;
|
||||
float transit_stop_offset;
|
||||
@@ -45,6 +53,12 @@ public:
|
||||
float lot_y_offset;
|
||||
float lot_y_rotation;
|
||||
String lot_type;
|
||||
|
||||
float lot_depth;
|
||||
/* calculated */
|
||||
float lot_depth_eff;
|
||||
|
||||
public:
|
||||
struct buildings {
|
||||
String id;
|
||||
Vector3 offsets;
|
||||
@@ -97,6 +111,7 @@ public:
|
||||
ret["sideroad_y_rotation"] = sideroad_y_rotation;
|
||||
ret["sideroad_type"] = sideroad_type;
|
||||
ret["lot"] = lot;
|
||||
ret["lot_depth"] = lot_depth;
|
||||
ret["lot_offset"] = lot_offset;
|
||||
ret["lot_dir_offset"] = lot_dir_offset;
|
||||
ret["lot_y_offset"] = lot_y_offset;
|
||||
@@ -112,8 +127,9 @@ public:
|
||||
ret["lot_buildings"] = lot_buildings;
|
||||
return ret;
|
||||
}
|
||||
road_edge_side()
|
||||
: transit_stop_count(0)
|
||||
road_edge_side(const RoadLinesData::road_edge &edge)
|
||||
: edge(edge)
|
||||
, transit_stop_count(0)
|
||||
, transit_stop_type("")
|
||||
, transit_stop_offset(0.0f)
|
||||
, transit_stop_dir_offset(0.0f)
|
||||
@@ -130,6 +146,7 @@ public:
|
||||
, lot_y_offset(0.0f)
|
||||
, lot_y_rotation(0.0f)
|
||||
, lot_type(String(""))
|
||||
, lot_depth(100.0f)
|
||||
, buildings{}
|
||||
{
|
||||
}
|
||||
@@ -151,6 +168,7 @@ public:
|
||||
side.sideroad_y_rotation = dict["sideroad_y_rotation"];
|
||||
side.sideroad_type = dict["sideroad_type"];
|
||||
side.lot = dict["lot"];
|
||||
side.lot_depth = dict.get("lot_depth", 100.0f);
|
||||
side.lot_offset = dict["lot_offset"];
|
||||
side.lot_dir_offset = dict["lot_dir_offset"];
|
||||
side.lot_y_offset = dict["lot_y_offset"];
|
||||
@@ -169,6 +187,118 @@ public:
|
||||
parts[i]);
|
||||
}
|
||||
}
|
||||
bool test(const struct RoadLinesData::test_edge &other);
|
||||
void
|
||||
update_test_points(const struct RoadLinesData::road_edge &edge);
|
||||
struct RoadLinesData::road_edge_side &
|
||||
operator=(const struct RoadLinesData::road_edge_side &other)
|
||||
{
|
||||
if (this == &other)
|
||||
return *this;
|
||||
from_dict(*this, other.to_dict());
|
||||
pmid[0] = other.pmid[0];
|
||||
pmid[1] = other.pmid[1];
|
||||
pside[0] = other.pside[0];
|
||||
pside[1] = other.pside[1];
|
||||
normal = other.normal;
|
||||
test_p[0] = other.test_p[0];
|
||||
test_p[1] = other.test_p[1];
|
||||
lot_depth_eff = other.lot_depth_eff;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
struct test_edge {
|
||||
String line_key;
|
||||
int edge_index;
|
||||
int p0_index, p1_index;
|
||||
Vector3 p0, p1;
|
||||
struct road_edge_side left, right;
|
||||
test_edge(const String &key, int index)
|
||||
: line_key(key)
|
||||
, edge_index(index)
|
||||
, left(RoadLinesData::get_singleton()
|
||||
->lines(key)
|
||||
.edges[index])
|
||||
, right(RoadLinesData::get_singleton()
|
||||
->lines(key)
|
||||
.edges[index])
|
||||
{
|
||||
update_from_line();
|
||||
}
|
||||
bool operator==(const struct test_edge &other)
|
||||
{
|
||||
return line_key == other.line_key &&
|
||||
edge_index == other.edge_index;
|
||||
}
|
||||
void validate()
|
||||
{
|
||||
RoadLinesData *rld = RoadLinesData::get_singleton();
|
||||
RoadLinesData::road_edge edge =
|
||||
rld->get_line_edge(line_key, edge_index);
|
||||
if (edge.left.lot != left.lot) {
|
||||
print_line("key: " + line_key +
|
||||
" index: " + itos(edge_index));
|
||||
print_line("rl.edges[edge_index].left.lot = " +
|
||||
itos(edge.left.lot));
|
||||
print_line("left.lot = " + itos(left.lot));
|
||||
}
|
||||
if (edge.right.lot != right.lot) {
|
||||
print_line("key: " + line_key +
|
||||
" index: " + itos(edge_index));
|
||||
print_line("rl.edges[edge_index].right.lot = " +
|
||||
itos(edge.right.lot));
|
||||
print_line("right.lot = " + itos(right.lot));
|
||||
}
|
||||
assert(edge.left.lot == left.lot);
|
||||
assert(edge.left.lot_depth == left.lot_depth);
|
||||
assert(edge.right.lot == right.lot);
|
||||
assert(edge.right.lot_depth == right.lot_depth);
|
||||
}
|
||||
void update_from_line()
|
||||
{
|
||||
RoadLinesData *rld = RoadLinesData::get_singleton();
|
||||
RoadLinesData::road_edge edge =
|
||||
rld->get_line_edge(line_key, edge_index);
|
||||
print_line("line: " + line_key +
|
||||
" index: " + itos(edge_index) +
|
||||
" left.lot: " + itos(edge.left.lot) +
|
||||
" right.lot: " + itos(edge.right.lot));
|
||||
print_line(edge.left.pmid[0].operator String());
|
||||
print_line(edge.right.pmid[0].operator String());
|
||||
assert(edge.left.pmid[0].is_equal_approx(
|
||||
edge.right.pmid[0]));
|
||||
assert(edge.left.pmid[1].is_equal_approx(
|
||||
edge.right.pmid[1]));
|
||||
|
||||
left = edge.left;
|
||||
right = edge.right;
|
||||
left.normal = edge.left.normal;
|
||||
left.lot = edge.left.lot;
|
||||
left.lot_depth = edge.left.lot_depth;
|
||||
right.normal = edge.right.normal;
|
||||
right.lot = edge.right.lot;
|
||||
right.lot_depth = edge.right.lot_depth;
|
||||
validate();
|
||||
}
|
||||
void update_line()
|
||||
{
|
||||
print_line("update_line");
|
||||
RoadLinesData *rld = RoadLinesData::get_singleton();
|
||||
RoadLinesData::road_edge_side tmp_left =
|
||||
rld->get_line_edge_left(line_key, edge_index);
|
||||
RoadLinesData::road_edge_side tmp_right =
|
||||
rld->get_line_edge_right(line_key, edge_index);
|
||||
tmp_left.lot = left.lot;
|
||||
tmp_left.lot_depth = left.lot_depth;
|
||||
tmp_right.lot = right.lot;
|
||||
tmp_right.lot_depth = right.lot_depth;
|
||||
rld->set_line_edge_left(line_key, edge_index, tmp_left);
|
||||
rld->set_line_edge_right(line_key, edge_index,
|
||||
tmp_right);
|
||||
validate();
|
||||
rld->update_line_edges();
|
||||
validate();
|
||||
}
|
||||
};
|
||||
struct road_edge {
|
||||
struct road_edge_side left, right;
|
||||
@@ -188,10 +318,18 @@ public:
|
||||
road_edge_side::from_dict(edge.left, dleft);
|
||||
road_edge_side::from_dict(edge.right, dright);
|
||||
}
|
||||
road_edge()
|
||||
: left(*this)
|
||||
, right(*this)
|
||||
{
|
||||
}
|
||||
};
|
||||
struct road_line {
|
||||
std::vector<Transform> points;
|
||||
|
||||
std::vector<struct road_edge> edges;
|
||||
|
||||
public:
|
||||
std::vector<struct line_segment> segments;
|
||||
int lanes;
|
||||
int pattern;
|
||||
@@ -202,6 +340,50 @@ public:
|
||||
struct road_line_index {
|
||||
std::vector<int> indices;
|
||||
};
|
||||
void update_line_edges()
|
||||
{
|
||||
int edge_index;
|
||||
List<String> keys;
|
||||
get_road_lines_key_list(&keys);
|
||||
List<String>::Element *e = keys.front();
|
||||
while (e) {
|
||||
String key = e->get();
|
||||
// struct road_line rl = get_line(key);
|
||||
for (edge_index = 0;
|
||||
edge_index < get_line_edge_count(key);
|
||||
edge_index++) {
|
||||
const Vector3 &p0 =
|
||||
get_line_point(key, edge_index);
|
||||
const Vector3 &p1 =
|
||||
get_line_point(key, edge_index + 1);
|
||||
Vector3 dir = (p1 - p0).normalized();
|
||||
Vector3 d = dir;
|
||||
Vector3 left_n = Vector3(0, 1, 0).cross(d);
|
||||
Vector3 right_n = -left_n;
|
||||
RoadLinesData::road_edge tmp_edge =
|
||||
get_line_edge(key, edge_index);
|
||||
tmp_edge.left.normal = left_n;
|
||||
tmp_edge.right.normal = right_n;
|
||||
tmp_edge.left.pmid[0] = p0;
|
||||
tmp_edge.left.pmid[1] = p1;
|
||||
tmp_edge.right.pmid[0] = p0;
|
||||
tmp_edge.right.pmid[1] = p1;
|
||||
tmp_edge.left.test_p[0] = p0 + (p1 - p0) * 0.5f;
|
||||
tmp_edge.left.test_p[1] =
|
||||
tmp_edge.left.test_p[0] +
|
||||
tmp_edge.left.normal *
|
||||
tmp_edge.left.lot_depth;
|
||||
tmp_edge.right.test_p[0] =
|
||||
p0 + (p1 - p0) * 0.5f;
|
||||
tmp_edge.right.test_p[1] =
|
||||
tmp_edge.right.test_p[0] +
|
||||
tmp_edge.right.normal *
|
||||
tmp_edge.right.lot_depth;
|
||||
set_line_edge(key, edge_index, tmp_edge);
|
||||
}
|
||||
e = e->next();
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
static ImmediateGeometry *get_debug_node();
|
||||
@@ -214,6 +396,25 @@ public:
|
||||
const struct road_line &lines(const String &key) const;
|
||||
const struct road_line_index &indices(const String &key) const;
|
||||
void set_line(const String &key, const struct road_line &line);
|
||||
void update_line(const String &key);
|
||||
const struct road_line *get_line_ptr(const String &key) const;
|
||||
struct road_edge get_line_edge(const String &key, int edge) const;
|
||||
struct road_edge_side get_line_edge_left(const String &key,
|
||||
int edge) const;
|
||||
struct road_edge_side get_line_edge_right(const String &key,
|
||||
int edge) const;
|
||||
struct road_edge_side get_line_edge_side(const String &key, int edge,
|
||||
int side) const;
|
||||
void set_line_edge_left(const String &key, int edge,
|
||||
struct road_edge_side &side);
|
||||
void set_line_edge_right(const String &key, int edge,
|
||||
struct road_edge_side &side);
|
||||
void set_line_edge(const String &key, int edge_id,
|
||||
const struct road_edge &edge);
|
||||
int get_line_edge_count(const String &key) const;
|
||||
const Vector3 &get_line_point(const String &key, int index) const;
|
||||
const Transform &get_line_point_transform(const String &key,
|
||||
int index) const;
|
||||
bool has_line(const String &key);
|
||||
void insert_line_point(const String &key, int index,
|
||||
const Transform &xform);
|
||||
|
||||
@@ -589,6 +589,7 @@ void RoadLinesEditor::create_new_line_at_cursor(const String &line_name)
|
||||
assert(rld->has_line(line_name));
|
||||
update_line_index_ui();
|
||||
update_ui();
|
||||
rld->update_line_edges();
|
||||
}
|
||||
|
||||
void RoadLinesEditor::delete_current_line()
|
||||
@@ -599,6 +600,7 @@ void RoadLinesEditor::delete_current_line()
|
||||
rld->erase_line(delete_line);
|
||||
update_line_index_ui();
|
||||
update_ui();
|
||||
rld->update_line_edges();
|
||||
}
|
||||
|
||||
Vector3 RoadLinesEditor::get_cursor_position()
|
||||
@@ -1027,6 +1029,7 @@ void RoadLinesEditor::event_handler(const String &event,
|
||||
}
|
||||
RoadLinesData::road_edge::from_dict(rl.edges[index], data);
|
||||
rld->set_line(current_line, rl);
|
||||
rld->update_line_edges();
|
||||
print_line("Update for index: " + itos(index) + " done");
|
||||
}
|
||||
}
|
||||
@@ -1199,8 +1202,10 @@ class EdgeEditorHandler {
|
||||
void set_lot(RoadLinesData::road_edge_side &side, const String &pname,
|
||||
float dir_offt)
|
||||
{
|
||||
print_line("set_lot");
|
||||
side.lot_type = pname.replace("lot-", "");
|
||||
if (side.lot == 0) {
|
||||
print_line("set_lot 2");
|
||||
side.lot = 1;
|
||||
side.lot_offset = get_edge_conf<float>(pname, "left",
|
||||
"lot_offset");
|
||||
@@ -1278,7 +1283,6 @@ class EdgeEditorHandler {
|
||||
b.id = pname;
|
||||
b.offsets = Vector3();
|
||||
b.y_rotation = 0.0f;
|
||||
|
||||
rl.edges[index].left.buildings.push_back(b);
|
||||
if (rl.edges[index].left.lot > 0) {
|
||||
String lot_id =
|
||||
@@ -1307,6 +1311,8 @@ class EdgeEditorHandler {
|
||||
rl.edges[index].right.buildings.clear();
|
||||
}
|
||||
rld->set_line(current_line, rl);
|
||||
print_line("line updated: " + current_line);
|
||||
rld->update_line_edges();
|
||||
editor->rebuild_roads();
|
||||
} else if (event == "road_lines_edge_editor::menu::right") {
|
||||
PopupMenu *menu = Object::cast_to<PopupMenu>(args[0]);
|
||||
@@ -1358,6 +1364,8 @@ class EdgeEditorHandler {
|
||||
rl.edges[index].right.buildings.clear();
|
||||
}
|
||||
rld->set_line(current_line, rl);
|
||||
rld->update_line_edges();
|
||||
print_line("line updated: " + current_line);
|
||||
editor->rebuild_roads();
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,6 @@ void BuildingLayoutGraphUI::menu_pressed(int id, Control *button,
|
||||
const String &path)
|
||||
{
|
||||
assert(button);
|
||||
print_line(itos(id));
|
||||
print_line(path);
|
||||
switch (id) {
|
||||
case 100:
|
||||
@@ -459,7 +458,6 @@ static void *__PPP_ptr2 = nullptr;
|
||||
void BuildingLayoutGraphUI::command_entered(int index, Control *item,
|
||||
const String &path)
|
||||
{
|
||||
print_line(itos(index));
|
||||
flecs::world ecs = BaseData::get_singleton()->get();
|
||||
flecs::entity e = ecs.lookup(path.ascii().ptr());
|
||||
assert(e.is_valid());
|
||||
|
||||
Reference in New Issue
Block a user