diff --git a/autoload/streaming.gd b/autoload/streaming.gd index 62eefc7..da8e548 100644 --- a/autoload/streaming.gd +++ b/autoload/streaming.gd @@ -50,104 +50,6 @@ onready var palace_map_data = { } -#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 traffic_rnd: RandomNumberGenerator var traffic_astar: AStar var towns = 0 @@ -168,7 +70,6 @@ func setup_town(site): center += p center /= poly.size() center.y = height -# grid.build(border2, center) var radial_points = RoadsData.get_site_radial_points(site, 32.0, 64.0) var max_r = 0.0 for p in range(radial_points.size()): @@ -179,6 +80,7 @@ func setup_town(site): for p in range(radial_points.size()): var ep = radial_points[p] var d = (center - ep).normalized() + assert(d.length_squared() > 0) var dst = ep.distance_to(center) print(dst) if dst < 64.0 + 12 + 8 + 4: @@ -250,6 +152,7 @@ func setup_first_town(): for p in range(radial_points.size()): var ep = radial_points[p] var d = (center - ep).normalized() + assert(d.length_squared() > 0) var dst = ep.distance_to(center) print(dst) if dst < 64.0 + 12 + 8 + 4: @@ -285,12 +188,13 @@ func setup_traffic(site): var n = (p2 - p1).cross(Vector3.UP).normalized() var t = (p2 - p1).normalized() var l = p1.distance_to(p2) + assert(l > 0 && t.length_squared() > 0) var xpos = p1 + t * 8.0 var xe = 128.0 if l < xe + 16.0: xpos = p1.linear_interpolate(p2, 0.5) - var x = xpos + n * 1.5 + Vector3.UP * 0.5 - var xform = Transform(Basis(), x).looking_at(x + t * 3.0, Vector3.UP) + var x = xpos + var xform = Transform(Basis(), x).looking_at(x - t * 3.0, Vector3.UP) var c = Spatial.new() lp.add_child(c) c.transform = xform @@ -299,8 +203,8 @@ func setup_traffic(site): c.add_to_group("traffic_spawn") else: while l > xe + 16.0: - var x = xpos + n * 4.0 + Vector3.UP * 0.5 - var xform = Transform(Basis(), x).looking_at(x + t * 3.0, Vector3.UP) + var x = xpos + var xform = Transform(Basis(), x).looking_at(x - t * 3.0, Vector3.UP) var c = Spatial.new() lp.add_child(c) c.transform = xform @@ -333,9 +237,12 @@ func _ready(): } for k in parts.keys(): Spawner.add_scene(k, parts[k]) + Traffic.set_min_spawn_distance(50.0) +# Traffic.set_deny_physics() + Traffic.set_physics_distance(Vector3(30, -10, 40)) +# Traffic.set_debug(true) Traffic.add_traffic_vehicle(car) -# Called every frame. 'delta' is the elapsed time since the previous frame. var delay = 3.0 var state = 0 func _process(delta): @@ -359,19 +266,6 @@ func _process(delta): func stream_obj(obj: String, xform: Transform): Spawner.place_scene(obj, xform) -func switch_to_distant_vehicle(n): - var sp = PhysicsServer.body_get_space(n.get_rid()) - var l = n.get_linear_velocity() - n.set_meta("velocity", l) - n.set_meta("space", sp) - PhysicsServer.body_set_space(n.get_rid(), RID()) -func switch_to_close_vehicle(n): - var sp = n.get_meta("space") - PhysicsServer.body_set_space(n.get_rid(), sp) - n.remove_meta("space") - if n.has_meta("velocity"): - n.set_linear_velocity(n.get_meta("velocity")) - n.remove_meta("velocity") func _physics_process(delta): var cam = get_viewport().get_camera() if !cam: @@ -382,111 +276,45 @@ func _physics_process(delta): for n in get_tree().get_nodes_in_group("traffic_vehicle"): var p1 = cam.global_transform.origin var p2 = n.global_transform.origin - var check_coords = cam.global_transform.xform_inv(p2) + # p2 has both vertical and lane offset, correct these and write to path_pos + var path_pos = Traffic.get_path_position(n) + var check_coords = cam.global_transform.xform_inv(path_pos) var steer = 0.0 - var x_target = Vector3() - var next_target = Vector3() var orientation = n.global_transform orientation.origin = Vector3() var direction = orientation.xform(Vector3(0, 0, -1)) var good_path = false var engine_force = n.engine_force if !n.has_meta("curve"): - create_path(n, p2, direction * 10.0) + continue if n.has_meta("curve"): - var curve = n.get_meta("curve") - if curve.get_point_count() > 0: - var plength = n.get_meta("curve_length") - var offt = curve.get_closest_offset(p2) - var offt_ext = 8.0 - if n.has_meta("velocity"): - offt_ext = n.get_meta("velocity").length() - offt = clamp(offt + offt_ext, 0, plength) - var p0 = curve.interpolate_baked(offt, false) - next_target = p0 - if false: # p0.distance_squared_to(p2) > 16.0: - n.remove_meta("curve") - steer = 0.0 - x_target = Vector3() - next_target = p2 + direction * 4.0 - else: - var xt0 = n.global_transform.xform_inv(p0) - x_target = xt0 - if xt0.z < 0.0: - steer = xt0.x - if steer == 0.0: - steer = -1 - else: - steer = x_target.x - steer = sign(steer) -# if abs(steer) < 0.005: -# steer = 0.0 - n.set_meta("x_target", x_target) - print("position: ", p2, " direction: ", direction, " next_target: ", next_target, " x_target: ", x_target, " steer: ", steer, " ! ", (next_target - p2).normalized()) - else: - assert(false) -# if check_coords.z > 160 || check_coords.z < -120 || abs(check_coords.x) > 100: -# n.queue_free() - if false: # check_coords.z > 40.0 || check_coords.z < -25.0 || abs(check_coords.x) > 20.0: - if !n.has_meta("space"): - switch_to_distant_vehicle(n) - var xvel = (next_target - p2).normalized() * 6.0 - n.set_meta("velocity", xvel) - var pos = n.global_transform.origin - var vel = (next_target - p2).normalized() * 6.0 - if n.has_meta("velocity"): - vel = n.get_meta("velocity") - var speed = vel.length() - - var stf = (next_target - pos).normalized() * speed -# stf.y = vel.y - vel = vel.linear_interpolate(stf, delta) - var target_pos = pos + vel -# vel.y = vel.y * delta - var newpos = pos.linear_interpolate(target_pos, delta) - n.set_meta("velocity", vel) - # why? - var xform = Transform(Basis(), newpos).looking_at(newpos - vel * 4.0, Vector3.UP) - n.global_transform = xform - else: - if n.has_meta("space"): - switch_to_close_vehicle(n) + # next_target has corrected vertical position (up from path) + steer = Traffic.get_steer(n, true) * 0.6 + if !n.has_meta("space"): var v = n.get_linear_velocity() - n.set_meta("velocity", v) var l = v.length() -# if abs(steer) > 3.0 || !good_path: -# # vehicle totally lost -# n.brake = 60000 -# n.engine_force = 0 -# elif abs(steer) > 2.0: -# # vehicle lost -# n.engine_force = 0 - if next_target.length_squared() == 0: - engine_force = 0.0 - steer = 0.0 + print("physics: velocity: ", v, " velocity norm: ", v.normalized()) + if true: + if abs(steer) > 3.0: + engine_force *= 0.9 + engine_force = clamp(engine_force, 2500.0, max(2500, engine_force)) else: - if abs(steer) > 3.0: - engine_force *= 0.9 - engine_force = clamp(engine_force, 2500.0, max(2500, engine_force)) - else: - if abs(steer) > 4.0 && l > 5.0: - engine_force = engine_force * 0.9996 - if l > 7.0: - engine_force = engine_force * 0.9996 - elif l < 1.1: - engine_force = clamp(engine_force * 1.004, 6000, 8000) - elif l < 2.5: - engine_force = clamp(engine_force * 1.002, 5000, 7000) - elif l < 5.0: - engine_force = clamp(engine_force * 1.001, 4000, 6000) - elif l < 6.0: - engine_force = clamp(engine_force * 1.001, 3000, 5000) -# engine_force = 0.0 - engine_force = clamp(engine_force, 0, 8500) - print("engine_force: ", engine_force) + if abs(steer) > 4.0 && l > 5.0: + engine_force = engine_force * 0.9996 + if l > 7.0: + engine_force = engine_force * 0.9996 + elif l < 1.1: + engine_force = clamp(engine_force * 1.004, 6000, 8000) + elif l < 2.5: + engine_force = clamp(engine_force * 1.002, 5000, 7000) + elif l < 5.0: + engine_force = clamp(engine_force * 1.001, 4000, 6000) + elif l < 6.0: + engine_force = clamp(engine_force * 1.001, 3000, 5000) + engine_force = clamp(engine_force, 0, 3500) +# print("engine_force: ", engine_force) n.engine_force = engine_force n.brake = 0 -# n.steering = clamp(steer, -1, 1) var base_steering = n.steering var main_steering = base_steering * 0.95 + steer * 0.05 n.steering = clamp(main_steering, -1, 1) @@ -522,81 +350,6 @@ func _physics_process(delta): p.add_child(c) c.global_transform = n.global_transform n.queue_free() -# elif n.is_in_group("traffic_spawn"): -# var p1 = cam.global_transform.origin -# var p2 = n.global_transform.origin -# if !n.has_meta("cooldown") && p1.distance_squared_to(p2) < 10000.0: -# var c = car.instance() -# c.add_to_group("traffic_vehicle") -# var p = get_tree().root -# p.add_child(c) -# c.global_transform = n.global_transform -# c.parked = false -# c.mode = c.MODE_RIGID -# c.engine_force = 2500 -# c.steering = 0 -# var xf = c.global_transform -# xf.origin = Vector3() -# var vel = xf.xform(Vector3(0, 0, -10)) -# c.set_linear_velocity(vel) -# var sp = PhysicsServer.body_get_space(c.get_rid()) -# c.set_meta("space", sp) -# PhysicsServer.body_set_space(c.get_rid(), RID()) -# n.set_meta("cooldown", 2.0 + randi() % 8) -# # create_path(c, p2, vel) -# elif n.has_meta("cooldown"): -# var cd = n.get_meta("cooldown") -# cd -= delta -# if cd < 0: -# n.remove_meta("cooldown") -func get_curve_closest(curve, p2): - var test_offt = curve.get_closest_offset(p2) - var testp = curve.interpolate_baked(test_offt, false) - return testp -func test_curve(curve, p2): - var testp = get_curve_closest(curve, p2) - return testp.distance_squared_to(p2) < 16.0 - -func create_path(c, p2, vel): - c.set_meta("velocity", vel) - print("create_path: velocity: ", vel) - var rangle = traffic_rnd.randf() * PI * 2.0 - var randa = 500.0 + traffic_rnd.randf() * 500.0 - var xt = cos(rangle) * randa - var yt = cos(rangle) * randa - var rv = Vector3(xt, 0, yt) - var target = RoadsData.get_closest_point(p2 + rv, false) - var cur = RoadsData.get_closest_point(p2, false) - while cur == target: - rangle = traffic_rnd.randf() * PI * 2.0 - randa = 500.0 + traffic_rnd.randf() * 500.0 - xt = cos(rangle) * randa - yt = sin(rangle) * randa - rv = Vector3(xt, 0, yt) - target = RoadsData.get_closest_point(p2 + rv, false) - c.set_meta("target", target) - var path = RoadsData.get_point_path(cur, target); - assert(cur != target) - assert(path.size() > 0) - var curve = Curve3D.new() - for e in range(path.size() - 1): - var pt1 = path[e] - var pt2 = path[e + 1] - var nt = (pt2 - pt1).cross(Vector3.UP).normalized() - var d = (pt2 - pt1).normalized() - var l = pt1.distance_to(pt2) - while l > 16.0: - pt1 += d * 8.0 - curve.add_point(pt1 + nt * 3.0 + Vector3.UP * 0.5) - l -= 8.0 - if (!test_curve(curve, p2)): - var testp = get_curve_closest(curve, p2) - var e = p2 + (testp - p2).normalized() * 2.0 - var nt = (testp - p2).cross(Vector3.UP).normalized() - curve.add_point(e + nt * 3.0 + Vector3.UP * 0.5, Vector3(), Vector3(), 0) - assert(test_curve(curve, p2)) - c.set_meta("curve", curve) - c.set_meta("curve_length", curve.get_baked_length()) # buildings diff --git a/project.godot b/project.godot index 684b821..bc8686d 100644 --- a/project.godot +++ b/project.godot @@ -8,6 +8,16 @@ config_version=4 +_global_script_classes=[ { +"base": "VoxelGeneratorScript", +"class": "TerrainData", +"language": "GDScript", +"path": "res://generator.gd" +} ] +_global_script_class_icons={ +"TerrainData": "" +} + [application] run/main_scene="res://world.tscn" diff --git a/scenes/vehicles/car.gd b/scenes/vehicles/car.gd index 0faa950..69f4c90 100644 --- a/scenes/vehicles/car.gd +++ b/scenes/vehicles/car.gd @@ -252,3 +252,5 @@ func is_upright(): # add_central_force(Vector3(0, -linear_velocity.y * delta * mass, 0)) # var l = linear_velocity.length() * delta # add_central_force(Vector3(0, -l * 0.5 * mass, 0)) +func set_lod(lod: int): + pass diff --git a/steering_test.gd b/steering_test.gd index e781cb7..d394c08 100644 --- a/steering_test.gd +++ b/steering_test.gd @@ -19,8 +19,9 @@ func _process(delta): var xt = $VehicleBody.global_transform.affine_inverse() var loc = xt.xform(tgt) $VehicleBody.steering = clamp(loc.x, -1, 1) - print(loc.x, " ", loc.z) + print(loc.x, " ", loc.z, $VehicleBody.linear_velocity) $Camera.look_at($VehicleBody.global_transform.origin, Vector3.UP) + print($VehicleBody.linear_velocity) match state: 0: $VehicleBody.engine_force = 2000 diff --git a/steering_test.tscn b/steering_test.tscn index bb964e6..b574382 100644 --- a/steering_test.tscn +++ b/steering_test.tscn @@ -52,14 +52,14 @@ transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 2.07902, 0, -0.0847001 ) transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -3.18049, 0, -0.0847001 ) [node name="target" type="Spatial" parent="."] -transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -3.18049, 0, 3.45624 ) +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.188565, 0, 4.49007 ) [node name="MeshInstance" type="MeshInstance" parent="target"] mesh = SubResource( 3 ) material/0 = null [node name="VehicleBody" type="VehicleBody" parent="."] -transform = Transform( -0.000366807, 0, -1, 0, 1, 0, 1, 0, -0.000366807, 0, 1.45468, 0 ) +transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.45468, 0 ) mass = 2000.0 [node name="MeshInstance" type="MeshInstance" parent="VehicleBody"]