Files
academy2-game/autoload/streaming.gd
Segey Lapin d6c8a24f5a stuff
2021-10-26 21:52:15 +03:00

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()