Quality of life in procedural town creation improved

This commit is contained in:
2025-02-13 14:41:53 +03:00
parent b56103930c
commit 2eed8ef509
59 changed files with 8150 additions and 88 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 341 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 341 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 341 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 341 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 276 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 437 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 517 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,153 @@
{
"asset":{
"generator":"Khronos glTF Blender I/O v3.6.28",
"version":"2.0"
},
"extensionsUsed":[
"KHR_materials_specular",
"KHR_materials_ior"
],
"scene":0,
"scenes":[
{
"name":"Scene",
"nodes":[
0
]
}
],
"nodes":[
{
"mesh":0,
"name":"terrain-parking-lot-col"
}
],
"materials":[
{
"alphaCutoff":0.5,
"alphaMode":"MASK",
"extensions":{
"KHR_materials_specular":{
"specularColorFactor":[
0.474271529955476,
0.474271529955476,
0.474271529955476
]
},
"KHR_materials_ior":{
"ior":1.4500000476837158
}
},
"name":"material_atlas_36953_1",
"pbrMetallicRoughness":{
"baseColorTexture":{
"index":0
},
"metallicFactor":0
}
}
],
"meshes":[
{
"name":"Plane",
"primitives":[
{
"attributes":{
"POSITION":0,
"NORMAL":1,
"TEXCOORD_0":2
},
"indices":3,
"material":0
}
]
}
],
"textures":[
{
"sampler":0,
"source":0
}
],
"images":[
{
"mimeType":"image/png",
"name":"Atlas_36953",
"uri":"Atlas_36953.png"
}
],
"accessors":[
{
"bufferView":0,
"componentType":5126,
"count":250,
"max":[
25.032987594604492,
0.3288002610206604,
49.057586669921875
],
"min":[
-25.032987594604492,
-4.005487442016602,
-37.008201599121094
],
"type":"VEC3"
},
{
"bufferView":1,
"componentType":5126,
"count":250,
"type":"VEC3"
},
{
"bufferView":2,
"componentType":5126,
"count":250,
"type":"VEC2"
},
{
"bufferView":3,
"componentType":5123,
"count":474,
"type":"SCALAR"
}
],
"bufferViews":[
{
"buffer":0,
"byteLength":3000,
"byteOffset":0,
"target":34962
},
{
"buffer":0,
"byteLength":3000,
"byteOffset":3000,
"target":34962
},
{
"buffer":0,
"byteLength":2000,
"byteOffset":6000,
"target":34962
},
{
"buffer":0,
"byteLength":948,
"byteOffset":8000,
"target":34963
}
],
"samplers":[
{
"magFilter":9729,
"minFilter":9987
}
],
"buffers":[
{
"byteLength":8948,
"uri":"terrain-lot1.bin"
}
]
}

Binary file not shown.

View File

@@ -10018,8 +10018,8 @@
"lot_dir_offset": 37.336308,
"lot_y_offset": 0,
"lot_y_rotation": -90,
"lot_type": "small1",
"lot_buildings": ""
"lot_type": "small0",
"lot_buildings": ":0, 0, 0:0"
},
"right": {
"transit_stop_count": 1,
@@ -10038,8 +10038,8 @@
"lot_dir_offset": 37.336308,
"lot_y_offset": 0,
"lot_y_rotation": 90,
"lot_type": "small1",
"lot_buildings": ""
"lot_type": "small0",
"lot_buildings": ":0, 0, 0:0"
}
},
{
@@ -10056,11 +10056,11 @@
"sideroad_y_rotation": 0,
"sideroad_type": "Null",
"lot": 1,
"lot_offset": 18.799999,
"lot_dir_offset": -8,
"lot_offset": 27,
"lot_dir_offset": 0.5,
"lot_y_offset": 0,
"lot_y_rotation": -90,
"lot_type": "small1",
"lot_y_rotation": 0,
"lot_type": "small0",
"lot_buildings": ":0, 0, 0:0"
},
"right": {
@@ -10077,10 +10077,10 @@
"sideroad_type": "Null",
"lot": 1,
"lot_offset": 35,
"lot_dir_offset": -10,
"lot_dir_offset": 0,
"lot_y_offset": 0.1,
"lot_y_rotation": 90,
"lot_type": "small1",
"lot_type": "small0",
"lot_buildings": ":0, 0, 0:0"
}
},
@@ -10691,7 +10691,7 @@
"lot_y_offset": 0,
"lot_y_rotation": -90,
"lot_type": "",
"lot_buildings": ""
"lot_buildings": ":0, 0, 0:0"
},
"right": {
"transit_stop_count": 0,
@@ -10711,7 +10711,7 @@
"lot_y_offset": 0,
"lot_y_rotation": 90,
"lot_type": "",
"lot_buildings": ""
"lot_buildings": ":0, 0, 0:0"
}
},
{

Binary file not shown.

View File

@@ -0,0 +1,153 @@
{
"asset":{
"generator":"Khronos glTF Blender I/O v3.6.28",
"version":"2.0"
},
"extensionsUsed":[
"KHR_materials_specular",
"KHR_materials_ior"
],
"scene":0,
"scenes":[
{
"name":"Scene",
"nodes":[
0
]
}
],
"nodes":[
{
"mesh":0,
"name":"terrain-col"
}
],
"materials":[
{
"alphaCutoff":0.5,
"alphaMode":"MASK",
"extensions":{
"KHR_materials_specular":{
"specularColorFactor":[
0.474271529955476,
0.474271529955476,
0.474271529955476
]
},
"KHR_materials_ior":{
"ior":1.4500000476837158
}
},
"name":"material_atlas_36953_1",
"pbrMetallicRoughness":{
"baseColorTexture":{
"index":0
},
"metallicFactor":0
}
}
],
"meshes":[
{
"name":"Plane",
"primitives":[
{
"attributes":{
"POSITION":0,
"NORMAL":1,
"TEXCOORD_0":2
},
"indices":3,
"material":0
}
]
}
],
"textures":[
{
"sampler":0,
"source":0
}
],
"images":[
{
"mimeType":"image/png",
"name":"Atlas_36953",
"uri":"Atlas_36953.png"
}
],
"accessors":[
{
"bufferView":0,
"componentType":5126,
"count":315,
"max":[
99.999267578125,
0.30028849840164185,
99.77977752685547
],
"min":[
-99.84414672851562,
-4.802618026733398,
-99.61351013183594
],
"type":"VEC3"
},
{
"bufferView":1,
"componentType":5126,
"count":315,
"type":"VEC3"
},
{
"bufferView":2,
"componentType":5126,
"count":315,
"type":"VEC2"
},
{
"bufferView":3,
"componentType":5123,
"count":552,
"type":"SCALAR"
}
],
"bufferViews":[
{
"buffer":0,
"byteLength":3780,
"byteOffset":0,
"target":34962
},
{
"buffer":0,
"byteLength":3780,
"byteOffset":3780,
"target":34962
},
{
"buffer":0,
"byteLength":2520,
"byteOffset":7560,
"target":34962
},
{
"buffer":0,
"byteLength":1104,
"byteOffset":10080,
"target":34963
}
],
"samplers":[
{
"magFilter":9729,
"minFilter":9987
}
],
"buffers":[
{
"byteLength":11184,
"uri":"lot-large1.bin"
}
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,5 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://astream/terrain/details/lot-large1.gltf" type="PackedScene" id=1]
[node name="lot-large1" instance=ExtResource( 1 )]

Binary file not shown.

View File

@@ -0,0 +1,153 @@
{
"asset":{
"generator":"Khronos glTF Blender I/O v3.6.28",
"version":"2.0"
},
"extensionsUsed":[
"KHR_materials_specular",
"KHR_materials_ior"
],
"scene":0,
"scenes":[
{
"name":"Scene",
"nodes":[
0
]
}
],
"nodes":[
{
"mesh":0,
"name":"terrain-col"
}
],
"materials":[
{
"alphaCutoff":0.5,
"alphaMode":"MASK",
"extensions":{
"KHR_materials_specular":{
"specularColorFactor":[
0.474271529955476,
0.474271529955476,
0.474271529955476
]
},
"KHR_materials_ior":{
"ior":1.4500000476837158
}
},
"name":"material_atlas_36953_1",
"pbrMetallicRoughness":{
"baseColorTexture":{
"index":0
},
"metallicFactor":0
}
}
],
"meshes":[
{
"name":"Plane",
"primitives":[
{
"attributes":{
"POSITION":0,
"NORMAL":1,
"TEXCOORD_0":2
},
"indices":3,
"material":0
}
]
}
],
"textures":[
{
"sampler":0,
"source":0
}
],
"images":[
{
"mimeType":"image/png",
"name":"Atlas_36953",
"uri":"Atlas_36953.png"
}
],
"accessors":[
{
"bufferView":0,
"componentType":5126,
"count":315,
"max":[
199.999267578125,
0.30028849840164185,
199.77978515625
],
"min":[
-199.84414672851562,
-4.802618026733398,
-199.61351013183594
],
"type":"VEC3"
},
{
"bufferView":1,
"componentType":5126,
"count":315,
"type":"VEC3"
},
{
"bufferView":2,
"componentType":5126,
"count":315,
"type":"VEC2"
},
{
"bufferView":3,
"componentType":5123,
"count":552,
"type":"SCALAR"
}
],
"bufferViews":[
{
"buffer":0,
"byteLength":3780,
"byteOffset":0,
"target":34962
},
{
"buffer":0,
"byteLength":3780,
"byteOffset":3780,
"target":34962
},
{
"buffer":0,
"byteLength":2520,
"byteOffset":7560,
"target":34962
},
{
"buffer":0,
"byteLength":1104,
"byteOffset":10080,
"target":34963
}
],
"samplers":[
{
"magFilter":9729,
"minFilter":9987
}
],
"buffers":[
{
"byteLength":11184,
"uri":"lot-large2.bin"
}
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,5 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://astream/terrain/details/lot-large2.gltf" type="PackedScene" id=1]
[node name="lot-large2" instance=ExtResource( 1 )]

Binary file not shown.

View File

@@ -0,0 +1,153 @@
{
"asset":{
"generator":"Khronos glTF Blender I/O v3.6.28",
"version":"2.0"
},
"extensionsUsed":[
"KHR_materials_specular",
"KHR_materials_ior"
],
"scene":0,
"scenes":[
{
"name":"Scene",
"nodes":[
0
]
}
],
"nodes":[
{
"mesh":0,
"name":"terrain-col"
}
],
"materials":[
{
"alphaCutoff":0.5,
"alphaMode":"MASK",
"extensions":{
"KHR_materials_specular":{
"specularColorFactor":[
0.474271529955476,
0.474271529955476,
0.474271529955476
]
},
"KHR_materials_ior":{
"ior":1.4500000476837158
}
},
"name":"material_atlas_36953_1",
"pbrMetallicRoughness":{
"baseColorTexture":{
"index":0
},
"metallicFactor":0
}
}
],
"meshes":[
{
"name":"Plane",
"primitives":[
{
"attributes":{
"POSITION":0,
"NORMAL":1,
"TEXCOORD_0":2
},
"indices":3,
"material":0
}
]
}
],
"textures":[
{
"sampler":0,
"source":0
}
],
"images":[
{
"mimeType":"image/png",
"name":"Atlas_36953",
"uri":"Atlas_36953.png"
}
],
"accessors":[
{
"bufferView":0,
"componentType":5126,
"count":315,
"max":[
29.999271392822266,
0.30028843879699707,
29.77977752685547
],
"min":[
-29.844146728515625,
-4.802618026733398,
-29.613506317138672
],
"type":"VEC3"
},
{
"bufferView":1,
"componentType":5126,
"count":315,
"type":"VEC3"
},
{
"bufferView":2,
"componentType":5126,
"count":315,
"type":"VEC2"
},
{
"bufferView":3,
"componentType":5123,
"count":552,
"type":"SCALAR"
}
],
"bufferViews":[
{
"buffer":0,
"byteLength":3780,
"byteOffset":0,
"target":34962
},
{
"buffer":0,
"byteLength":3780,
"byteOffset":3780,
"target":34962
},
{
"buffer":0,
"byteLength":2520,
"byteOffset":7560,
"target":34962
},
{
"buffer":0,
"byteLength":1104,
"byteOffset":10080,
"target":34963
}
],
"samplers":[
{
"magFilter":9729,
"minFilter":9987
}
],
"buffers":[
{
"byteLength":11184,
"uri":"lot-small0.bin"
}
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,5 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://astream/terrain/details/lot-small0.gltf" type="PackedScene" id=1]
[node name="lot-small0" instance=ExtResource( 1 )]

View File

@@ -80,61 +80,61 @@
{
"bufferView":0,
"componentType":5126,
"count":330,
"count":220,
"max":[
28.415786743164062,
0.01780128851532936,
44.232872009277344
39.999271392822266,
0.30028843879699707,
49.77977752685547
],
"min":[
-28.410146713256836,
-39.844146728515625,
-4.802618026733398,
-39.0701789855957
-49.61350631713867
],
"type":"VEC3"
},
{
"bufferView":1,
"componentType":5126,
"count":330,
"count":220,
"type":"VEC3"
},
{
"bufferView":2,
"componentType":5126,
"count":330,
"count":220,
"type":"VEC2"
},
{
"bufferView":3,
"componentType":5123,
"count":492,
"count":348,
"type":"SCALAR"
}
],
"bufferViews":[
{
"buffer":0,
"byteLength":3960,
"byteLength":2640,
"byteOffset":0,
"target":34962
},
{
"buffer":0,
"byteLength":3960,
"byteOffset":3960,
"target":34962
},
{
"buffer":0,
"byteLength":2640,
"byteOffset":7920,
"byteOffset":2640,
"target":34962
},
{
"buffer":0,
"byteLength":984,
"byteOffset":10560,
"byteLength":1760,
"byteOffset":5280,
"target":34962
},
{
"buffer":0,
"byteLength":696,
"byteOffset":7040,
"target":34963
}
],
@@ -146,7 +146,7 @@
],
"buffers":[
{
"byteLength":11544,
"byteLength":7736,
"uri":"lot-small1.bin"
}
]

View File

@@ -2,4 +2,6 @@
[ext_resource path="res://astream/terrain/details/lot-small1.gltf" type="PackedScene" id=1]
[node name="lot-small1" instance=ExtResource( 1 )]
[node name="terrain" type="Spatial"]
[node name="lot-small1" parent="." instance=ExtResource( 1 )]

Binary file not shown.

View File

@@ -0,0 +1,153 @@
{
"asset":{
"generator":"Khronos glTF Blender I/O v3.6.28",
"version":"2.0"
},
"extensionsUsed":[
"KHR_materials_specular",
"KHR_materials_ior"
],
"scene":0,
"scenes":[
{
"name":"Scene",
"nodes":[
0
]
}
],
"nodes":[
{
"mesh":0,
"name":"terrain-col"
}
],
"materials":[
{
"alphaCutoff":0.5,
"alphaMode":"MASK",
"extensions":{
"KHR_materials_specular":{
"specularColorFactor":[
0.474271529955476,
0.474271529955476,
0.474271529955476
]
},
"KHR_materials_ior":{
"ior":1.4500000476837158
}
},
"name":"material_atlas_36953_1",
"pbrMetallicRoughness":{
"baseColorTexture":{
"index":0
},
"metallicFactor":0
}
}
],
"meshes":[
{
"name":"Plane",
"primitives":[
{
"attributes":{
"POSITION":0,
"NORMAL":1,
"TEXCOORD_0":2
},
"indices":3,
"material":0
}
]
}
],
"textures":[
{
"sampler":0,
"source":0
}
],
"images":[
{
"mimeType":"image/png",
"name":"Atlas_36953",
"uri":"Atlas_36953.png"
}
],
"accessors":[
{
"bufferView":0,
"componentType":5126,
"count":241,
"max":[
99.999267578125,
0.30028843879699707,
49.77977752685547
],
"min":[
-99.84414672851562,
-4.802618026733398,
-49.61350631713867
],
"type":"VEC3"
},
{
"bufferView":1,
"componentType":5126,
"count":241,
"type":"VEC3"
},
{
"bufferView":2,
"componentType":5126,
"count":241,
"type":"VEC2"
},
{
"bufferView":3,
"componentType":5123,
"count":408,
"type":"SCALAR"
}
],
"bufferViews":[
{
"buffer":0,
"byteLength":2892,
"byteOffset":0,
"target":34962
},
{
"buffer":0,
"byteLength":2892,
"byteOffset":2892,
"target":34962
},
{
"buffer":0,
"byteLength":1928,
"byteOffset":5784,
"target":34962
},
{
"buffer":0,
"byteLength":816,
"byteOffset":7712,
"target":34963
}
],
"samplers":[
{
"magFilter":9729,
"minFilter":9987
}
],
"buffers":[
{
"byteLength":8528,
"uri":"lot-small2.bin"
}
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,5 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://astream/terrain/details/lot-small2.gltf" type="PackedScene" id=1]
[node name="lot-small2" instance=ExtResource( 1 )]

Binary file not shown.

View File

@@ -0,0 +1,235 @@
{
"asset":{
"generator":"Khronos glTF Blender I/O v3.6.28",
"version":"2.0"
},
"extensionsUsed":[
"KHR_materials_specular",
"KHR_materials_ior"
],
"scene":0,
"scenes":[
{
"name":"Scene",
"nodes":[
1,
2
]
}
],
"nodes":[
{
"mesh":0,
"name":"garage-col-colonly"
},
{
"children":[
0
],
"mesh":1,
"name":"garage"
},
{
"name":"NurbsPath"
}
],
"materials":[
{
"alphaCutoff":0.5,
"alphaMode":"MASK",
"extensions":{
"KHR_materials_specular":{
"specularColorFactor":[
0.474271529955476,
0.474271529955476,
0.474271529955476
]
},
"KHR_materials_ior":{
"ior":1.4500000476837158
}
},
"name":"material_atlas_36953_1",
"pbrMetallicRoughness":{
"baseColorTexture":{
"index":0
},
"metallicFactor":0
}
}
],
"meshes":[
{
"name":"Cube",
"primitives":[
{
"attributes":{
"POSITION":0,
"NORMAL":1,
"TEXCOORD_0":2
},
"indices":3
}
]
},
{
"name":"Cube.014",
"primitives":[
{
"attributes":{
"POSITION":4,
"NORMAL":5,
"TEXCOORD_0":6
},
"indices":7,
"material":0
}
]
}
],
"textures":[
{
"sampler":0,
"source":0
}
],
"images":[
{
"mimeType":"image/png",
"name":"Atlas_36953",
"uri":"Atlas_36953.png"
}
],
"accessors":[
{
"bufferView":0,
"componentType":5126,
"count":160,
"max":[
19,
6,
4.5
],
"min":[
-12.100000381469727,
-0.5,
-4.5
],
"type":"VEC3"
},
{
"bufferView":1,
"componentType":5126,
"count":160,
"type":"VEC3"
},
{
"bufferView":2,
"componentType":5126,
"count":160,
"type":"VEC2"
},
{
"bufferView":3,
"componentType":5123,
"count":420,
"type":"SCALAR"
},
{
"bufferView":4,
"componentType":5126,
"count":129,
"max":[
19,
6,
4.500000953674316
],
"min":[
-12.100000381469727,
-0.5,
-4.499999046325684
],
"type":"VEC3"
},
{
"bufferView":5,
"componentType":5126,
"count":129,
"type":"VEC3"
},
{
"bufferView":6,
"componentType":5126,
"count":129,
"type":"VEC2"
},
{
"bufferView":7,
"componentType":5123,
"count":306,
"type":"SCALAR"
}
],
"bufferViews":[
{
"buffer":0,
"byteLength":1920,
"byteOffset":0,
"target":34962
},
{
"buffer":0,
"byteLength":1920,
"byteOffset":1920,
"target":34962
},
{
"buffer":0,
"byteLength":1280,
"byteOffset":3840,
"target":34962
},
{
"buffer":0,
"byteLength":840,
"byteOffset":5120,
"target":34963
},
{
"buffer":0,
"byteLength":1548,
"byteOffset":5960,
"target":34962
},
{
"buffer":0,
"byteLength":1548,
"byteOffset":7508,
"target":34962
},
{
"buffer":0,
"byteLength":1032,
"byteOffset":9056,
"target":34962
},
{
"buffer":0,
"byteLength":612,
"byteOffset":10088,
"target":34963
}
],
"samplers":[
{
"magFilter":9729,
"minFilter":9987
}
],
"buffers":[
{
"byteLength":10700,
"uri":"residental-garage.bin"
}
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,54 @@
[gd_scene load_steps=6 format=2]
[ext_resource path="res://astream/terrain/details/residental-garage.gltf" type="PackedScene" id=1]
[sub_resource type="CubeMesh" id=1]
size = Vector3( 27, 1, 10 )
[sub_resource type="SpatialMaterial" id=2]
albedo_color = Color( 0.227451, 0.0235294, 0.0235294, 1 )
[sub_resource type="CubeMesh" id=3]
size = Vector3( 25, 6, 9 )
[sub_resource type="SpatialMaterial" id=4]
albedo_color = Color( 0.980392, 0.639216, 0.0705882, 1 )
[node name="garage" type="Spatial"]
[node name="LOD" type="LOD" parent="."]
[node name="MergeGroup" type="MergeGroup" parent="LOD"]
lod_range = 35.0
[node name="residental-garage" parent="LOD/MergeGroup" instance=ExtResource( 1 )]
[node name="MeshInstance" type="MeshInstance" parent="LOD/MergeGroup"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.427596, 6.49411, 0 )
mesh = SubResource( 1 )
material/0 = SubResource( 2 )
[node name="MergeGroup1" type="MergeGroup" parent="LOD"]
visible = false
lod_range = 20.0
[node name="residental-garage" parent="LOD/MergeGroup1" instance=ExtResource( 1 )]
[node name="MeshInstance" type="MeshInstance" parent="LOD/MergeGroup1"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.427596, 6.49411, 0 )
mesh = SubResource( 1 )
material/0 = SubResource( 2 )
[node name="MergeGroup2" type="MergeGroup" parent="LOD"]
visible = false
[node name="MeshInstance" type="MeshInstance" parent="LOD/MergeGroup2"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 3, 0 )
mesh = SubResource( 3 )
skeleton = NodePath("../../MergeGroup2")
material/0 = SubResource( 4 )
[node name="MeshInstance2" type="MeshInstance" parent="LOD/MergeGroup2"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.427596, 6.49411, 0 )
mesh = SubResource( 1 )
material/0 = SubResource( 2 )

Binary file not shown.

View File

@@ -0,0 +1,237 @@
{
"asset":{
"generator":"Khronos glTF Blender I/O v3.6.28",
"version":"2.0"
},
"extensionsUsed":[
"KHR_materials_specular",
"KHR_materials_ior"
],
"scene":0,
"scenes":[
{
"name":"Scene",
"nodes":[
1
]
}
],
"nodes":[
{
"mesh":0,
"name":"flat3-1-noimp",
"translation":[
0,
1,
0
]
},
{
"children":[
0
],
"mesh":1,
"name":"house3-col"
}
],
"materials":[
{
"alphaCutoff":0.5,
"alphaMode":"MASK",
"extensions":{
"KHR_materials_specular":{
"specularColorFactor":[
0.474271529955476,
0.474271529955476,
0.474271529955476
]
},
"KHR_materials_ior":{
"ior":1.4500000476837158
}
},
"name":"material_atlas_73934_1",
"pbrMetallicRoughness":{
"baseColorTexture":{
"index":0
},
"metallicFactor":0
}
}
],
"meshes":[
{
"name":"Plane.003",
"primitives":[
{
"attributes":{
"POSITION":0,
"NORMAL":1,
"TEXCOORD_0":2
},
"indices":3,
"material":0
}
]
},
{
"name":"Cube.003",
"primitives":[
{
"attributes":{
"POSITION":4,
"NORMAL":5,
"TEXCOORD_0":6
},
"indices":7,
"material":0
}
]
}
],
"textures":[
{
"sampler":0,
"source":0
}
],
"images":[
{
"mimeType":"image/png",
"name":"Atlas_73934",
"uri":"Atlas_73934.png"
}
],
"accessors":[
{
"bufferView":0,
"componentType":5126,
"count":28,
"max":[
11,
4,
11
],
"min":[
-11,
0,
-8
],
"type":"VEC3"
},
{
"bufferView":1,
"componentType":5126,
"count":28,
"type":"VEC3"
},
{
"bufferView":2,
"componentType":5126,
"count":28,
"type":"VEC2"
},
{
"bufferView":3,
"componentType":5123,
"count":72,
"type":"SCALAR"
},
{
"bufferView":4,
"componentType":5126,
"count":368,
"max":[
7,
13,
8
],
"min":[
-7,
0,
-9
],
"type":"VEC3"
},
{
"bufferView":5,
"componentType":5126,
"count":368,
"type":"VEC3"
},
{
"bufferView":6,
"componentType":5126,
"count":368,
"type":"VEC2"
},
{
"bufferView":7,
"componentType":5123,
"count":1002,
"type":"SCALAR"
}
],
"bufferViews":[
{
"buffer":0,
"byteLength":336,
"byteOffset":0,
"target":34962
},
{
"buffer":0,
"byteLength":336,
"byteOffset":336,
"target":34962
},
{
"buffer":0,
"byteLength":224,
"byteOffset":672,
"target":34962
},
{
"buffer":0,
"byteLength":144,
"byteOffset":896,
"target":34963
},
{
"buffer":0,
"byteLength":4416,
"byteOffset":1040,
"target":34962
},
{
"buffer":0,
"byteLength":4416,
"byteOffset":5456,
"target":34962
},
{
"buffer":0,
"byteLength":2944,
"byteOffset":9872,
"target":34962
},
{
"buffer":0,
"byteLength":2004,
"byteOffset":12816,
"target":34963
}
],
"samplers":[
{
"magFilter":9729,
"minFilter":9987
}
],
"buffers":[
{
"byteLength":14820,
"uri":"residental-hut1.bin"
}
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,74 @@
[gd_scene load_steps=7 format=2]
[ext_resource path="res://astream/terrain/details/residental-hut1.gltf" type="PackedScene" id=1]
[ext_resource path="res://astream/terrain/details/parts/door1-portal.tscn" type="PackedScene" id=2]
[ext_resource path="res://astream/terrain/details/parts/residental-house-stair.tscn" type="PackedScene" id=3]
[sub_resource type="BoxShape" id=1]
extents = Vector3( 0.7, 1, 0.6 )
[sub_resource type="CubeMesh" id=2]
size = Vector3( 14, 7, 16 )
[sub_resource type="SpatialMaterial" id=3]
albedo_color = Color( 0.937255, 0.615686, 0.0627451, 1 )
[node name="residental-hut1" type="Spatial"]
[node name="LOD" type="LOD" parent="."]
[node name="MergeGroup" type="MergeGroup" parent="LOD"]
lod_range = 40.0
[node name="residental-hut1" parent="LOD/MergeGroup" instance=ExtResource( 1 )]
[node name="door1-portal" parent="LOD/MergeGroup" instance=ExtResource( 2 )]
transform = Transform( -1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 1, 1, -7.48604 )
skeleton = NodePath("../../..")
[node name="enter_destination" type="Spatial" parent="LOD/MergeGroup/door1-portal" groups=["smart_object"]]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.905, 0, 0.65 )
[node name="actions" type="Node" parent="LOD/MergeGroup/door1-portal/enter_destination"]
[node name="EnterDestination" type="Node" parent="LOD/MergeGroup/door1-portal/enter_destination/actions"]
[node name="Area" type="Area" parent="LOD/MergeGroup/door1-portal/enter_destination"]
[node name="CollisionShape" type="CollisionShape" parent="LOD/MergeGroup/door1-portal/enter_destination/Area"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.1, 0 )
shape = SubResource( 1 )
[node name="residental-house-stair" parent="LOD/MergeGroup" instance=ExtResource( 3 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -7.97294 )
[node name="MergeGroup2" type="MergeGroup" parent="LOD"]
visible = false
lod_range = 20.0
[node name="residental-hut1" parent="LOD/MergeGroup2" instance=ExtResource( 1 )]
[node name="door1-portal" parent="LOD/MergeGroup2" instance=ExtResource( 2 )]
transform = Transform( -1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 1, 1, -7.48604 )
skeleton = NodePath("../../..")
[node name="enter_destination" type="Spatial" parent="LOD/MergeGroup2/door1-portal" groups=["smart_object"]]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.905, 0, 0.65 )
[node name="actions" type="Node" parent="LOD/MergeGroup2/door1-portal/enter_destination"]
[node name="EnterDestination" type="Node" parent="LOD/MergeGroup2/door1-portal/enter_destination/actions"]
[node name="Area" type="Area" parent="LOD/MergeGroup2/door1-portal/enter_destination"]
[node name="CollisionShape" type="CollisionShape" parent="LOD/MergeGroup2/door1-portal/enter_destination/Area"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.1, 0 )
shape = SubResource( 1 )
[node name="MergeGroup3" type="MergeGroup" parent="LOD"]
visible = false
[node name="MeshInstance" type="MeshInstance" parent="LOD/MergeGroup3"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 3.5, 0 )
mesh = SubResource( 2 )
material/0 = SubResource( 3 )

View File

@@ -37,7 +37,13 @@ building_data = {
"foundation30": "res://astream/terrain/details/foundation30.tscn",
"foundation60": "res://astream/terrain/details/foundation60.tscn",
"bus-stop": "res://astream/terrain/details/bus-stop.tscn",
"lot-small0": "res://astream/terrain/details/lot-small0.tscn",
"lot-small1": "res://astream/terrain/details/lot-small1.tscn",
"lot-small2": "res://astream/terrain/details/lot-small2.tscn",
"lot-large1": "res://astream/terrain/details/lot-large1.tscn",
"lot-large2": "res://astream/terrain/details/lot-large2.tscn",
"residental-garage1": "res://astream/terrain/details/residental-garage1.tscn",
"residental-hut1": "res://astream/terrain/details/residental-hut1.tscn",
"sideroad-short1": "res://astream/terrain/details/sideroad-short1.tscn",
}
buildings_path = "res://astream/buildings.json"
@@ -68,3 +74,53 @@ lot_y_rotation = -90.0
lot_offset = 33.8
lot_y_rotation = 90.0
[lines/edges/lot-small0/left]
lot_offset = 26.5
lot_y_rotation = 0
lot_y_offset = 0
[lines/edges/lot-small0/right]
lot_offset = 26.5
lot_y_rotation = 180
lot_y_offset = 0
[lines/edges/lot-small1/left]
lot_offset = 36
lot_y_rotation = 0
lot_y_offset = 0
[lines/edges/lot-small1/right]
lot_offset = 36
lot_y_rotation = 180
lot_y_offset = 0
[lines/edges/lot-small2/left]
lot_offset = 96
lot_y_rotation = 0
lot_y_offset = 0
[lines/edges/lot-small2/right]
lot_offset = 96
lot_y_rotation = 180
lot_y_offset = 0
[lines/edges/lot-large1/left]
lot_offset = 96
lot_y_rotation = 0
lot_y_offset = 0
[lines/edges/lot-large1/right]
lot_offset = 96
lot_y_rotation = 180
lot_y_offset = 0
[lines/edges/lot-large2/left]
lot_offset = 196
lot_y_rotation = 0
lot_y_offset = 0
[lines/edges/lot-large2/right]
lot_offset = 196
lot_y_rotation = 180
lot_y_offset = 0

View File

@@ -1091,6 +1091,112 @@ class EdgeEditorHandler {
result = 1;
return result;
}
bool pack_buildings(
const AABB &lot_aabb,
std::vector<struct RoadLinesData::road_edge_side::buildings>
&buildings,
float gap)
{
int i;
Rect2 rect_lot(lot_aabb.position.x, lot_aabb.position.z,
lot_aabb.size.x, lot_aabb.size.z);
std::vector<Rect2> inputs, outputs;
List<Rect2> parts;
List<Rect2> parts_next;
rect_lot.grow_by(-4);
print_line("lot rect: " + (rect_lot.operator String()));
parts.push_back(rect_lot);
Vector<int> bad_indices;
for (i = 0; i < (int)buildings.size(); i++) {
if (buildings[i].id.length() == 0) {
if (bad_indices.find(i) < 0)
bad_indices.push_back(i);
continue;
}
const AABB &aabb_building =
BuildingsData::get_singleton()
->building_aabbs[buildings[i].id];
Transform building_rot(
Basis().rotated(
Vector3(0, 1, 0),
Math::deg2rad(buildings[i].y_rotation)),
Vector3());
const AABB &aabb_building_rot =
building_rot.xform(aabb_building);
Rect2 input(aabb_building_rot.position.x,
aabb_building_rot.position.z,
aabb_building_rot.size.x,
aabb_building_rot.size.z);
if (input.size.x < 0.1f) {
if (bad_indices.find(i) < 0)
bad_indices.push_back(i);
continue;
}
print_line("id: " + buildings[i].id +
" input: " + (input.operator String()));
input.grow_by(gap);
inputs.push_back(input);
}
bad_indices.invert();
for (i = 0; i < (int)bad_indices.size(); i++)
buildings.erase(buildings.begin() + bad_indices[i]);
if (buildings.size() < 2)
return false;
for (i = 0; i < (int)inputs.size(); i++) {
bool found = false;
List<Rect2>::Element *e = parts.front();
while (e) {
Rect2 part = e->get();
if (part.size.x >= inputs[i].size.x &&
part.size.y >= inputs[i].size.y) {
found = true;
Rect2 output(part.position.x,
part.position.y,
inputs[i].size.x,
inputs[i].size.y);
outputs.push_back(output);
Rect2 part1(part.position.x,
part.position.y +
inputs[i].size.y,
inputs[i].size.x,
part.size.y -
inputs[i].size.y);
Rect2 part2(part.position.x +
inputs[i].size.x,
part.position.y,
part.size.x -
inputs[i].size.x,
part.size.y);
parts_next.push_back(part1);
parts_next.push_back(part2);
break;
} else
parts_next.push_back(part);
e = e->next();
}
if (!found) {
print_line("can't fit " + itos(i));
break;
}
parts = parts_next;
}
if (outputs.size() < buildings.size())
return false;
Rect2 result;
for (i = 0; i < (int)outputs.size(); i++) {
print_line("output: " + itos(i) +
(outputs[i].operator String()));
result = result.merge(outputs[i]);
}
for (i = 0; i < (int)outputs.size(); i++) {
/* FIXME: why ? */
Vector2 center =
outputs[i].get_center() - result.get_center();
buildings[i].offsets.x = center.x;
buildings[i].offsets.z = center.y;
}
return true;
}
void event_handler(const String &event, const Vector<Variant> &args)
{
if (event == "road_lines_edge_editor::edit") {
@@ -1133,6 +1239,9 @@ class EdgeEditorHandler {
case 200:
pname = "clear";
break;
case 201:
pname = "clear-buildings";
break;
default:
pname = menu->get_item_metadata(item_index);
break;
@@ -1150,6 +1259,10 @@ class EdgeEditorHandler {
get_edge_conf<float>(
pname, "left",
"lot_y_rotation");
rl.edges[index].left.lot_offset =
get_edge_conf<float>(
pname, "left",
"lot_offset");
float dir_offt =
rl.points[index + 1]
.origin.distance_to(
@@ -1159,6 +1272,32 @@ class EdgeEditorHandler {
rl.edges[index].left.lot_dir_offset =
dir_offt;
}
} else if (pname.begins_with("residental-")) {
struct RoadLinesData::road_edge_side::buildings
b;
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 =
rl.edges[index].left.lot_type;
if (rl.edges[index]
.left.buildings.size() >
1) {
const AABB &aabb_lot =
BuildingsData::get_singleton()
->building_aabbs
["lot-" +
lot_id];
pack_buildings(
aabb_lot,
rl.edges[index]
.left.buildings,
2.0f);
}
}
} else if (pname == "clear") {
rl.edges[index].left.lot_type = "";
rl.edges[index].left.lot = 0;
@@ -1175,6 +1314,9 @@ class EdgeEditorHandler {
case 200:
pname = "clear";
break;
case 201:
pname = "clear-buildings";
break;
default:
pname = menu->get_item_metadata(item_index);
break;
@@ -1195,6 +1337,10 @@ class EdgeEditorHandler {
get_edge_conf<float>(
pname, "right",
"lot_y_rotation");
rl.edges[index].right.lot_offset =
get_edge_conf<float>(
pname, "right",
"lot_offset");
float dir_offt =
rl.points[index + 1]
.origin.distance_to(
@@ -1204,6 +1350,33 @@ class EdgeEditorHandler {
rl.edges[index].right.lot_dir_offset =
dir_offt;
}
} else if (pname.begins_with("residental-") ||
pname.begins_with("business-")) {
struct RoadLinesData::road_edge_side::buildings
b;
b.id = pname;
b.offsets = Vector3();
b.y_rotation = 0.0f;
rl.edges[index].right.buildings.push_back(b);
if (rl.edges[index].right.lot > 0) {
String lot_id =
rl.edges[index].right.lot_type;
if (rl.edges[index]
.right.buildings.size() >
1) {
const AABB &aabb_lot =
BuildingsData::get_singleton()
->building_aabbs
["lot-" +
lot_id];
pack_buildings(
aabb_lot,
rl.edges[index]
.right.buildings,
2.0f);
}
}
} else if (pname == "clear") {
rl.edges[index].right.lot_type = "";
rl.edges[index].right.lot = 0;
@@ -1253,74 +1426,124 @@ public:
v->call_deferred("add_child", sep);
v->call_deferred("add_child", h2);
side_handler(v, right, "right");
MenuButton *mb = memnew(MenuButton);
v->call_deferred("add_child", mb);
mb->set_text("Action...");
MenuButton *mb_left = memnew(MenuButton);
v->call_deferred("add_child", mb_left);
mb_left->set_text("Select left lot...");
MenuButton *mb_right = memnew(MenuButton);
mb_right->set_text("Select right lot...");
v->call_deferred("add_child", mb_right);
Error err = stream_conf.load("res://config/stream.conf");
assert(err == OK);
struct menu_button_config {
String caption;
std::vector<std::pair<String, int> > *menu_items;
String filter;
String msg;
String event;
};
std::vector<std::pair<String, int> > menu_items = {
{ "Move lots starting from current edge to next edges",
100 },
};
std::vector<std::pair<String, int> > menu_items_leftright = {
{ "Clear current lot and building(s)", 200 },
{ "Clear current building(s)", 201 },
};
for (i = 0; i < (int)menu_items.size(); i++)
mb->get_popup()->add_item(menu_items[i].first,
menu_items[i].second);
for (i = 0; i < (int)menu_items_leftright.size(); i++) {
mb_left->get_popup()->add_item(
menu_items_leftright[i].first,
menu_items_leftright[i].second);
mb_right->get_popup()->add_item(
menu_items_leftright[i].first,
menu_items_leftright[i].second);
}
int item_id = 1000;
struct menu_button_config buttons[] = {
{
.caption = "Action...",
.menu_items = &menu_items,
.filter = "",
.event = event_prefix + "::menu",
},
{
.caption = "Select left lot...",
.menu_items = &menu_items_leftright,
.filter = "lot-",
.msg = "Create lot ",
.event = event_prefix + "::menu::left",
},
{
.caption = "Add left house...",
.menu_items = nullptr,
.filter = "residental-",
.msg = "Add house ",
.event = event_prefix + "::menu::left",
},
{
.caption = "Add left business...",
.menu_items = nullptr,
.filter = "business-",
.msg = "Add business ",
.event = event_prefix + "::menu::left",
},
{
.caption = "Select right lot...",
.menu_items = &menu_items_leftright,
.filter = "lot-",
.msg = "Create lot ",
.event = event_prefix + "::menu::right",
},
{
.caption = "Add right house...",
.menu_items = nullptr,
.filter = "residental-",
.msg = "Add house ",
.event = event_prefix + "::menu::right",
},
{
.caption = "Add right business...",
.menu_items = nullptr,
.filter = "business-",
.msg = "Add business ",
.event = event_prefix + "::menu::right",
},
};
Error err = stream_conf.load("res://config/stream.conf");
assert(err == OK);
Dictionary bdata =
stream_conf.get_value("buildings", "building_data");
int item_id = 1000;
List<Variant> building_list;
List<Variant>::Element *el;
for (i = 0; i < (int)sizeof(buttons) / (int)sizeof(buttons[0]);
i++) {
int j;
MenuButton *mb = memnew(MenuButton);
v->call_deferred("add_child", mb);
mb->set_text(buttons[i].caption);
if (buttons[i].menu_items) {
for (j = 0;
j < (int)buttons[i].menu_items->size();
j++)
mb->get_popup()->add_item(
buttons[i]
.menu_items->data()[j]
.first,
buttons[i]
.menu_items->data()[j]
.second);
}
if (buttons[i].filter.length() > 0) {
List<Variant> building_list;
bdata.get_key_list(&building_list);
el = building_list.front();
while (el) {
String pname = el->get();
String msg;
if (pname.begins_with("lot-"))
msg = "Create lot: " + pname;
else if (pname.begins_with("residental-"))
msg = "Add house: " + pname;
if (msg.length() > 0 && pname.begins_with("lot-")) {
std::vector<PopupMenu *> menus = {
mb_left->get_popup(),
mb_right->get_popup()
};
for (i = 0; i < (int)menus.size(); i++) {
menus[i]->add_item(msg, item_id);
if (pname.begins_with(
buttons[i].filter)) {
String message =
buttons[i].msg + " " +
pname;
mb->get_popup()->add_item(
message, item_id);
int item_index =
menus[i]->get_item_index(
mb->get_popup()
->get_item_index(
item_id);
menus[i]->set_item_metadata(item_index,
mb->get_popup()
->set_item_metadata(
item_index,
pname);
item_id++;
}
}
el = el->next();
}
}
menu_handlers.push_back(memnew(PopupMenuSelectHandler(
mb->get_popup(), event_prefix + "::menu")));
menu_handlers.push_back(memnew(PopupMenuSelectHandler(
mb_left->get_popup(), event_prefix + "::menu::left")));
menu_handlers.push_back(memnew(PopupMenuSelectHandler(
mb_right->get_popup(),
event_prefix + "::menu::right")));
mb->get_popup(), buttons[i].event)));
}
EditorEvent::get_singleton()->event.add_listener(
this, &EdgeEditorHandler::event_handler);
}