297 lines
7.8 KiB
GDScript
297 lines
7.8 KiB
GDScript
extends Node
|
|
|
|
export var trailer_house: PackedScene
|
|
export var palace: PackedScene
|
|
export var car: PackedScene
|
|
|
|
onready var obj_names = {
|
|
"palace": palace,
|
|
"trailer_house": trailer_house
|
|
}
|
|
|
|
var done = false
|
|
|
|
class radial_grid:
|
|
var radial_points = []
|
|
var max_r = 0.0
|
|
var grid = []
|
|
var width: int = 0
|
|
var height: int = 0
|
|
var nodes = []
|
|
func build(poly, center):
|
|
var height = center.y
|
|
max_r = 0.0
|
|
for p in range(poly.size()):
|
|
var ep1 = poly[p]
|
|
ep1.y = height
|
|
var ep2 = poly[(p + 1) % poly.size()]
|
|
ep2.y = height
|
|
var d = (ep2 - ep1).normalized()
|
|
radial_points.push_back(ep1)
|
|
var dst = ep1.distance_to(ep2)
|
|
while dst > 32:
|
|
ep1 += d * 32
|
|
radial_points.push_back(ep1)
|
|
dst -= 32
|
|
for p in range(radial_points.size()):
|
|
var ep = radial_points[p]
|
|
var dst = ep.distance_to(center)
|
|
if max_r < dst:
|
|
max_r = dst
|
|
width = radial_points.size()
|
|
height = int(max_r / 32)
|
|
grid.resize(width * height)
|
|
for p in range(width):
|
|
var start = radial_points[p]
|
|
var end = center
|
|
var step = (end - start).normalized() * (end - start).length() / float(height + 1)
|
|
var val = start
|
|
for q in range(height):
|
|
grid[p * height + q] = {"position": val, "node": null}
|
|
func get_grid_node(x, y):
|
|
return grid[x * height + y].node
|
|
func set_grid_node(x, y, node):
|
|
if !node in nodes:
|
|
nodes.push_back(node)
|
|
grid[x * height + y].node = node
|
|
func place_grid(aabb: AABB, node) -> void:
|
|
for u in range(width):
|
|
for v in range(height):
|
|
if aabb.has_point(grid[u * height + v].position):
|
|
set_grid_node(u, v, node)
|
|
func get_pos(x, y):
|
|
return grid[x * height + y].position
|
|
|
|
onready var grid = radial_grid.new()
|
|
|
|
func debug_poly(poly):
|
|
for k in range(poly.size()):
|
|
var p1 = poly[k]
|
|
var p2 = poly[(k + 1) % poly.size()]
|
|
var l = p1.distance_to(p2)
|
|
var d = (p2 - p1).normalized()
|
|
var pt = p1
|
|
while l > 0.0:
|
|
for e in range(0, 30, 2):
|
|
var mi = MeshInstance.new()
|
|
mi.mesh = CubeMesh.new()
|
|
get_tree().root.add_child(mi)
|
|
mi.global_transform.origin = pt + Vector3(0, e, 0)
|
|
pt += d * 5.0
|
|
l -= 5.0
|
|
|
|
func calc_border(poly, offt):
|
|
var height = RoadsData.get_site_avg_height(0)
|
|
var border = []
|
|
border.resize(poly.size())
|
|
for k in range(poly.size()):
|
|
var i = k - 1
|
|
if i < 0:
|
|
i += poly.size()
|
|
var p1 = poly[i]
|
|
var p2 = poly[k]
|
|
var p3 = poly[(k + 1) % poly.size()]
|
|
var p1x = Vector2(p1.x, p1.z)
|
|
var p2x = Vector2(p2.x, p2.z)
|
|
var p3x = Vector2(p2.x, p2.z)
|
|
var p4x = Vector2(p3.x, p3.z)
|
|
var n1 = (p2x - p1x).tangent().normalized()
|
|
var n2 = (p4x - p3x).tangent().normalized()
|
|
p1x -= n1 * offt
|
|
p2x -= n1 * offt
|
|
p3x -= n2 * offt
|
|
p4x -= n2 * offt
|
|
|
|
var xp = Geometry.segment_intersects_segment_2d(p1x, p2x, p3x, p4x)
|
|
if !xp:
|
|
xp = p2x.linear_interpolate(p3x, 0.5) - (n1 + n2).normalized() * offt
|
|
var tp = Vector3(xp.x, height, xp.y)
|
|
border[k] = tp
|
|
return border
|
|
|
|
var towns = 0
|
|
func setup_town(site):
|
|
if !RoadsData.site_is_town(site):
|
|
print("site ", site, " type: ", RoadsData.get_site_type(site))
|
|
return
|
|
var poly = RoadsData.get_site_polygon_3d(site)
|
|
var height = RoadsData.get_site_avg_height(site)
|
|
var border2 = calc_border(poly, 60)
|
|
var aabbs = []
|
|
var poly2 = []
|
|
poly2.resize(border2.size())
|
|
for p in range(border2.size()):
|
|
poly2[p] = Vector2(border2[p].x, border2[p].z)
|
|
var center = Vector3()
|
|
for p in poly:
|
|
center += p
|
|
center /= poly.size()
|
|
center.y = height
|
|
grid.build(border2, center)
|
|
var radial_points = grid.radial_points
|
|
var max_r = 0.0
|
|
for p in range(radial_points.size()):
|
|
var ep = radial_points[p]
|
|
var dst = ep.distance_to(center)
|
|
if max_r < dst:
|
|
max_r = dst
|
|
for p in range(radial_points.size()):
|
|
var ep = radial_points[p]
|
|
var d = (center - ep).normalized()
|
|
var dst = ep.distance_to(center)
|
|
print(dst)
|
|
if dst < 64.0 + 12 + 8 + 4:
|
|
continue
|
|
var step = 16.0
|
|
var pstart = ep
|
|
while dst > 0.0:
|
|
var ok = true
|
|
if !Geometry.is_point_in_polygon(Vector2(pstart.x, pstart.z), poly2):
|
|
ok = false
|
|
if ok:
|
|
for b in aabbs:
|
|
if b.has_point(pstart):
|
|
ok = false
|
|
if ok:
|
|
var xform = Transform(Basis(), pstart).looking_at(pstart + d, Vector3.UP)
|
|
stream_obj("trailer_house", xform)
|
|
var aabb = AABB(pstart, Vector3())
|
|
aabb = aabb.grow(20)
|
|
aabbs.push_back(aabb)
|
|
print("placed to: ", pstart)
|
|
pstart = pstart + d * step
|
|
dst -= step
|
|
towns += 1
|
|
|
|
func setup_first_town():
|
|
assert(!done)
|
|
var poly = RoadsData.get_site_polygon_3d(0)
|
|
var height = RoadsData.get_site_avg_height(0)
|
|
var border = calc_border(poly, 32)
|
|
var border1a = calc_border(poly, 42)
|
|
var border2 = calc_border(poly, 60)
|
|
|
|
var poly2 = []
|
|
poly2.resize(border2.size())
|
|
for p in range(border2.size()):
|
|
poly2[p] = Vector2(border2[p].x, border2[p].z)
|
|
var center = Vector3()
|
|
for p in poly:
|
|
center += p
|
|
center /= poly.size()
|
|
center.y = height
|
|
grid.build(border2, center)
|
|
var radial_points = grid.radial_points
|
|
var max_r = 0.0
|
|
for p in range(radial_points.size()):
|
|
var ep = radial_points[p]
|
|
var dst = ep.distance_to(center)
|
|
if max_r < dst:
|
|
max_r = dst
|
|
var u = radial_points.size()
|
|
var v = int(max_r / 32)
|
|
var grid = []
|
|
grid.resize(u * v)
|
|
for p in range(u):
|
|
var start = radial_points[p]
|
|
var end = center
|
|
var step = (end - start).normalized() * (end - start).length() / float(v + 1)
|
|
var val = start
|
|
for q in range(v):
|
|
grid[p * v + q] = {"position": val}
|
|
var aabbs = []
|
|
var palace_aabb = AABB(center, Vector3())
|
|
palace_aabb = palace_aabb.grow(48)
|
|
print(palace_aabb)
|
|
aabbs.push_back(palace_aabb)
|
|
stream_obj("palace", Transform(Basis(), center))
|
|
|
|
for p in range(radial_points.size()):
|
|
var ep = radial_points[p]
|
|
var d = (center - ep).normalized()
|
|
var dst = ep.distance_to(center)
|
|
print(dst)
|
|
if dst < 64.0 + 12 + 8 + 4:
|
|
continue
|
|
var step = 16.0
|
|
var pstart = ep
|
|
while dst > 0.0:
|
|
var ok = true
|
|
if !Geometry.is_point_in_polygon(Vector2(pstart.x, pstart.z), poly2):
|
|
ok = false
|
|
if ok:
|
|
for b in aabbs:
|
|
if b.has_point(pstart):
|
|
ok = false
|
|
if ok:
|
|
var xform = Transform(Basis(), pstart).looking_at(pstart + d, Vector3.UP)
|
|
stream_obj("trailer_house", xform)
|
|
var aabb = AABB(pstart, Vector3())
|
|
aabb = aabb.grow(20)
|
|
aabbs.push_back(aabb)
|
|
print("placed to: ", pstart)
|
|
pstart = pstart + d * step
|
|
dst -= step
|
|
towns += 1
|
|
done = true
|
|
|
|
func _ready():
|
|
for k in obj_names.keys():
|
|
Spawner.add_scene(k, obj_names[k])
|
|
|
|
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
|
var delay = 3.0
|
|
var state = 0
|
|
func _process(delta):
|
|
match state:
|
|
0:
|
|
delay -= delta
|
|
if delay < 0:
|
|
state = 1
|
|
1:
|
|
Spawner.update_view(self, 300)
|
|
var sc = get_tree().root
|
|
var viewport: = get_viewport()
|
|
if !viewport:
|
|
return
|
|
var cam: = viewport.get_camera()
|
|
if !cam:
|
|
return
|
|
var cam_xform: = cam.global_transform
|
|
|
|
func stream_obj(obj: String, xform: Transform):
|
|
Spawner.place_scene(obj, xform)
|
|
func _physics_process(delta):
|
|
var cam = get_viewport().get_camera()
|
|
if !cam:
|
|
return
|
|
match state:
|
|
1:
|
|
var space_state = get_viewport().get_world().direct_space_state
|
|
# probaly should not be here
|
|
for n in get_tree().get_nodes_in_group("spawn"):
|
|
var ok = false
|
|
if !n.is_in_group("keep"):
|
|
var where = n.get_global_transform().origin
|
|
var from = where
|
|
var to = where
|
|
from.y -= 8.0
|
|
to.y += 8.0
|
|
var result = space_state.intersect_ray(from, to)
|
|
if result.empty() || !result.has("collider"):
|
|
continue
|
|
if result.collider:
|
|
n.global_transform.origin = result.position
|
|
ok = true
|
|
if ok || n.is_in_group("keep"):
|
|
if n.is_in_group("male"):
|
|
characters.replace_character(n, "male", ["cmdq", "marker", "hurtboxes", "student"])
|
|
elif n.is_in_group("female"):
|
|
characters.replace_character(n, "female", ["cmdq", "marker", "hurtboxes", "student"])
|
|
elif n.is_in_group("car"):
|
|
var c = car.instance()
|
|
var p = get_tree().root
|
|
p.add_child(c)
|
|
c.global_transform = n.global_transform
|
|
n.queue_free()
|