Converted to grammar-based approach

This commit is contained in:
Segey Lapin
2021-12-02 20:28:04 +03:00
parent 6e8029c29c
commit 48889c5044

View File

@@ -1,6 +1,6 @@
extends Reference
static func build_house(main_xform: Transform):
static func build_house2(main_xform: Transform):
var rnd = streaming.get_place_rnd(main_xform)
print(main_xform.origin, " seed = ", rnd.state)
var l = 5 + 2 * (rnd.randi() % 5) - 1
@@ -52,3 +52,116 @@ static func build_house(main_xform: Transform):
objects.push_back({"xform": xform, "data": obj_data})
return objects
static func build_walls(pos: Vector3, rnd: RandomNumberGenerator):
var objects = []
var xt = [Transform(Basis(), pos), Transform(Basis().rotated(Vector3.UP, PI), pos - Vector3(0, 0, 2))]
for x in range(xt.size()):
var obj_data = []
if rnd.randf() > 0.5:
obj_data.push_back("wall_solid")
elif rnd.randf() > 0.5:
obj_data.push_back("window_narrow")
else:
obj_data.push_back("window_wide")
objects.push_back({"xform": xt[x], "data": obj_data})
return objects
static func build_house(main_xform: Transform):
var rnd = streaming.get_place_rnd(main_xform)
var terminals = [
"side_wall",
"side_wall_rotated",
"room",
"entry",
"room_range",
"wheels_room"
]
var grammar = {
"start": ["side_wall", "room", "wheels_room", "rooms_entry", "wheels_room", "side_wall_rotated"],
"rooms_entry": ["rooms", "entry!", "rooms"],
"rooms": ["rooms#", ["room", "range!"]],
"entry!": ["entry"],
"range!": ["room_range"],
"rooms#": ["rooms"]
}
var seen = {}
var queue = ["start"]
var complete = false
while !complete:
complete = true
var data = []
for k in range(queue.size()):
var item = queue[k]
print("item=", item)
if !item in terminals:
complete = false
for de in grammar[item]:
var e
if typeof(de) == TYPE_ARRAY:
while true:
e = de[rnd.randi() % de.size()]
if !e.ends_with("!") || !seen.has(e):
break
else:
e = de
print("e=", e)
if e.ends_with("!"):
if seen.has(e):
continue
else:
seen[e] = 1
if e.ends_with("#"):
if queue.size() < 12:
if rnd.randf() >= 0.3:
data.push_back(e)
else:
data.push_back(e)
else:
data.push_back(item)
queue = data
if complete:
if !seen.has("entry!") || !seen.has("range!"):
complete = false
seen.clear()
queue = ["start"]
print("queue: ", queue)
var objects = []
for k in range(queue.size()):
var pos = Vector3(0, 0, k * 2)
var xform = Transform(Basis(), pos)
var xt = [Transform(Basis(), pos), Transform(Basis().rotated(Vector3.UP, PI), pos - Vector3(0, 0, 2))]
match queue[k]:
"side_wall":
objects.push_back({"xform": xform, "data": ["side_wall", "bottom_side"]})
"room":
objects.push_back({"xform": xform, "data": ["roof_floor", "bottom"]})
objects.append_array(build_walls(pos, rnd))
if rnd.randf() > 0.6:
objects.push_back({"xform": xform, "data": ["wall_internal"]})
"wheels_room":
objects.push_back({"xform": xform, "data": ["roof_floor", "bottom_wheels"]})
objects.append_array(build_walls(pos, rnd))
if rnd.randf() > 0.6:
objects.push_back({"xform": xform, "data": ["wall_internal"]})
"room_range":
objects.push_back({"xform": xform, "data": ["roof_floor_range", "bottom"]})
objects.append_array(build_walls(pos, rnd))
if rnd.randf() > 0.6:
objects.push_back({"xform": xform, "data": ["wall_internal"]})
"entry":
for x in range(xt.size()):
var obj_data = []
if x == 0:
continue
if rnd.randf() > 0.5:
obj_data.push_back("wall_solid")
elif rnd.randf() > 0.5:
obj_data.push_back("window_narrow")
else:
obj_data.push_back("window_wide")
objects.push_back({"xform": xt[x], "data": obj_data})
objects.push_back({"xform": xform, "data": ["roof_floor", "entry", "bottom"]})
"side_wall_rotated":
objects.append_array(build_walls(pos, rnd))
objects.push_back({"xform": xform, "data": ["roof_floor", "side_wall_rotated", "bottom_side_rotated", "bottom"]})
return objects