Now road, terrain and buildings work fine

This commit is contained in:
2024-05-26 01:21:19 +03:00
parent d0db1e45a3
commit ab5f35eba1
20 changed files with 2625 additions and 649 deletions
Binary file not shown.
Binary file not shown.
+315
View File
@@ -0,0 +1,315 @@
{
"asset" : {
"generator" : "Khronos glTF Blender I/O v3.3.32",
"version" : "2.0"
},
"extensionsUsed" : [
"KHR_materials_specular",
"KHR_materials_ior"
],
"scene" : 0,
"scenes" : [
{
"name" : "Scene",
"nodes" : [
0,
1,
2
]
}
],
"nodes" : [
{
"mesh" : 0,
"name" : "road-lane-center"
},
{
"mesh" : 1,
"name" : "road-lane-mid",
"translation" : [
1.100000023841858,
0,
0
]
},
{
"mesh" : 2,
"name" : "roadd-sidewalk",
"translation" : [
2.200000047683716,
0,
0
]
}
],
"materials" : [
{
"extensions" : {
"KHR_materials_specular" : {
"specularColorFactor" : [
0.474271529955476,
0.474271529955476,
0.474271529955476
]
},
"KHR_materials_ior" : {
"ior" : 1.4500000476837158
}
},
"name" : "road-material",
"pbrMetallicRoughness" : {
"baseColorTexture" : {
"index" : 0
},
"metallicFactor" : 0.20000000298023224
}
}
],
"meshes" : [
{
"name" : "road-lane-center",
"primitives" : [
{
"attributes" : {
"POSITION" : 0,
"NORMAL" : 1,
"TEXCOORD_0" : 2
},
"indices" : 3,
"material" : 0
}
]
},
{
"name" : "road-lane-mid",
"primitives" : [
{
"attributes" : {
"POSITION" : 4,
"NORMAL" : 5,
"TEXCOORD_0" : 6
},
"indices" : 7,
"material" : 0
}
]
},
{
"name" : "road-sidewalk",
"primitives" : [
{
"attributes" : {
"POSITION" : 8,
"NORMAL" : 9,
"TEXCOORD_0" : 10
},
"indices" : 11,
"material" : 0
}
]
}
],
"textures" : [
{
"sampler" : 0,
"source" : 0
}
],
"images" : [
{
"mimeType" : "image/png",
"name" : "road",
"uri" : "road.png"
}
],
"accessors" : [
{
"bufferView" : 0,
"componentType" : 5126,
"count" : 32,
"max" : [
-8.847564458847046e-09,
0.12099996209144592,
5.960464477539063e-08
],
"min" : [
-0.9999999403953552,
-0.09999995678663254,
-0.5
],
"type" : "VEC3"
},
{
"bufferView" : 1,
"componentType" : 5126,
"count" : 32,
"type" : "VEC3"
},
{
"bufferView" : 2,
"componentType" : 5126,
"count" : 32,
"type" : "VEC2"
},
{
"bufferView" : 3,
"componentType" : 5123,
"count" : 48,
"type" : "SCALAR"
},
{
"bufferView" : 4,
"componentType" : 5126,
"count" : 80,
"max" : [
9.921204764395952e-07,
0.1214386522769928,
-6.735790520906448e-07
],
"min" : [
-0.9999990463256836,
-0.09999995678663254,
-0.5000007152557373
],
"type" : "VEC3"
},
{
"bufferView" : 5,
"componentType" : 5126,
"count" : 80,
"type" : "VEC3"
},
{
"bufferView" : 6,
"componentType" : 5126,
"count" : 80,
"type" : "VEC2"
},
{
"bufferView" : 7,
"componentType" : 5123,
"count" : 126,
"type" : "SCALAR"
},
{
"bufferView" : 8,
"componentType" : 5126,
"count" : 42,
"max" : [
2.5033950805664062e-05,
0.19999995827674866,
0
],
"min" : [
-1.100000023841858,
-0.10000000149011612,
-0.5
],
"type" : "VEC3"
},
{
"bufferView" : 9,
"componentType" : 5126,
"count" : 42,
"type" : "VEC3"
},
{
"bufferView" : 10,
"componentType" : 5126,
"count" : 42,
"type" : "VEC2"
},
{
"bufferView" : 11,
"componentType" : 5123,
"count" : 66,
"type" : "SCALAR"
}
],
"bufferViews" : [
{
"buffer" : 0,
"byteLength" : 384,
"byteOffset" : 0,
"target" : 34962
},
{
"buffer" : 0,
"byteLength" : 384,
"byteOffset" : 384,
"target" : 34962
},
{
"buffer" : 0,
"byteLength" : 256,
"byteOffset" : 768,
"target" : 34962
},
{
"buffer" : 0,
"byteLength" : 96,
"byteOffset" : 1024,
"target" : 34963
},
{
"buffer" : 0,
"byteLength" : 960,
"byteOffset" : 1120,
"target" : 34962
},
{
"buffer" : 0,
"byteLength" : 960,
"byteOffset" : 2080,
"target" : 34962
},
{
"buffer" : 0,
"byteLength" : 640,
"byteOffset" : 3040,
"target" : 34962
},
{
"buffer" : 0,
"byteLength" : 252,
"byteOffset" : 3680,
"target" : 34963
},
{
"buffer" : 0,
"byteLength" : 504,
"byteOffset" : 3932,
"target" : 34962
},
{
"buffer" : 0,
"byteLength" : 504,
"byteOffset" : 4436,
"target" : 34962
},
{
"buffer" : 0,
"byteLength" : 336,
"byteOffset" : 4940,
"target" : 34962
},
{
"buffer" : 0,
"byteLength" : 132,
"byteOffset" : 5276,
"target" : 34963
}
],
"samplers" : [
{
"magFilter" : 9729,
"minFilter" : 9987
}
],
"buffers" : [
{
"byteLength" : 5408,
"uri" : "road-lanes.bin"
}
]
}
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

+35
View File
@@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/road.png-fffb0f4010c0e3e4e2d8a7ecd084e72d.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://astream/road/road.png"
dest_files=[ "res://.import/road.png-fffb0f4010c0e3e4e2d8a7ecd084e72d.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
+3
View File
@@ -45,3 +45,6 @@ tile_size = 128
view_distance = 2 view_distance = 2
[road] [road]
road_lines_path = "res://astream/road_lines.json" road_lines_path = "res://astream/road_lines.json"
center_mesh = "res://astream/road/road-lanes_road-lane-center.mesh"
mid_mesh = "res://astream/road/road-lanes_road-lane-mid.mesh"
sidewalk_mesh = "res://astream/road/road-lanes_road-sidewalk.mesh"
+39
View File
@@ -0,0 +1,39 @@
name = "project"
skipFolders = [ "node_modules", ".vscode", "out", "dist", ".vscode-test" ]
skipFiles = [ ".gitignore", "package.json" ]
[[processes]]
id = "jpfqu4wnok04vkg1ojnhwl25"
name = "Todo"
[[processes.tasks]]
id = "q57b8pyb97wzlahuaxjttlan"
title = "Fix nodes close to edges"
description = "Check that node is too close to edge and split it"
tag = "backlog"
linkFiles = [ ]
dueDate = ""
checkList = [ ]
priority = ""
linkCommits = [ ]
[[processes.tasks]]
id = "xnxan65j063qs2wrvcquo8fc"
title = "Create building editing and road editing commands"
description = "Create building editing and road editing commands"
tag = "backlog"
linkFiles = [ ]
dueDate = ""
checkList = [ ]
priority = ""
linkCommits = [ ]
[[processes]]
id = "process2"
name = "In Progress"
tasks = [ ]
[[processes]]
id = "process3"
name = "Done"
tasks = [ ]
+2
View File
@@ -1,5 +1,6 @@
#include "register_types.h" #include "register_types.h"
#include "stream.h" #include "stream.h"
#include "road_debug.h"
void register_stream_types() void register_stream_types()
{ {
@@ -9,4 +10,5 @@ void register_stream_types()
void unregister_stream_types() void unregister_stream_types()
{ {
StreamWorld::cleanup();
} }
+26
View File
@@ -0,0 +1,26 @@
#include "road_debug.h"
AABB RoadDebug::get_aabb() const
{
return aabb;
}
PoolVector<Face3> RoadDebug::get_faces(uint32_t p_usage_flags) const
{
return PoolVector<Face3>();
}
RoadDebug::RoadDebug()
{
imm = VisualServer::get_singleton()->immediate_create();
set_base(imm);
material.instance();
material->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR,
true);
material->set_flag(SpatialMaterial::FLAG_DISABLE_DEPTH_TEST, true);
material->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
VisualServer::get_singleton()->immediate_set_material(
imm, material->get_rid());
}
RoadDebug::~RoadDebug()
{
VisualServer::get_singleton()->free(imm);
}
+18
View File
@@ -0,0 +1,18 @@
#ifndef ROAD_DEBUG_H_
#define ROAD_DEBUG_H_
#include <scene/3d/visual_instance.h>
class RoadDebug : public VisualInstance {
GDCLASS(RoadDebug, VisualInstance)
protected:
RID imm;
Ref<SpatialMaterial> material;
void _notification(int which);
AABB aabb;
public:
RoadDebug();
~RoadDebug();
virtual AABB get_aabb() const;
virtual PoolVector<Face3> get_faces(uint32_t p_usage_flags) const;
};
#endif
File diff suppressed because it is too large Load Diff
+10
View File
@@ -0,0 +1,10 @@
#ifndef ROAD_LINES_PROCESSING_H_
#define ROAD_LINES_PROCESSSING_H_
class Node;
class RoadProcessing {
public:
static void road_setup(Node *target);
static void load_data();
static void cleanup();
};
#endif
+9 -633
View File
@@ -5,10 +5,13 @@
#include <scene/main/viewport.h> #include <scene/main/viewport.h>
#include <scene/resources/packed_scene.h> #include <scene/resources/packed_scene.h>
#include <scene/resources/material.h> #include <scene/resources/material.h>
#include <scene/3d/mesh_instance.h>
#include <modules/voxel/terrain/voxel_viewer.h> #include <modules/voxel/terrain/voxel_viewer.h>
#include <modules/voxel/terrain/voxel_lod_terrain.h> #include <modules/voxel/terrain/voxel_lod_terrain.h>
#include "from_string.h" #include "from_string.h"
#include "road_processing.h"
#include "stream.h" #include "stream.h"
#include "road_debug.h"
void StreamWorld::read_buildings_json(const String &buildings_path) void StreamWorld::read_buildings_json(const String &buildings_path)
{ {
@@ -272,533 +275,6 @@ void StreamWorld::update_items()
} }
} }
struct RoadLinesProcessing {
struct road_line {
std::vector<Transform> points;
std::vector<int> indices;
int lanes;
int flags;
};
HashMap<String, struct road_line> road_lines;
std::vector<Vector3> nodes;
struct edgedata {
std::vector<int> neighbors;
};
std::unordered_map<int, struct edgedata> edges;
static struct RoadLinesProcessing *singleton;
static RoadLinesProcessing *get_singleton()
{
if (!singleton)
singleton = memnew(RoadLinesProcessing);
return singleton;
}
RoadLinesProcessing()
{
singleton = this;
}
uint32_t road_lines_hash(const Vector3 &v)
{
int x = (int)(v.x / 100);
int y = (int)(v.y / 100);
int z = (int)(v.z / 100);
return x ^ (y * 100) ^ (z * 10000);
}
void create_segments(const String &road, std::vector<int> &segments)
{
int i;
for (i = 0; i < (int)road_lines[road].indices.size() - 1; i++) {
int idx1 = road_lines[road].indices[i];
int idx2 = road_lines[road].indices[i + 1];
segments.push_back(idx1);
segments.push_back(idx2);
segments.push_back(i + 1);
}
}
void road_lines_curve_index(
struct road_line &rline,
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;
int pt_hash = road_lines_hash(pt);
if (road_lines_nodes_hash.find(pt_hash) !=
road_lines_nodes_hash.end()) {
bool ok = true;
for (j = 0;
j <
(int)road_lines_nodes_hash[pt_hash].size();
j++) {
const Vector3 &xpt =
road_lines_nodes_hash[pt_hash]
[j];
if (xpt.distance_squared_to(pt) < 160) {
ok = false;
pt = xpt;
break;
}
}
if (ok) {
road_lines_nodes_hash[pt_hash].push_back(
pt);
road_lines_nodes.push_back(pt);
}
} else {
road_lines_nodes.push_back(pt);
road_lines_nodes_hash[pt_hash] = { pt };
}
std::vector<Vector3>::iterator it =
std::find(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);
}
}
void index_lines(std::unordered_map<uint32_t, std::vector<Vector3> >
&road_lines_nodes_hash,
std::vector<Vector3> &road_lines_nodes)
{
List<String> keys;
road_lines.get_key_list(&keys);
List<String>::Element *e = keys.front();
while (e) {
String rkey = e->get();
struct road_line &pt = road_lines[rkey];
pt.indices.clear();
e = e->next();
}
e = keys.front();
while (e) {
String rkey = e->get();
struct road_line &pt = road_lines[rkey];
road_lines_curve_index(pt, road_lines_nodes_hash,
road_lines_nodes);
e = e->next();
}
#if 0
/* deduplicate */
e = keys.front();
while (e) {
String rkey = e->get();
std::vector<int> index;
struct road_line &pt = road_lines[rkey];
for (i = 0; i < (int)pt.indices.size() - 1; i++) {
int i1 = pt.indices[i];
if (i1 == 0)
index.push_back(i1);
int i2 = pt.indices[i + 1];
if (i1 != i2)
index.push_back(i2);
}
pt.indices = index;
e = e->next();
}
#endif
}
/* add close points on each line to the line */
void insert_close_points(std::vector<Vector3> &road_lines_nodes)
{
int i;
List<String> keys;
road_lines.get_key_list(&keys);
List<String>::Element *e = keys.front();
for (i = 0; i < (int)road_lines_nodes.size(); i++) {
int idx3 = i;
while (e) {
int j;
std::vector<int> segments;
String rkey = e->get();
create_segments(rkey, segments);
for (j = 0; j < (int)segments.size(); j += 3) {
int idx1 = segments[j];
int idx2 = segments[j + 1];
int idx = segments[j + 2];
/* Skip segment point */
if (idx3 == idx1 || idx3 == idx2)
continue;
Vector3 p1 = road_lines_nodes[idx1];
Vector3 p2 = road_lines_nodes[idx2];
Vector3 p3 = road_lines_nodes[idx3];
std::vector<Vector3> seg = { p1, p2 };
Vector3 closest = Geometry::
get_closest_point_to_segment(
p3, seg.data());
if (p3.distance_squared_to(closest) <
160) {
road_lines_nodes[idx3] =
closest;
road_lines[rkey].indices.insert(
road_lines[rkey].indices
.begin() +
idx,
idx3);
}
}
e = e->next();
}
}
}
void update_road_lines_nodes(std::vector<Vector3> &road_lines_nodes)
{
List<String> keys;
road_lines.get_key_list(&keys);
std::unordered_map<uint32_t, std::tuple<String, String> > kcmp;
{
List<String>::Element *k = keys.front();
List<String>::Element *r = keys.front();
while (k) {
String kkey = k->get();
uint32_t kkey_hash = kkey.hash();
while (r) {
String rkey = r->get();
uint32_t rkey_hash = rkey.hash();
uint32_t key = kkey_hash ^ rkey_hash;
uint32_t key2 = rkey_hash ^ kkey_hash;
if (kcmp.find(key) == kcmp.end() &&
kcmp.find(key2) == kcmp.end())
kcmp[key] = std::make_tuple(
k->get(), r->get());
r = r->next();
}
k = k->next();
}
}
/*
var checks = {}
for cmp in compare.values():
var k = cmp[0]
var r = cmp[1]
if road_lines[k].indices.size() < 2:
continue
if road_lines[r].indices.size() < 2:
continue
for i1 in range(road_lines[k].indices.size() - 1):
for j1 in range(road_lines[r].indices.size() - 1):
var key = k + str(i1) + "-" + r + str(j1)
var key2 = r + str(j1) + "-" + k + str(i1)
if !checks.has(key) && !checks.has(key2):
var idx_a1 = road_lines[k].indices[i1]
var idx_a2 = road_lines[k].indices[i1 + 1]
var idx_b1 = road_lines[r].indices[j1]
var idx_b2 = road_lines[r].indices[j1 + 1]
if idx_b1 in [idx_a1, idx_a2] || idx_b2 in [idx_a1, idx_a2]:
continue
checks[key] = [k, i1, idx_a1, idx_a2, r, j1, idx_b1, idx_b2]
*/
using checks_tuple =
std::tuple<String, int, int, int, String, int, int, int>;
std::unordered_map<uint32_t, checks_tuple> checks;
std::unordered_map<uint32_t, checks_tuple>::iterator checks_it;
std::unordered_map<uint32_t,
std::tuple<String, String> >::iterator it;
for (it = kcmp.begin(); it != kcmp.end(); it++) {
int i, j;
std::tuple<String, String> data = kcmp[it->first];
const String &k = std::get<0>(data);
const String &r = std::get<1>(data);
if (road_lines[k].indices.size() < 2)
continue;
if (road_lines[r].indices.size() < 2)
continue;
for (i = 0; i < (int)road_lines[k].indices.size() - 1;
i++) {
for (j = 0;
j < (int)road_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 =
road_lines[k].indices[i];
int idx_a2 =
road_lines[k]
.indices[i + 1];
int idx_b1 =
road_lines[k].indices[j];
int idx_b2 =
road_lines[k]
.indices[j + 1];
std::vector<int> cmp1 = {
idx_a1, idx_a2
};
if (std::find(cmp1.begin(),
cmp1.end(),
idx_b1) !=
cmp1.end())
continue;
if (std::find(cmp1.begin(),
cmp1.end(),
idx_b2) !=
cmp1.end())
continue;
checks[key] = std::make_tuple(
k, i, idx_a1, idx_a2, r,
j, idx_b1, idx_b2);
}
}
}
}
/*
for ch in checks.values():
var k = ch[0]
var i1 = ch[1]
var idx_a1 = ch[2]
var idx_a2 = ch[3]
var r = ch[4]
var j1 = ch[5]
var idx_b1 = ch[6]
var idx_b2 = ch[7]
var p_a1 = road_lines_nodes[idx_a1]
var p_a2 = road_lines_nodes[idx_a2]
var p_b1 = road_lines_nodes[idx_b1]
var p_b2 = road_lines_nodes[idx_b2]
var px = Geometry.get_closest_points_between_segments(p_a1, p_a2, p_b1, p_b2)
var d = px[0].distance_squared_to(px[1])
if d < 160:
var pxt = px[0].linear_interpolate(px[1], 0.5)
var nidx = road_lines_nodes.size()
road_lines_nodes.push_back(pxt)
var il = road_lines[k].indices.size()
assert(!nidx in road_lines[k].indices)
assert(!nidx in road_lines[r].indices)
road_lines[k].indices.insert(i1 + 1, nidx)
road_lines[r].indices.insert(j1 + 1, nidx)
##end
*/
for (checks_it = checks.begin(); checks_it != checks.end();
checks_it++) {
String k = std::get<0>(checks_it->second);
int i = std::get<1>(checks_it->second);
int idx_a1 = std::get<2>(checks_it->second);
int idx_a2 = std::get<3>(checks_it->second);
String r = std::get<4>(checks_it->second);
int j = std::get<5>(checks_it->second);
int idx_b1 = std::get<6>(checks_it->second);
int idx_b2 = std::get<7>(checks_it->second);
Vector3 p_a1 = road_lines_nodes[idx_a1];
Vector3 p_a2 = road_lines_nodes[idx_a2];
Vector3 p_b1 = road_lines_nodes[idx_b1];
Vector3 p_b2 = road_lines_nodes[idx_b2];
Vector3 px, px2;
Geometry::get_closest_points_between_segments(
p_a1, p_a2, p_b1, p_b2, px, px2);
float d = px.distance_squared_to(px2);
if (d < 160) {
Vector3 pxt = px.linear_interpolate(px2, 0.5f);
int nidx = road_lines_nodes.size();
road_lines_nodes.push_back(pxt);
// int il = (int)road_lines[k].indices.size();
assert(std::find(road_lines[k].indices.begin(),
road_lines[k].indices.end(),
nidx) ==
road_lines[k].indices.end());
assert(std::find(road_lines[r].indices.begin(),
road_lines[r].indices.end(),
nidx) ==
road_lines[r].indices.end());
road_lines[k].indices.insert(
road_lines[k].indices.begin() + i + 1,
nidx);
road_lines[r].indices.insert(
road_lines[k].indices.begin() + j + 1,
nidx);
}
}
/*
var nodes = []
var edges = {}
for n in road_lines_nodes:
# var pn = Vector3(n.x, n.y - 20.0, n.z)
var ndata = var2str(n)
nodes.push_back(ndata)
for k in road_lines.keys():
if road_lines[k].indices.size() < 2:
continue
for l in range(road_lines[k].indices.size() - 1):
var idx1 = road_lines[k].indices[l]
var idx2 = road_lines[k].indices[l + 1]
if !edges.has(str(idx1)):
edges[str(idx1)] = {"neighbors": []}
if !edges.has(str(idx2)):
edges[str(idx2)] = {"neighbors": []}
if !idx2 in edges[str(idx1)].neighbors:
edges[str(idx1)].neighbors.push_back(idx2)
if !idx1 in edges[str(idx2)].neighbors:
edges[str(idx2)].neighbors.push_back(idx1)
var road_nodes = SceneComps.get_component("road_nodes")
var ndebug = {
"nodes": nodes,
"edges": edges
}
# print(ndebug)
## assert(false)
road_nodes.roads_data.nodes = nodes
road_nodes.roads_data.edges = edges
# print(nodes)
# print(edges)
# print(road_nodes.roads_data.nodes)
*/
}
void create_nodes(const std::vector<Vector3> &road_lines_nodes)
{
nodes.resize(road_lines_nodes.size());
memcpy(nodes.data(), road_lines_nodes.data(),
sizeof(Vector3) * road_lines_nodes.size());
}
void create_edges()
{
int i;
List<String> keys;
road_lines.get_key_list(&keys);
List<String>::Element *e = keys.front();
while (e) {
const String &key = e->get();
if (road_lines[key].indices.size() < 2) {
e = e->next();
continue;
}
for (i = 0; i < (int)road_lines[key].indices.size() - 1;
i++) {
int idx1 = road_lines[key].indices[i];
int idx2 = road_lines[key].indices[i + 1];
if (edges.find(idx1) == edges.end()) {
struct edgedata ed;
ed.neighbors.clear();
edges[idx1] = ed;
}
if (edges.find(idx2) == edges.end()) {
struct edgedata ed;
ed.neighbors.clear();
edges[idx2] = ed;
}
if (std::find(edges[idx1].neighbors.begin(),
edges[idx1].neighbors.end(),
idx2) ==
edges[idx1].neighbors.end())
edges[idx1].neighbors.push_back(idx2);
if (std::find(edges[idx2].neighbors.begin(),
edges[idx2].neighbors.end(),
idx1) ==
edges[idx2].neighbors.end())
edges[idx2].neighbors.push_back(idx1);
}
e = e->next();
}
}
void create_road_from_lines()
{
}
void dump_lines(const std::vector<Vector3> &road_lines_nodes)
{
int i;
List<String> keys;
road_lines.get_key_list(&keys);
List<String>::Element *e = keys.front();
while (e) {
String rkey = e->get();
struct road_line &pt = road_lines[rkey];
String outline = rkey + ": ";
for (i = 0; i < (int)pt.indices.size(); i++) {
outline += " " + itos(pt.indices[i]);
}
for (i = 0; i < (int)pt.indices.size(); i++) {
outline +=
" " + (road_lines_nodes[pt.indices[i]]
.operator String());
}
print_line(outline);
e = e->next();
}
}
void road_setup()
{
std::vector<Vector3> road_lines_nodes;
std::unordered_map<uint32_t, std::vector<Vector3> >
road_lines_nodes_hash;
print_line("ROAD SETUP");
road_lines_nodes.clear();
road_lines_nodes_hash.clear();
index_lines(road_lines_nodes_hash, road_lines_nodes);
insert_close_points(road_lines_nodes);
update_road_lines_nodes(road_lines_nodes);
dump_lines(road_lines_nodes);
create_nodes(road_lines_nodes);
create_edges();
print_line("NODES:" + itos(nodes.size()));
print_line("EDGES:" + itos(edges.size()));
create_road_from_lines();
print_line("ROAD SETUP DONE");
}
void read_road_lines_json(const String &road_lines_path)
{
int i;
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();
if (!key.ends_with("_road")) {
e = e->next();
continue;
}
struct road_line rline;
Array points = json[key].get("points");
Array indices = json[key].get("indices");
int lanes = json[key].get("lanes");
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;
road_lines[key] = rline;
print_line("added line: " + key +
" nodes: " + itos(rline.points.size()) +
" " + itos(rline.indices.size()) +
" lanes: " + itos(rline.lanes));
e = e->next();
}
}
};
RoadLinesProcessing *RoadLinesProcessing::singleton;
void StreamWorld::_notification(int which) void StreamWorld::_notification(int which)
{ {
switch (which) { switch (which) {
@@ -814,7 +290,7 @@ void StreamWorld::_notification(int which)
else else
current_scene = get_tree()->get_current_scene(); current_scene = get_tree()->get_current_scene();
ERR_FAIL_COND_MSG(!current_scene, "No current scene"); ERR_FAIL_COND_MSG(!current_scene, "No current scene");
RoadLinesProcessing::get_singleton()->road_setup(); RoadProcessing::road_setup(this);
set_process(true); set_process(true);
} }
break; break;
@@ -886,10 +362,7 @@ StreamWorld::StreamWorld()
} }
String buildings_path = config.get_value("buildings", "buildings_path"); String buildings_path = config.get_value("buildings", "buildings_path");
read_buildings_json(buildings_path); read_buildings_json(buildings_path);
String road_lines_path = config.get_value("road", "road_lines_path"); RoadProcessing::load_data();
RoadLinesProcessing::get_singleton()->read_road_lines_json(
road_lines_path);
world_extent = config.get_value("world", "world_extent"); world_extent = config.get_value("world", "world_extent");
tile_size = config.get_value("world", "tile_size"); tile_size = config.get_value("world", "tile_size");
ERR_FAIL_COND_MSG(tile_size <= 0 || world_extent <= 0 || ERR_FAIL_COND_MSG(tile_size <= 0 || world_extent <= 0 ||
@@ -908,108 +381,11 @@ StreamWorld::StreamWorld()
view_distance = config.get_value("world", "view_distance"); view_distance = config.get_value("world", "view_distance");
initialized = true; initialized = true;
} }
void StreamWorld::cleanup()
void RoadDebug::_notification(int which)
{ {
int i; RoadProcessing::cleanup();
RoadLinesProcessing *r = RoadLinesProcessing::get_singleton();
std::unordered_map<int, RoadLinesProcessing::edgedata>::iterator it;
switch (which) {
case NOTIFICATION_ENTER_TREE:
set_process(true);
break;
case NOTIFICATION_PROCESS:
if (r->nodes.size() > 0 && r->edges.size() > 0) {
VisualServer::get_singleton()->immediate_clear(imm);
VisualServer::get_singleton()->immediate_begin(
imm, VisualServer::PRIMITIVE_LINES, RID());
VisualServer::get_singleton()->immediate_color(
imm, Color(1.0f, 0.6f, 0.6f, 1.0f));
for (it = r->edges.begin(); it != r->edges.end();
it++) {
int idx1 = it->first;
if (it == r->edges.begin()) {
aabb.position = r->nodes[idx1];
aabb.size = Vector3();
} else
aabb.expand_to(r->nodes[idx1]);
struct RoadLinesProcessing::edgedata data =
it->second;
for (i = 0; i < (int)data.neighbors.size();
i++) {
int idx2 = data.neighbors[i];
aabb.expand_to(r->nodes[idx2]);
Vector3 d = (r->nodes[idx2] -
r->nodes[idx1])
.normalized() *
0.5f;
VisualServer::get_singleton()
->immediate_vertex(
imm,
r->nodes[idx1] + d);
VisualServer::get_singleton()
->immediate_vertex(
imm,
r->nodes[idx2] - d);
print_line(
"draw line: " + itos(idx1) +
" " + itos(idx2) +
(r->nodes[idx1]
.operator String()) +
" " +
(r->nodes[idx2]
.operator String()));
}
}
VisualServer::get_singleton()->immediate_color(
imm, Color(0.6f, 0.6f, 1.0f, 1.0f));
for (it = r->edges.begin(); it != r->edges.end();
it++) {
int idx1 = it->first;
VisualServer::get_singleton()->immediate_vertex(
imm,
r->nodes[idx1] - Vector3(0, 10, 0));
VisualServer::get_singleton()->immediate_vertex(
imm,
r->nodes[idx1] + Vector3(0, 100, 0));
}
VisualServer::get_singleton()->immediate_color(
imm, Color(0.6f, 1.0f, 0.6f, 1.0f));
for (i = 0; i < (int)r->nodes.size(); i++) {
VisualServer::get_singleton()->immediate_vertex(
imm, r->nodes[i] - Vector3(0, 5, 0));
VisualServer::get_singleton()->immediate_vertex(
imm, r->nodes[i] + Vector3(0, 80, 0));
}
VisualServer::get_singleton()->immediate_end(imm);
set_process(false);
}
break;
case NOTIFICATION_EXIT_TREE:
break;
}
} }
AABB RoadDebug::get_aabb() const StreamWorld::~StreamWorld()
{ {
return aabb; RoadProcessing::cleanup();
}
PoolVector<Face3> RoadDebug::get_faces(uint32_t p_usage_flags) const
{
return PoolVector<Face3>();
}
RoadDebug::RoadDebug()
{
imm = VisualServer::get_singleton()->immediate_create();
set_base(imm);
material.instance();
material->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR,
true);
material->set_flag(SpatialMaterial::FLAG_DISABLE_DEPTH_TEST, true);
material->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
VisualServer::get_singleton()->immediate_set_material(
imm, material->get_rid());
}
RoadDebug::~RoadDebug()
{
VisualServer::get_singleton()->free(imm);
} }
+2 -15
View File
@@ -5,7 +5,6 @@
#include <tuple> #include <tuple>
#include <algorithm> #include <algorithm>
#include <scene/3d/spatial.h> #include <scene/3d/spatial.h>
#include <scene/3d/visual_instance.h>
class VoxelViewer; class VoxelViewer;
class VoxelLodTerrain; class VoxelLodTerrain;
class StreamWorld : public Spatial { class StreamWorld : public Spatial {
@@ -62,19 +61,7 @@ private:
public: public:
StreamWorld(); StreamWorld();
}; ~StreamWorld();
class RoadDebug : public VisualInstance { static void cleanup();
GDCLASS(RoadDebug, VisualInstance)
protected:
RID imm;
Ref<SpatialMaterial> material;
void _notification(int which);
AABB aabb;
public:
RoadDebug();
~RoadDebug();
virtual AABB get_aabb() const;
virtual PoolVector<Face3> get_faces(uint32_t p_usage_flags) const;
}; };
#endif #endif