Implemented structure relocation
This commit is contained in:
203
godot/main/editor.gd
Normal file
203
godot/main/editor.gd
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
extends Spatial
|
||||||
|
|
||||||
|
var camera_mode = -1
|
||||||
|
|
||||||
|
onready var vmode = {
|
||||||
|
2: $"%v_buildings",
|
||||||
|
3: $"%v_navigation",
|
||||||
|
5: $"%v_poi",
|
||||||
|
6: $"%v_road_lines",
|
||||||
|
7: $"%v_npc",
|
||||||
|
}
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
for b in [
|
||||||
|
$"%select_buildings",
|
||||||
|
$"%select_navigation",
|
||||||
|
$"%select_poi",
|
||||||
|
$"%select_road_lines",
|
||||||
|
$"%select_npc",
|
||||||
|
]:
|
||||||
|
b.connect("pressed", $WorldEditor, "editor_command", [b.name, []])
|
||||||
|
$WorldEditor.connect("editor_event", self, "editor_event")
|
||||||
|
for k in vmode.keys():
|
||||||
|
vmode[k].hide()
|
||||||
|
$building_cursor.hide()
|
||||||
|
|
||||||
|
func editor_event(evname: String, args: Array):
|
||||||
|
print(evname, args)
|
||||||
|
if evname == "mode_change_pre":
|
||||||
|
var mode_prev = args[0]
|
||||||
|
if mode_prev == -1:
|
||||||
|
for k in vmode.keys():
|
||||||
|
vmode[k].hide()
|
||||||
|
elif vmode.has(mode_prev):
|
||||||
|
vmode[mode_prev].hide()
|
||||||
|
elif evname == "mode_change_post":
|
||||||
|
var mode_next = args[1]
|
||||||
|
if vmode.has(mode_next):
|
||||||
|
vmode[mode_next].show()
|
||||||
|
elif evname == "result:get_closest_building":
|
||||||
|
print(evname, args)
|
||||||
|
select_building(args[0], args[3])
|
||||||
|
else:
|
||||||
|
breakpoint
|
||||||
|
var selected_building
|
||||||
|
var selected_building_xform
|
||||||
|
func select_building(xform, id):
|
||||||
|
selected_building = id
|
||||||
|
selected_building_xform = xform
|
||||||
|
print("selected id: ", id)
|
||||||
|
if !$building_cursor.visible:
|
||||||
|
$building_cursor.show()
|
||||||
|
$building_cursor.global_transform.origin = xform.origin
|
||||||
|
func _process(delta):
|
||||||
|
if Input.is_action_just_pressed("editor_cam1"):
|
||||||
|
setup_cam1()
|
||||||
|
if Input.is_action_just_pressed("editor_cam2"):
|
||||||
|
setup_cam2()
|
||||||
|
if Input.is_action_just_pressed("editor_cam3"):
|
||||||
|
setup_cam3()
|
||||||
|
if dragging:
|
||||||
|
if !Input.is_action_pressed("mouse1"):
|
||||||
|
dragging = false
|
||||||
|
drag_delay = 0.2
|
||||||
|
else:
|
||||||
|
var position = get_viewport().get_mouse_position()
|
||||||
|
var camera = get_viewport().get_camera()
|
||||||
|
var start = camera.project_ray_origin(position)
|
||||||
|
var normal = camera.project_ray_normal(position)
|
||||||
|
var end = start + normal * camera.get_zfar()
|
||||||
|
var space_state = get_world().direct_space_state
|
||||||
|
var result = space_state.intersect_ray(start, end, [], 1 << 15, false, true)
|
||||||
|
if result.has("collider"):
|
||||||
|
var proj = result.position
|
||||||
|
if $"%buildings_edit_mode".selected == 1:
|
||||||
|
print(proj)
|
||||||
|
var newpos = proj
|
||||||
|
newpos.x = stepify(newpos.x, 2.0)
|
||||||
|
newpos.z = stepify(newpos.z, 2.0)
|
||||||
|
var gen: VoxelGeneratorImgMapper = $VoxelLodTerrain.generator
|
||||||
|
var hpos = gen.get_height_full(newpos)
|
||||||
|
newpos.y = hpos
|
||||||
|
$WorldEditor.editor_command("update_building_transform", [selected_building, Transform(selected_building_xform.basis, newpos)])
|
||||||
|
selected_building_xform = Transform(selected_building_xform.basis, newpos)
|
||||||
|
$building_cursor.global_transform.origin = newpos
|
||||||
|
var motion = Vector2()
|
||||||
|
var old_mouse_pos = Vector2(-1, -1)
|
||||||
|
var rotation_y = 0
|
||||||
|
var dragging = false
|
||||||
|
var drag_delay = 0.2
|
||||||
|
var drag_start = Vector3()
|
||||||
|
func _unhandled_input(event):
|
||||||
|
var editor_mode = $WorldEditor.get_current_mode()
|
||||||
|
if camera_mode in [2, 3]:
|
||||||
|
if event is InputEventMouseMotion:
|
||||||
|
motion = event.relative
|
||||||
|
if camera_mode == 3:
|
||||||
|
match editor_mode:
|
||||||
|
2:
|
||||||
|
check_edit_building()
|
||||||
|
func check_edit_building():
|
||||||
|
if Input.is_action_just_pressed("mouse1"):
|
||||||
|
var position = get_viewport().get_mouse_position()
|
||||||
|
# var proj = get_viewport().get_camera().project_position(position, $cam.global_transform.origin.y + position.y * 0.5)
|
||||||
|
# print(position, proj)
|
||||||
|
# proj = get_viewport().get_camera().project_ray_origin(position)
|
||||||
|
# proj.y = 0
|
||||||
|
# proj.x = stepify(proj.x, 100.0)
|
||||||
|
# proj.z = stepify(proj.z, 100.0)
|
||||||
|
# var mouse_pos = get_viewport().get_mouse_position()
|
||||||
|
var camera = get_viewport().get_camera()
|
||||||
|
var start = camera.project_ray_origin(position)
|
||||||
|
var normal = camera.project_ray_normal(position)
|
||||||
|
var end = start + normal * camera.get_zfar()
|
||||||
|
var space_state = get_world().direct_space_state
|
||||||
|
var result = space_state.intersect_ray(start, end, [], 1 << 15, false, true)
|
||||||
|
if result.has("collider"):
|
||||||
|
var proj = result.position
|
||||||
|
if $"%buildings_edit_mode".selected == 0:
|
||||||
|
print("get closest building")
|
||||||
|
$WorldEditor.editor_command("get_closest_building", [Transform(Basis(), proj)])
|
||||||
|
elif Input.is_action_pressed("mouse1"):
|
||||||
|
if $"%buildings_edit_mode".selected == 1:
|
||||||
|
if drag_delay < 0.0:
|
||||||
|
dragging = true
|
||||||
|
var position = get_viewport().get_mouse_position()
|
||||||
|
var camera = get_viewport().get_camera()
|
||||||
|
var start = camera.project_ray_origin(position)
|
||||||
|
var normal = camera.project_ray_normal(position)
|
||||||
|
var end = start + normal * camera.get_zfar()
|
||||||
|
var space_state = get_world().direct_space_state
|
||||||
|
var result = space_state.intersect_ray(start, end, [], 1 << 15, false, true)
|
||||||
|
if result.has("collider"):
|
||||||
|
var proj = result.position
|
||||||
|
if $"%buildings_edit_mode".selected == 1:
|
||||||
|
drag_start = proj
|
||||||
|
else:
|
||||||
|
drag_delay -= get_process_delta_time()
|
||||||
|
else:
|
||||||
|
dragging = false
|
||||||
|
drag_delay = 0.2
|
||||||
|
else:
|
||||||
|
dragging = false
|
||||||
|
drag_delay = 0.2
|
||||||
|
func _physics_process(delta):
|
||||||
|
var editor_mode = $WorldEditor.get_current_mode()
|
||||||
|
if camera_mode == 1:
|
||||||
|
var mouse_pos = get_viewport().get_mouse_position()
|
||||||
|
if old_mouse_pos.x < 0:
|
||||||
|
old_mouse_pos = mouse_pos
|
||||||
|
motion = Vector2()
|
||||||
|
else:
|
||||||
|
motion = mouse_pos - old_mouse_pos
|
||||||
|
old_mouse_pos = mouse_pos
|
||||||
|
var moved = false
|
||||||
|
match camera_mode:
|
||||||
|
1:
|
||||||
|
var xx = Input.get_axis("left", "right")
|
||||||
|
var zz = Input.get_axis("backward", "forward")
|
||||||
|
var hh = Input.get_axis("action2", "action")
|
||||||
|
var h = $Camera.global_transform.origin.y
|
||||||
|
if abs(zz) > 0.1:
|
||||||
|
$Camera.global_transform.origin.z -= abs(h) * zz * delta
|
||||||
|
moved = true
|
||||||
|
if abs(xx) > 0.1:
|
||||||
|
$Camera.global_transform.origin.x += abs(h) * xx * delta
|
||||||
|
moved = true
|
||||||
|
if abs(hh) > 0.1 && abs(xx) < 0.1 && abs(zz) < 0.1:
|
||||||
|
$Camera.global_transform.origin.y += 10 * hh * delta
|
||||||
|
moved = true
|
||||||
|
2:
|
||||||
|
var h = $Camera.global_transform.origin.y
|
||||||
|
var xx = motion.x
|
||||||
|
$Camera.rotate_y(-xx * 0.005)
|
||||||
|
var offset = -$Camera.global_transform.basis.z * 10.0 * delta
|
||||||
|
offset.y = 0
|
||||||
|
var hh = Input.get_axis("action2", "action")
|
||||||
|
if abs(hh) > 0.1:
|
||||||
|
$Camera.global_transform.origin.y += 10 * hh * delta
|
||||||
|
moved = true
|
||||||
|
var zz = Input.get_axis("backward", "forward")
|
||||||
|
if abs(zz) > 0.1:
|
||||||
|
$Camera.global_transform.origin += zz * abs(h) * offset
|
||||||
|
moved = true
|
||||||
|
motion = Vector2()
|
||||||
|
if moved:
|
||||||
|
$Area.global_transform.origin.x = $Camera.global_transform.origin.x
|
||||||
|
$Area.global_transform.origin.z = $Camera.global_transform.origin.z
|
||||||
|
func setup_cam1():
|
||||||
|
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
|
||||||
|
camera_mode = 1
|
||||||
|
if camera_mode == -1:
|
||||||
|
$Camera.global_transform.origin.y = 80.0
|
||||||
|
$Camera.global_transform.basis = Basis().rotated(Vector3(1, 0, 0), -PI / 2.0)
|
||||||
|
func setup_cam2():
|
||||||
|
camera_mode = 2
|
||||||
|
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
|
||||||
|
if camera_mode == -1:
|
||||||
|
$Camera.global_transform.origin.y = 80.0
|
||||||
|
$Camera.global_transform.basis = Basis().rotated(Vector3(1, 0, 0), -PI / 4.0)
|
||||||
|
func setup_cam3():
|
||||||
|
camera_mode = 3
|
||||||
|
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
|
||||||
@@ -1,5 +1,244 @@
|
|||||||
[gd_scene format=2]
|
[gd_scene load_steps=14 format=2]
|
||||||
|
|
||||||
|
[ext_resource path="res://main/editor.gd" type="Script" id=1]
|
||||||
|
[ext_resource path="res://terrain/terrain_draw.png" type="Image" id=2]
|
||||||
|
[ext_resource path="res://terrain/terrain.png" type="Image" id=3]
|
||||||
|
[ext_resource path="res://terrain/terrain_edit.png" type="Image" id=4]
|
||||||
|
|
||||||
|
[sub_resource type="VoxelGeneratorImgMapper" id=5]
|
||||||
|
height_start = -150.0
|
||||||
|
height_range = 300.0
|
||||||
|
image_bg = ExtResource( 3 )
|
||||||
|
image_overlay = ExtResource( 4 )
|
||||||
|
image_draw = ExtResource( 2 )
|
||||||
|
|
||||||
|
[sub_resource type="VoxelMesherTransvoxel" id=6]
|
||||||
|
|
||||||
|
[sub_resource type="ORMSpatialMaterial" id=7]
|
||||||
|
albedo_color = Color( 0.254902, 0.886275, 0.101961, 1 )
|
||||||
|
|
||||||
|
[sub_resource type="ProceduralSky" id=4]
|
||||||
|
|
||||||
|
[sub_resource type="Environment" id=8]
|
||||||
|
background_mode = 2
|
||||||
|
background_sky = SubResource( 4 )
|
||||||
|
|
||||||
|
[sub_resource type="BoxShape" id=9]
|
||||||
|
extents = Vector3( 550, 0.1, 550 )
|
||||||
|
|
||||||
|
[sub_resource type="CubeMesh" id=10]
|
||||||
|
size = Vector3( 5, 120, 5 )
|
||||||
|
|
||||||
|
[sub_resource type="SpatialMaterial" id=11]
|
||||||
|
flags_transparent = true
|
||||||
|
albedo_color = Color( 0.698039, 0.192157, 0.101961, 0.427451 )
|
||||||
|
emission_enabled = true
|
||||||
|
emission = Color( 0.894118, 0.0980392, 0.0980392, 1 )
|
||||||
|
emission_energy = 1.0
|
||||||
|
emission_operator = 0
|
||||||
|
emission_on_uv2 = false
|
||||||
|
|
||||||
|
[sub_resource type="BoxShape" id=12]
|
||||||
|
extents = Vector3( 50, 1, 50 )
|
||||||
|
|
||||||
[node name="editor" type="Spatial"]
|
[node name="editor" type="Spatial"]
|
||||||
|
script = ExtResource( 1 )
|
||||||
|
|
||||||
[node name="WorldEditor" type="WorldEditor" parent="."]
|
[node name="WorldEditor" type="WorldEditor" parent="."]
|
||||||
|
|
||||||
|
[node name="VBoxContainer" type="VBoxContainer" parent="."]
|
||||||
|
anchor_left = 1.0
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
margin_left = -160.0
|
||||||
|
|
||||||
|
[node name="ColorRect" type="ColorRect" parent="VBoxContainer"]
|
||||||
|
margin_right = 160.0
|
||||||
|
margin_bottom = 30.0
|
||||||
|
rect_min_size = Vector2( 160, 30 )
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
size_flags_vertical = 5
|
||||||
|
color = Color( 0.25098, 0.25098, 0.25098, 1 )
|
||||||
|
|
||||||
|
[node name="Label" type="Label" parent="VBoxContainer/ColorRect"]
|
||||||
|
margin_left = 39.0
|
||||||
|
margin_top = 8.0
|
||||||
|
margin_right = 118.0
|
||||||
|
margin_bottom = 22.0
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
size_flags_vertical = 7
|
||||||
|
text = "Mode select"
|
||||||
|
align = 1
|
||||||
|
valign = 1
|
||||||
|
|
||||||
|
[node name="select_buildings" type="Button" parent="VBoxContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
margin_top = 34.0
|
||||||
|
margin_right = 160.0
|
||||||
|
margin_bottom = 54.0
|
||||||
|
text = "Buildings Mode"
|
||||||
|
|
||||||
|
[node name="select_navigation" type="Button" parent="VBoxContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
margin_top = 58.0
|
||||||
|
margin_right = 160.0
|
||||||
|
margin_bottom = 78.0
|
||||||
|
text = "Navigation Mode"
|
||||||
|
|
||||||
|
[node name="select_poi" type="Button" parent="VBoxContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
margin_top = 82.0
|
||||||
|
margin_right = 160.0
|
||||||
|
margin_bottom = 102.0
|
||||||
|
text = "POI Mode"
|
||||||
|
|
||||||
|
[node name="select_road_lines" type="Button" parent="VBoxContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
margin_top = 106.0
|
||||||
|
margin_right = 160.0
|
||||||
|
margin_bottom = 126.0
|
||||||
|
text = "Road Lines Mode"
|
||||||
|
|
||||||
|
[node name="select_npc" type="Button" parent="VBoxContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
margin_top = 130.0
|
||||||
|
margin_right = 160.0
|
||||||
|
margin_bottom = 150.0
|
||||||
|
text = "NPC Mode"
|
||||||
|
|
||||||
|
[node name="v_buildings" type="VBoxContainer" parent="VBoxContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
margin_top = 154.0
|
||||||
|
margin_right = 160.0
|
||||||
|
margin_bottom = 224.0
|
||||||
|
|
||||||
|
[node name="HSeparator" type="HSeparator" parent="VBoxContainer/v_buildings"]
|
||||||
|
margin_right = 160.0
|
||||||
|
margin_bottom = 4.0
|
||||||
|
|
||||||
|
[node name="Label" type="Label" parent="VBoxContainer/v_buildings"]
|
||||||
|
margin_top = 8.0
|
||||||
|
margin_right = 160.0
|
||||||
|
margin_bottom = 22.0
|
||||||
|
text = "Buildings mode"
|
||||||
|
|
||||||
|
[node name="buildings_edit_mode" type="OptionButton" parent="VBoxContainer/v_buildings"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
margin_top = 26.0
|
||||||
|
margin_right = 160.0
|
||||||
|
margin_bottom = 46.0
|
||||||
|
text = "Select"
|
||||||
|
items = [ "Select", null, false, 0, null, "Move", null, false, 1, null, "Rotate", null, false, 2, null ]
|
||||||
|
selected = 0
|
||||||
|
|
||||||
|
[node name="building_type" type="OptionButton" parent="VBoxContainer/v_buildings"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
margin_top = 50.0
|
||||||
|
margin_right = 160.0
|
||||||
|
margin_bottom = 70.0
|
||||||
|
text = "Building Type"
|
||||||
|
|
||||||
|
[node name="v_navigation" type="VBoxContainer" parent="VBoxContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
margin_top = 228.0
|
||||||
|
margin_right = 160.0
|
||||||
|
margin_bottom = 250.0
|
||||||
|
|
||||||
|
[node name="HSeparator" type="HSeparator" parent="VBoxContainer/v_navigation"]
|
||||||
|
margin_right = 160.0
|
||||||
|
margin_bottom = 4.0
|
||||||
|
|
||||||
|
[node name="Label" type="Label" parent="VBoxContainer/v_navigation"]
|
||||||
|
margin_top = 8.0
|
||||||
|
margin_right = 160.0
|
||||||
|
margin_bottom = 22.0
|
||||||
|
text = "Navigation mode"
|
||||||
|
|
||||||
|
[node name="v_poi" type="VBoxContainer" parent="VBoxContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
margin_top = 254.0
|
||||||
|
margin_right = 160.0
|
||||||
|
margin_bottom = 276.0
|
||||||
|
|
||||||
|
[node name="HSeparator" type="HSeparator" parent="VBoxContainer/v_poi"]
|
||||||
|
margin_right = 160.0
|
||||||
|
margin_bottom = 4.0
|
||||||
|
|
||||||
|
[node name="Label" type="Label" parent="VBoxContainer/v_poi"]
|
||||||
|
margin_top = 8.0
|
||||||
|
margin_right = 160.0
|
||||||
|
margin_bottom = 22.0
|
||||||
|
text = "POI mode"
|
||||||
|
|
||||||
|
[node name="v_road_lines" type="VBoxContainer" parent="VBoxContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
margin_top = 280.0
|
||||||
|
margin_right = 160.0
|
||||||
|
margin_bottom = 302.0
|
||||||
|
|
||||||
|
[node name="HSeparator" type="HSeparator" parent="VBoxContainer/v_road_lines"]
|
||||||
|
margin_right = 160.0
|
||||||
|
margin_bottom = 4.0
|
||||||
|
|
||||||
|
[node name="Label" type="Label" parent="VBoxContainer/v_road_lines"]
|
||||||
|
margin_top = 8.0
|
||||||
|
margin_right = 160.0
|
||||||
|
margin_bottom = 22.0
|
||||||
|
text = "Road Lines mode"
|
||||||
|
|
||||||
|
[node name="v_npc" type="VBoxContainer" parent="VBoxContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
margin_top = 306.0
|
||||||
|
margin_right = 160.0
|
||||||
|
margin_bottom = 328.0
|
||||||
|
|
||||||
|
[node name="HSeparator" type="HSeparator" parent="VBoxContainer/v_npc"]
|
||||||
|
margin_right = 160.0
|
||||||
|
margin_bottom = 4.0
|
||||||
|
|
||||||
|
[node name="Label" type="Label" parent="VBoxContainer/v_npc"]
|
||||||
|
margin_top = 8.0
|
||||||
|
margin_right = 160.0
|
||||||
|
margin_bottom = 22.0
|
||||||
|
text = "NPC mode"
|
||||||
|
|
||||||
|
[node name="StreamWorld" type="StreamWorld" parent="."]
|
||||||
|
|
||||||
|
[node name="VoxelLodTerrain" type="VoxelLodTerrain" parent="."]
|
||||||
|
generator = SubResource( 5 )
|
||||||
|
mesher = SubResource( 6 )
|
||||||
|
voxel_bounds = AABB( -5.36871e+08, -2048, -5.36871e+08, 1.07374e+09, 4096, 1.07374e+09 )
|
||||||
|
lod_count = 5
|
||||||
|
material = SubResource( 7 )
|
||||||
|
|
||||||
|
[node name="Camera" type="Camera" parent="."]
|
||||||
|
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0 )
|
||||||
|
environment = SubResource( 8 )
|
||||||
|
far = 1000.0
|
||||||
|
|
||||||
|
[node name="VoxelViewer" type="VoxelViewer" parent="Camera"]
|
||||||
|
|
||||||
|
[node name="DirectionalLight" type="DirectionalLight" parent="."]
|
||||||
|
transform = Transform( 1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 2, 0 )
|
||||||
|
|
||||||
|
[node name="Area" type="Area" parent="."]
|
||||||
|
collision_layer = 32768
|
||||||
|
collision_mask = 32768
|
||||||
|
monitoring = false
|
||||||
|
|
||||||
|
[node name="CollisionShape" type="CollisionShape" parent="Area"]
|
||||||
|
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.1, 0 )
|
||||||
|
shape = SubResource( 9 )
|
||||||
|
|
||||||
|
[node name="building_cursor" type="MeshInstance" parent="."]
|
||||||
|
mesh = SubResource( 10 )
|
||||||
|
material/0 = SubResource( 11 )
|
||||||
|
|
||||||
|
[node name="Area" type="Area" parent="building_cursor"]
|
||||||
|
collision_layer = 32768
|
||||||
|
collision_mask = 32768
|
||||||
|
monitoring = false
|
||||||
|
|
||||||
|
[node name="CollisionShape" type="CollisionShape" parent="building_cursor/Area"]
|
||||||
|
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -2, 0 )
|
||||||
|
shape = SubResource( 12 )
|
||||||
|
|||||||
@@ -35,6 +35,36 @@ right={
|
|||||||
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":68,"unicode":0,"echo":false,"script":null)
|
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":68,"unicode":0,"echo":false,"script":null)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
editor_cam1={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":49,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
action={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":69,"unicode":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
action2={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":0,"physical_scancode":81,"unicode":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
editor_cam2={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":50,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
editor_cam3={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":51,"physical_scancode":0,"unicode":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
mouse1={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [ Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"button_mask":0,"position":Vector2( 0, 0 ),"global_position":Vector2( 0, 0 ),"factor":1.0,"button_index":1,"canceled":false,"pressed":false,"doubleclick":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
[rendering]
|
[rendering]
|
||||||
|
|
||||||
|
|||||||
Submodule src/godot updated: 1bfb788c4f...2cc5ca43ef
@@ -30,6 +30,7 @@ void StreamWorld::read_buildings_json(const String &buildings_path)
|
|||||||
while (e) {
|
while (e) {
|
||||||
struct building b;
|
struct building b;
|
||||||
String key = e->get();
|
String key = e->get();
|
||||||
|
b.key = key;
|
||||||
b.id = json[key].get("id");
|
b.id = json[key].get("id");
|
||||||
if (b.id == "empty") {
|
if (b.id == "empty") {
|
||||||
e = e->next();
|
e = e->next();
|
||||||
@@ -277,6 +278,67 @@ void StreamWorld::update_items()
|
|||||||
|
|
||||||
void StreamWorld::run_command(const String &command, const Array &args)
|
void StreamWorld::run_command(const String &command, const Array &args)
|
||||||
{
|
{
|
||||||
|
if (command == "get_closest_building") {
|
||||||
|
if (args.size() == 0) {
|
||||||
|
print_error("bad command: not enough args: " + command);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const Transform &xform = args[0];
|
||||||
|
int i;
|
||||||
|
float dst = Math_INF;
|
||||||
|
Transform ret;
|
||||||
|
String rkey;
|
||||||
|
int id = -1;
|
||||||
|
for (i = 0; i < (int)buildings.size(); i++) {
|
||||||
|
Vector3 o = xform.origin;
|
||||||
|
Vector3 m = buildings[i].xform.origin;
|
||||||
|
float mdst = o.distance_squared_to(m);
|
||||||
|
if (dst > mdst) {
|
||||||
|
ret = buildings[i].xform;
|
||||||
|
dst = mdst;
|
||||||
|
rkey = buildings[i].key;
|
||||||
|
id = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Array ret_data;
|
||||||
|
ret_data.resize(4);
|
||||||
|
ret_data[0] = ret;
|
||||||
|
ret_data[1] = dst;
|
||||||
|
ret_data[2] = rkey;
|
||||||
|
ret_data[3] = id;
|
||||||
|
emit_signal("command_result", command, ret_data);
|
||||||
|
} else if (command == "get_building_id_for_key") {
|
||||||
|
if (args.size() == 0) {
|
||||||
|
print_error("bad command: not enough args: " + command);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String key = args[1];
|
||||||
|
Array ret_data;
|
||||||
|
ret_data.resize(1);
|
||||||
|
int id = -1, i;
|
||||||
|
for (i = 0; i < (int)buildings.size(); i++)
|
||||||
|
if (buildings[i].key == key) {
|
||||||
|
id = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ret_data[0] = id;
|
||||||
|
emit_signal("command_result", command, ret_data);
|
||||||
|
} else if (command == "update_building_transform") {
|
||||||
|
if (args.size() == 0) {
|
||||||
|
print_error("bad command: not enough args: " + command);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int id = args[0];
|
||||||
|
if (id < 0 || id >= (int)buildings.size())
|
||||||
|
return;
|
||||||
|
String key = buildings[id].key;
|
||||||
|
buildings[id].xform == args[1];
|
||||||
|
Spatial *bnode = Object::cast_to<Spatial>(item_nodes[id]);
|
||||||
|
bnode->set_global_transform(args[1]);
|
||||||
|
VariantWriter::write_to_string(buildings[id].xform, key);
|
||||||
|
buildings[id].key = key;
|
||||||
|
} else
|
||||||
|
print_error("No command " + command);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StreamWorld::_notification(int which)
|
void StreamWorld::_notification(int which)
|
||||||
@@ -287,6 +349,8 @@ void StreamWorld::_notification(int which)
|
|||||||
case NOTIFICATION_EXIT_WORLD:
|
case NOTIFICATION_EXIT_WORLD:
|
||||||
break;
|
break;
|
||||||
case NOTIFICATION_ENTER_TREE:
|
case NOTIFICATION_ENTER_TREE:
|
||||||
|
if (Engine::get_singleton()->is_editor_hint())
|
||||||
|
break;
|
||||||
if (initialized) {
|
if (initialized) {
|
||||||
if (Engine::get_singleton()->is_editor_hint())
|
if (Engine::get_singleton()->is_editor_hint())
|
||||||
current_scene = Object::cast_to<Node>(this);
|
current_scene = Object::cast_to<Node>(this);
|
||||||
@@ -303,6 +367,8 @@ void StreamWorld::_notification(int which)
|
|||||||
case NOTIFICATION_EXIT_TREE:
|
case NOTIFICATION_EXIT_TREE:
|
||||||
break;
|
break;
|
||||||
case NOTIFICATION_PROCESS: {
|
case NOTIFICATION_PROCESS: {
|
||||||
|
if (Engine::get_singleton()->is_editor_hint())
|
||||||
|
break;
|
||||||
update_view();
|
update_view();
|
||||||
const String *key = scenes.next(nullptr);
|
const String *key = scenes.next(nullptr);
|
||||||
while (key) {
|
while (key) {
|
||||||
@@ -337,6 +403,9 @@ void StreamWorld::_bind_methods()
|
|||||||
&StreamWorld::viewer_dead);
|
&StreamWorld::viewer_dead);
|
||||||
ClassDB::bind_method(D_METHOD("run_command", "command", "args"),
|
ClassDB::bind_method(D_METHOD("run_command", "command", "args"),
|
||||||
&StreamWorld::run_command);
|
&StreamWorld::run_command);
|
||||||
|
ADD_SIGNAL(MethodInfo("command_result",
|
||||||
|
PropertyInfo(Variant::STRING, "result_name"),
|
||||||
|
PropertyInfo(Variant::ARRAY, "args")));
|
||||||
}
|
}
|
||||||
|
|
||||||
StreamWorld::StreamWorld()
|
StreamWorld::StreamWorld()
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ private:
|
|||||||
Node *current_scene;
|
Node *current_scene;
|
||||||
struct building {
|
struct building {
|
||||||
String id;
|
String id;
|
||||||
|
String key;
|
||||||
Transform xform;
|
Transform xform;
|
||||||
AABB aabb;
|
AABB aabb;
|
||||||
};
|
};
|
||||||
@@ -57,10 +58,11 @@ private:
|
|||||||
void unload_building(int id);
|
void unload_building(int id);
|
||||||
void request_item(int type, int item);
|
void request_item(int type, int item);
|
||||||
void update_items();
|
void update_items();
|
||||||
void run_command(const String &command, const Array &args);
|
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
void run_command(const String &command, const Array &args);
|
||||||
StreamWorld();
|
StreamWorld();
|
||||||
~StreamWorld();
|
~StreamWorld();
|
||||||
static void cleanup();
|
static void cleanup();
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
#include <core/object.h>
|
#include <core/object.h>
|
||||||
|
#include <core/engine.h>
|
||||||
#include <scene/gui/control.h>
|
#include <scene/gui/control.h>
|
||||||
#include <scene/gui/box_container.h>
|
#include <scene/gui/box_container.h>
|
||||||
#include <scene/gui/button.h>
|
#include <scene/gui/button.h>
|
||||||
|
#include <scene/scene_string_names.h>
|
||||||
#include "world_editor.h"
|
#include "world_editor.h"
|
||||||
|
|
||||||
WorldEditor::WorldEditor()
|
WorldEditor::WorldEditor()
|
||||||
: Spatial()
|
: Spatial()
|
||||||
, stream_world(nullptr)
|
, stream_world(nullptr)
|
||||||
, editor_menu(nullptr)
|
, editor_menu(nullptr)
|
||||||
|
, current_mode(-1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,9 +73,16 @@ static std::unordered_map<String, int, StringHasher> modes = {
|
|||||||
};
|
};
|
||||||
void WorldEditor::tools_button(const String &button)
|
void WorldEditor::tools_button(const String &button)
|
||||||
{
|
{
|
||||||
|
Array change;
|
||||||
|
change.resize(2);
|
||||||
print_line("tools_button: " + button);
|
print_line("tools_button: " + button);
|
||||||
if (modes.find(button) == modes.end())
|
if (modes.find(button) == modes.end())
|
||||||
goto end;
|
goto end;
|
||||||
|
if (current_mode == modes[button])
|
||||||
|
goto end;
|
||||||
|
change[0] = current_mode;
|
||||||
|
change[1] = modes[button];
|
||||||
|
emit_signal("editor_event", "mode_change_pre", change);
|
||||||
switch (modes[button]) {
|
switch (modes[button]) {
|
||||||
case MODE_BUILDINGS:
|
case MODE_BUILDINGS:
|
||||||
mode_buildings();
|
mode_buildings();
|
||||||
@@ -90,82 +100,89 @@ void WorldEditor::tools_button(const String &button)
|
|||||||
mode_npc();
|
mode_npc();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
emit_signal("editor_event", "mode_change_post", change);
|
||||||
|
current_mode = modes[button];
|
||||||
end:;
|
end:;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CREATE_TOOLS_BUTTON(bname, btext) \
|
void WorldEditor::editor_command(const String &command, const Array &args)
|
||||||
{ \
|
|
||||||
Vector<Variant> binds; \
|
|
||||||
binds.push_back(#bname); \
|
|
||||||
Button *bname = memnew(Button); \
|
|
||||||
bname->set_name(#bname); \
|
|
||||||
bname->set_text(btext); \
|
|
||||||
bname->set_custom_minimum_size(Vector2(188, 16)); \
|
|
||||||
bname->connect("pressed", this, "tools_button", binds); \
|
|
||||||
tools->add_child(bname); \
|
|
||||||
bname->update(); \
|
|
||||||
tools->update(); \
|
|
||||||
}
|
|
||||||
void WorldEditor::create_menu()
|
|
||||||
{
|
{
|
||||||
editor_menu = memnew(Control);
|
print_line("running command: " + command);
|
||||||
editor_menu->set_name("menu");
|
if (command.begins_with("select_") &&
|
||||||
editor_menu->set_anchor(MARGIN_LEFT, 1.0f);
|
modes.find(command) != modes.end()) {
|
||||||
editor_menu->set_anchor(MARGIN_RIGHT, 1.0f);
|
tools_button(command);
|
||||||
editor_menu->set_anchor(MARGIN_BOTTOM, 1.0f);
|
return;
|
||||||
editor_menu->set_anchor(MARGIN_TOP, 0.0f);
|
} else if (command == "get_closest_building") {
|
||||||
editor_menu->update();
|
if (stream_world) {
|
||||||
VBoxContainer *tools = memnew(VBoxContainer);
|
stream_world->run_command(command, args);
|
||||||
Vector2 min_size = tools->get_minimum_size();
|
}
|
||||||
min_size.x = 200.0f;
|
} else if (command == "update_building_transform") {
|
||||||
min_size.y = 400.0f;
|
if (stream_world) {
|
||||||
tools->set_custom_minimum_size(min_size);
|
stream_world->run_command(command, args);
|
||||||
tools->set_name("tools");
|
}
|
||||||
tools->set_anchor_and_margin(MARGIN_LEFT, 1.0f, -210.0f);
|
}
|
||||||
tools->set_anchor_and_margin(MARGIN_RIGHT, 1.0f, 0.0f);
|
|
||||||
tools->set_anchor_and_margin(MARGIN_BOTTOM, 1.0f, 0.0f);
|
|
||||||
tools->set_anchor_and_margin(MARGIN_TOP, 0.0f, 0.0f);
|
|
||||||
tools->set_mouse_filter(Control::MOUSE_FILTER_STOP);
|
|
||||||
editor_menu->add_child(tools);
|
|
||||||
|
|
||||||
CREATE_TOOLS_BUTTON(select_buildings, "Select Buildings");
|
|
||||||
CREATE_TOOLS_BUTTON(select_navigation, "Select Navigation");
|
|
||||||
CREATE_TOOLS_BUTTON(select_poi, "Select POI");
|
|
||||||
CREATE_TOOLS_BUTTON(select_road_lines, "Select Road Lines");
|
|
||||||
CREATE_TOOLS_BUTTON(select_npc, "Select NPC");
|
|
||||||
editor_menu->update();
|
|
||||||
tools->update();
|
|
||||||
editor_menu->update();
|
|
||||||
tools->update();
|
|
||||||
print_line("Created menu");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Control *WorldEditor::get_editor_menu()
|
int WorldEditor::get_current_mode() const
|
||||||
{
|
{
|
||||||
if (!is_inside_tree())
|
return current_mode;
|
||||||
return nullptr;
|
}
|
||||||
if (!editor_menu)
|
|
||||||
create_menu();
|
StreamWorld *WorldEditor::get_stream_world()
|
||||||
return editor_menu;
|
{
|
||||||
|
return stream_world;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldEditor::world_command_result(const String &what, const Array &data)
|
||||||
|
{
|
||||||
|
print_line("what: " + what);
|
||||||
|
emit_signal("editor_event", "result:" + what, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldEditor::_notification(int which)
|
void WorldEditor::_notification(int which)
|
||||||
{
|
{
|
||||||
switch (which) {
|
switch (which) {
|
||||||
case NOTIFICATION_ENTER_TREE: {
|
case NOTIFICATION_ENTER_TREE: {
|
||||||
Control *c = get_editor_menu();
|
Node *base = get_parent();
|
||||||
if (c)
|
int count = base->get_child_count();
|
||||||
add_child(c);
|
int i;
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
Node *node = base->get_child(i);
|
||||||
|
StreamWorld *sw = Object::cast_to<StreamWorld>(node);
|
||||||
|
if (sw && !stream_world &&
|
||||||
|
!Engine::get_singleton()->is_editor_hint()) {
|
||||||
|
stream_world = sw;
|
||||||
|
sw->connect(SceneStringNames::get_singleton()
|
||||||
|
->tree_exiting,
|
||||||
|
this, "world_exited");
|
||||||
|
sw->connect("command_result", this,
|
||||||
|
"world_command_result");
|
||||||
|
}
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
case NOTIFICATION_EXIT_TREE:
|
case NOTIFICATION_EXIT_TREE:
|
||||||
if (editor_menu)
|
|
||||||
editor_menu->queue_delete();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WorldEditor::world_exited()
|
||||||
|
{
|
||||||
|
stream_world = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
void WorldEditor::_bind_methods()
|
void WorldEditor::_bind_methods()
|
||||||
{
|
{
|
||||||
ClassDB::bind_method(D_METHOD("tools_button", "button"),
|
ClassDB::bind_method(D_METHOD("editor_command", "command", "args"),
|
||||||
&WorldEditor::tools_button);
|
&WorldEditor::editor_command);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_current_mode"),
|
||||||
|
&WorldEditor::get_current_mode);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_stream_world"),
|
||||||
|
&WorldEditor::get_stream_world);
|
||||||
|
ClassDB::bind_method(D_METHOD("world_exited"),
|
||||||
|
&WorldEditor::world_exited);
|
||||||
|
ClassDB::bind_method(D_METHOD("world_command_result", "what", "data"),
|
||||||
|
&WorldEditor::world_command_result);
|
||||||
|
ADD_SIGNAL(MethodInfo("editor_event",
|
||||||
|
PropertyInfo(Variant::STRING, "event_name"),
|
||||||
|
PropertyInfo(Variant::ARRAY, "args")));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,12 +13,18 @@ protected:
|
|||||||
void mode_poi();
|
void mode_poi();
|
||||||
void mode_road_lines();
|
void mode_road_lines();
|
||||||
void mode_npc();
|
void mode_npc();
|
||||||
void tools_button(const String &which);
|
void tools_button(const String &button);
|
||||||
void create_menu();
|
void editor_command(const String &command, const Array &args);
|
||||||
Control *get_editor_menu();
|
int get_current_mode() const;
|
||||||
|
StreamWorld *get_stream_world();
|
||||||
|
void world_command_result(const String &what, const Array &data);
|
||||||
void _notification(int which);
|
void _notification(int which);
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void world_exited();
|
||||||
|
int current_mode;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
WorldEditor();
|
WorldEditor();
|
||||||
~WorldEditor();
|
~WorldEditor();
|
||||||
|
|||||||
Reference in New Issue
Block a user