initial commit
This commit is contained in:
@ -0,0 +1,56 @@
|
||||
# MIT License
|
||||
#
|
||||
# Copyright (c) 2023 Mark McKay
|
||||
# https://github.com/blackears/cyclopsLevelBuilder
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
@tool
|
||||
class_name CommandMaterialDockAddMaterials
|
||||
extends CyclopsCommand
|
||||
|
||||
#Public
|
||||
var res_path_list:Array[String]
|
||||
|
||||
#Private
|
||||
var old_res_path_list:Array[String]
|
||||
|
||||
|
||||
func _init():
|
||||
command_name = "Add materials"
|
||||
|
||||
func do_it():
|
||||
# print("Add Materials do_it")
|
||||
var mat_dock:MaterialPaletteViewport = builder.material_dock
|
||||
old_res_path_list = mat_dock.material_list.duplicate()
|
||||
|
||||
# print("old mat list %s" % str(old_res_path_list))
|
||||
|
||||
var new_list:Array[String] = old_res_path_list.duplicate()
|
||||
for mat in res_path_list:
|
||||
if !new_list.has(mat):
|
||||
new_list.append(mat)
|
||||
|
||||
# print("new mat list %s" % str(new_list))
|
||||
|
||||
mat_dock.set_materials(new_list)
|
||||
|
||||
func undo_it():
|
||||
var mat_dock:MaterialPaletteViewport = builder.material_dock
|
||||
mat_dock.set_materials(old_res_path_list)
|
@ -0,0 +1,52 @@
|
||||
# MIT License
|
||||
#
|
||||
# Copyright (c) 2023 Mark McKay
|
||||
# https://github.com/blackears/cyclopsLevelBuilder
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
@tool
|
||||
class_name CommandMaterialDockRemoveMaterials
|
||||
extends CyclopsCommand
|
||||
|
||||
#Public
|
||||
var res_path_list:Array[String]
|
||||
|
||||
#Private
|
||||
var old_res_path_list:Array[String]
|
||||
|
||||
|
||||
func _init():
|
||||
command_name = "Remove materials"
|
||||
|
||||
func do_it():
|
||||
# print("Remove Materials do_it")
|
||||
|
||||
var mat_dock:MaterialPaletteViewport = builder.material_dock
|
||||
old_res_path_list = mat_dock.material_list.duplicate()
|
||||
|
||||
var new_list:Array[String] = old_res_path_list.duplicate()
|
||||
for mat in res_path_list:
|
||||
var idx:int = new_list.find(mat)
|
||||
new_list.remove_at(idx)
|
||||
mat_dock.set_materials(new_list)
|
||||
|
||||
func undo_it():
|
||||
var mat_dock:MaterialPaletteViewport = builder.material_dock
|
||||
mat_dock.set_materials(old_res_path_list)
|
@ -0,0 +1,191 @@
|
||||
# MIT License
|
||||
#
|
||||
# Copyright (c) 2023 Mark McKay
|
||||
# https://github.com/blackears/cyclopsLevelBuilder
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
@tool
|
||||
extends Control
|
||||
class_name MaterialPaletteViewport
|
||||
|
||||
@export var material_list:Array[String] = []
|
||||
|
||||
@export var thumbnail_group:ThumbnailGroup
|
||||
|
||||
var builder:CyclopsLevelBuilder
|
||||
#var undo_manager:UndoRedo
|
||||
|
||||
var has_mouse_focus:bool = false
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
# print("MaterialPaletteViewport")
|
||||
#undo_manager = UndoRedo.new()
|
||||
|
||||
update_thumbnails()
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(delta):
|
||||
pass
|
||||
|
||||
func _can_drop_data(at_position:Vector2, data:Variant):
|
||||
# print("_can_drop_data %s" % data)
|
||||
return typeof(data) == TYPE_DICTIONARY and data.has("type") and data["type"] == "files"
|
||||
|
||||
func _unhandled_input(event):
|
||||
if !has_mouse_focus:
|
||||
return
|
||||
|
||||
if event is InputEventKey:
|
||||
#print("key event %s" % str(event))
|
||||
var e:InputEventKey = event
|
||||
# if e.keycode == KEY_DELETE:
|
||||
if e.keycode == KEY_X:
|
||||
if e.pressed:
|
||||
# print("mat pal X")
|
||||
remove_selected_material()
|
||||
|
||||
accept_event()
|
||||
|
||||
func remove_selected_material():
|
||||
var cmd:CommandMaterialDockRemoveMaterials = CommandMaterialDockRemoveMaterials.new()
|
||||
cmd.builder = builder
|
||||
|
||||
for child in $VBoxContainer/ScrollContainer/HFlowContainer.get_children():
|
||||
if child.selected:
|
||||
cmd.res_path_list.append(child.material_path)
|
||||
|
||||
var undo_manager:EditorUndoRedoManager = builder.get_undo_redo()
|
||||
cmd.add_to_undo_manager(undo_manager)
|
||||
|
||||
func set_materials(res_path_list:Array[String]):
|
||||
material_list = res_path_list
|
||||
# print("set mat list %s" % str(material_list))
|
||||
update_thumbnails()
|
||||
|
||||
|
||||
func save_state(state:Dictionary):
|
||||
var substate:Dictionary = {}
|
||||
state["material_palette"] = substate
|
||||
|
||||
substate["materials"] = material_list.duplicate()
|
||||
|
||||
func load_state(state:Dictionary):
|
||||
if state == null || !state.has("material_palette"):
|
||||
return
|
||||
|
||||
var substate:Dictionary = state["material_palette"]
|
||||
|
||||
# print("load_state()")
|
||||
material_list = []
|
||||
if substate.has("materials"):
|
||||
for mat_path in substate["materials"]:
|
||||
if ResourceLoader.exists(mat_path):
|
||||
material_list.append(mat_path)
|
||||
|
||||
update_thumbnails()
|
||||
|
||||
func _drop_data(at_position, data):
|
||||
var files = data["files"]
|
||||
#print("--drop")
|
||||
var add_list:Array[String]
|
||||
for f in files:
|
||||
# print("Dropping %s" % f)
|
||||
var res:Resource = load(f)
|
||||
if res is Material:
|
||||
if !material_list.has(f):
|
||||
add_list.append(f)
|
||||
|
||||
|
||||
var cmd:CommandMaterialDockAddMaterials = CommandMaterialDockAddMaterials.new()
|
||||
cmd.builder = builder
|
||||
|
||||
cmd.res_path_list = add_list
|
||||
|
||||
var undo_manager:EditorUndoRedoManager = builder.get_undo_redo()
|
||||
cmd.add_to_undo_manager(undo_manager)
|
||||
|
||||
#print("drop data clear")
|
||||
#material_list.clear()
|
||||
|
||||
func update_thumbnails():
|
||||
# print("update_thumbnails()")
|
||||
var cur_sel:String
|
||||
|
||||
for child in $VBoxContainer/ScrollContainer/HFlowContainer.get_children():
|
||||
if child.selected:
|
||||
cur_sel = child.material_path
|
||||
break
|
||||
|
||||
for child in $VBoxContainer/ScrollContainer/HFlowContainer.get_children():
|
||||
#print("removing %s" % child.get_class())
|
||||
child.group = null
|
||||
$VBoxContainer/ScrollContainer/HFlowContainer.remove_child(child)
|
||||
child.queue_free()
|
||||
|
||||
for path in material_list:
|
||||
var res:Resource = preload("res://addons/cyclops_level_builder/docks/material_palette/material_thumbnail.tscn")
|
||||
var thumbnail:MaterialThumbnail = res.instantiate()
|
||||
thumbnail.builder = builder
|
||||
thumbnail.material_path = path
|
||||
thumbnail.group = thumbnail_group
|
||||
# print("adding mat %s" % path)
|
||||
|
||||
|
||||
$VBoxContainer/ScrollContainer/HFlowContainer.add_child(thumbnail)
|
||||
thumbnail.owner = self
|
||||
|
||||
if cur_sel:
|
||||
for child in $VBoxContainer/ScrollContainer/HFlowContainer.get_children():
|
||||
if child.material_path == cur_sel:
|
||||
child.selected = true
|
||||
break
|
||||
|
||||
|
||||
func _on_visibility_changed():
|
||||
#Control freezes for some reason when hidden and then shown, so just regenereate it
|
||||
if visible:
|
||||
update_thumbnails()
|
||||
|
||||
|
||||
|
||||
func _on_remove_all_materials_pressed():
|
||||
var cmd:CommandMaterialDockRemoveMaterials = CommandMaterialDockRemoveMaterials.new()
|
||||
cmd.builder = builder
|
||||
|
||||
cmd.res_path_list = material_list.duplicate()
|
||||
|
||||
var undo_manager:EditorUndoRedoManager = builder.get_undo_redo()
|
||||
cmd.add_to_undo_manager(undo_manager)
|
||||
|
||||
|
||||
|
||||
func _on_remove_sel_pressed():
|
||||
remove_selected_material()
|
||||
|
||||
|
||||
func _on_h_flow_container_mouse_entered():
|
||||
has_mouse_focus = true
|
||||
# print("_on_h_flow_container_mouse_entered()")
|
||||
|
||||
|
||||
func _on_h_flow_container_mouse_exited():
|
||||
has_mouse_focus = false
|
||||
# print("_on_h_flow_container_mouse_exited()")
|
@ -0,0 +1,60 @@
|
||||
[gd_scene load_steps=4 format=3 uid="uid://o1efx0qxc4n3"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/cyclops_level_builder/docks/material_palette/material_palette_viewport.gd" id="1_xyxg3"]
|
||||
[ext_resource type="Script" path="res://addons/cyclops_level_builder/docks/material_palette/thumbnail_group.gd" id="2_sg6yo"]
|
||||
|
||||
[sub_resource type="Resource" id="Resource_ljbow"]
|
||||
script = ExtResource("2_sg6yo")
|
||||
|
||||
[node name="Materials" type="Control"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_xyxg3")
|
||||
thumbnail_group = SubResource("Resource_ljbow")
|
||||
metadata/_edit_lock_ = true
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
metadata/_edit_lock_ = true
|
||||
|
||||
[node name="PanelContainer" type="PanelContainer" parent="VBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 0
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/PanelContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="remove_all_materials" type="Button" parent="VBoxContainer/PanelContainer/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 0
|
||||
text = "Remove All"
|
||||
|
||||
[node name="remove_sel" type="Button" parent="VBoxContainer/PanelContainer/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
tooltip_text = "Press X to removeselected material."
|
||||
text = "Remove Selected"
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="VBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
metadata/_edit_lock_ = true
|
||||
|
||||
[node name="HFlowContainer" type="HFlowContainer" parent="VBoxContainer/ScrollContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
|
||||
[connection signal="visibility_changed" from="." to="." method="_on_visibility_changed"]
|
||||
[connection signal="pressed" from="VBoxContainer/PanelContainer/HBoxContainer/remove_all_materials" to="." method="_on_remove_all_materials_pressed"]
|
||||
[connection signal="pressed" from="VBoxContainer/PanelContainer/HBoxContainer/remove_sel" to="." method="_on_remove_sel_pressed"]
|
||||
[connection signal="mouse_entered" from="VBoxContainer/ScrollContainer/HFlowContainer" to="." method="_on_h_flow_container_mouse_entered"]
|
||||
[connection signal="mouse_exited" from="VBoxContainer/ScrollContainer/HFlowContainer" to="." method="_on_h_flow_container_mouse_exited"]
|
@ -0,0 +1,52 @@
|
||||
# MIT License
|
||||
#
|
||||
# Copyright (c) 2023 Mark McKay
|
||||
# https://github.com/blackears/cyclopsLevelBuilder
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
|
||||
@tool
|
||||
extends SubViewport
|
||||
class_name MaterialShapshot
|
||||
|
||||
@export var target_material:Material:
|
||||
get:
|
||||
return target_material
|
||||
set(value):
|
||||
target_material = value
|
||||
$Node3D/MeshInstance3D.material_override = target_material
|
||||
|
||||
func take_snapshot()->ImageTexture:
|
||||
#print ("pre-grabbing image %s" % target_material.resource_path)
|
||||
await RenderingServer.frame_post_draw
|
||||
#print ("grabbing image %s" % target_material.resource_path)
|
||||
var image:Image = get_viewport().get_texture().get_image()
|
||||
var tex:ImageTexture = ImageTexture.create_from_image(image)
|
||||
return tex
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(delta):
|
||||
pass
|
@ -0,0 +1,30 @@
|
||||
[gd_scene load_steps=5 format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/cyclops_level_builder/docks/material_palette/material_snapshot.gd" id="1_c0jsn"]
|
||||
[ext_resource type="Material" uid="uid://rdhrhgrb78ls" path="res://addons/cyclops_level_builder/materials/grid.tres" id="2_q7d7x"]
|
||||
|
||||
[sub_resource type="QuadMesh" id="QuadMesh_o8jeg"]
|
||||
|
||||
[sub_resource type="Environment" id="Environment_p06d0"]
|
||||
|
||||
[node name="SubViewport" type="SubViewport"]
|
||||
own_world_3d = true
|
||||
size = Vector2i(64, 64)
|
||||
render_target_update_mode = 4
|
||||
script = ExtResource("1_c0jsn")
|
||||
|
||||
[node name="Node3D" type="Node3D" parent="."]
|
||||
|
||||
[node name="Camera3D" type="Camera3D" parent="Node3D"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1)
|
||||
projection = 1
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="Node3D"]
|
||||
mesh = SubResource("QuadMesh_o8jeg")
|
||||
surface_material_override/0 = ExtResource("2_q7d7x")
|
||||
|
||||
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="Node3D"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 4)
|
||||
|
||||
[node name="WorldEnvironment" type="WorldEnvironment" parent="Node3D"]
|
||||
environment = SubResource("Environment_p06d0")
|
@ -0,0 +1,166 @@
|
||||
# MIT License
|
||||
#
|
||||
# Copyright (c) 2023 Mark McKay
|
||||
# https://github.com/blackears/cyclopsLevelBuilder
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
@tool
|
||||
extends Control
|
||||
class_name MaterialThumbnail
|
||||
|
||||
@export var selected:bool = false
|
||||
|
||||
@export_file("*.tres") var material_path:String:
|
||||
get:
|
||||
return material_path
|
||||
set(value):
|
||||
if material_path == value:
|
||||
return
|
||||
|
||||
material_path = value
|
||||
|
||||
if ResourceLoader.exists(material_path):
|
||||
var res:Resource = load(material_path)
|
||||
#print("loaded res %s" % res)
|
||||
|
||||
if res is Material:
|
||||
tracked_material = res
|
||||
else:
|
||||
tracked_material = null
|
||||
else:
|
||||
tracked_material = null
|
||||
|
||||
material_thumbnail_dirty = true
|
||||
|
||||
@export var group:ThumbnailGroup:
|
||||
get:
|
||||
return group
|
||||
set(value):
|
||||
if group == value:
|
||||
return
|
||||
|
||||
if group != null:
|
||||
group.remove_thumbnail(self)
|
||||
|
||||
group = value
|
||||
|
||||
if group != null:
|
||||
group.add_thumbnail(self)
|
||||
|
||||
|
||||
@export var theme_normal:Theme
|
||||
@export var theme_selected:Theme
|
||||
|
||||
var builder:CyclopsLevelBuilder
|
||||
|
||||
var tracked_material:Material
|
||||
var material_thumbnail_dirty:bool = true
|
||||
|
||||
var snapper:MaterialShapshot
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
snapper = preload("res://addons/cyclops_level_builder/docks/material_palette/material_snapshot.tscn").instantiate()
|
||||
add_child(snapper)
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(delta):
|
||||
if selected:
|
||||
theme = theme_selected
|
||||
else:
|
||||
theme = theme_normal
|
||||
|
||||
if material_thumbnail_dirty:
|
||||
material_thumbnail_dirty = false
|
||||
|
||||
snapper.target_material = tracked_material
|
||||
|
||||
var tex:ImageTexture = await snapper.take_snapshot()
|
||||
$VBoxContainer/TextureRect.texture = tex
|
||||
|
||||
if tracked_material:
|
||||
var name:String = tracked_material.resource_name
|
||||
if name.is_empty():
|
||||
name = material_path.get_file()
|
||||
var idx:int = name.rfind(".")
|
||||
if idx != -1:
|
||||
name = name.substr(0, idx)
|
||||
$VBoxContainer/MaterialName.text = name
|
||||
else:
|
||||
$VBoxContainer/MaterialName.text = ""
|
||||
|
||||
|
||||
func _gui_input(event:InputEvent):
|
||||
if event is InputEventMouseButton:
|
||||
var e:InputEventMouseButton = event
|
||||
if e.pressed:
|
||||
if e.double_click:
|
||||
apply_material_to_selected()
|
||||
else:
|
||||
|
||||
if group:
|
||||
group.select_thumbnail(self)
|
||||
else:
|
||||
selected = true
|
||||
|
||||
builder.tool_material_path = material_path
|
||||
|
||||
get_viewport().set_input_as_handled()
|
||||
|
||||
|
||||
func apply_material_to_selected():
|
||||
var cmd:CommandSetMaterial = CommandSetMaterial.new()
|
||||
cmd.builder = builder
|
||||
cmd.material_path = material_path
|
||||
|
||||
var is_obj_mode:bool = builder.mode == CyclopsLevelBuilder.Mode.OBJECT
|
||||
|
||||
var root_blocks:CyclopsBlocks = builder.active_node
|
||||
for child in root_blocks.get_children():
|
||||
# print("child block %s %s" % [child.name, child.get_class()])
|
||||
# if child.has_method("append_mesh_wire"):
|
||||
if child is CyclopsConvexBlock:
|
||||
#if !(child is MeshInstance3D):
|
||||
# print("setting child block %s" % child.name)
|
||||
if child.selected:
|
||||
if is_obj_mode:
|
||||
cmd.add_target(child.get_path(), child.control_mesh.get_face_indices())
|
||||
else:
|
||||
var face_indices:PackedInt32Array = child.control_mesh.get_face_indices(true)
|
||||
if !face_indices.is_empty():
|
||||
cmd.add_target(child.get_path(), face_indices)
|
||||
|
||||
if cmd.will_change_anything():
|
||||
var undo:EditorUndoRedoManager = builder.get_undo_redo()
|
||||
cmd.add_to_undo_manager(undo)
|
||||
|
||||
|
||||
func _on_focus_entered():
|
||||
pass # Replace with function body.
|
||||
|
||||
|
||||
func _on_focus_exited():
|
||||
pass # Replace with function body.
|
||||
|
||||
|
||||
func _on_tree_exiting():
|
||||
if group != null:
|
||||
group.remove_thumbnail(self)
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,40 @@
|
||||
# MIT License
|
||||
#
|
||||
# Copyright (c) 2023 Mark McKay
|
||||
# https://github.com/blackears/cyclopsLevelBuilder
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
@tool
|
||||
extends Resource
|
||||
class_name ThumbnailGroup
|
||||
|
||||
var thumbnails:Array[MaterialThumbnail] = []
|
||||
|
||||
func select_thumbnail(obj:MaterialThumbnail):
|
||||
for t in thumbnails:
|
||||
t.selected = t == obj
|
||||
|
||||
func add_thumbnail(obj:MaterialThumbnail):
|
||||
thumbnails.append(obj)
|
||||
|
||||
func remove_thumbnail(obj:MaterialThumbnail):
|
||||
thumbnails.remove_at(thumbnails.find(obj))
|
||||
|
||||
|
@ -0,0 +1,17 @@
|
||||
[gd_resource type="Theme" load_steps=2 format=3 uid="uid://bx26luxdhj3jq"]
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_amf1g"]
|
||||
bg_color = Color(0, 0, 0, 1)
|
||||
border_width_left = 4
|
||||
border_width_top = 4
|
||||
border_width_right = 4
|
||||
border_width_bottom = 4
|
||||
border_color = Color(0, 0, 0, 1)
|
||||
border_blend = true
|
||||
corner_radius_top_left = 4
|
||||
corner_radius_top_right = 4
|
||||
corner_radius_bottom_right = 4
|
||||
corner_radius_bottom_left = 4
|
||||
|
||||
[resource]
|
||||
PanelContainer/styles/panel = SubResource("StyleBoxFlat_amf1g")
|
@ -0,0 +1,16 @@
|
||||
[gd_resource type="Theme" load_steps=2 format=3 uid="uid://c0gpl22e2g6ay"]
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_amf1g"]
|
||||
bg_color = Color(0, 0, 0, 1)
|
||||
border_width_left = 4
|
||||
border_width_top = 4
|
||||
border_width_right = 4
|
||||
border_width_bottom = 4
|
||||
border_color = Color(1, 0, 0, 1)
|
||||
corner_radius_top_left = 4
|
||||
corner_radius_top_right = 4
|
||||
corner_radius_bottom_right = 4
|
||||
corner_radius_bottom_left = 4
|
||||
|
||||
[resource]
|
||||
PanelContainer/styles/panel = SubResource("StyleBoxFlat_amf1g")
|
@ -0,0 +1,56 @@
|
||||
# MIT License
|
||||
#
|
||||
# Copyright (c) 2023 Mark McKay
|
||||
# https://github.com/blackears/cyclopsLevelBuilder
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
@tool
|
||||
extends Control
|
||||
class_name ToolPropertiesDock
|
||||
|
||||
var builder:CyclopsLevelBuilder
|
||||
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(delta):
|
||||
pass
|
||||
|
||||
func set_editor(control:Control):
|
||||
for child in $ScrollContainer.get_children():
|
||||
$ScrollContainer.remove_child(child)
|
||||
|
||||
if control:
|
||||
$ScrollContainer.add_child(control)
|
||||
|
||||
func save_state(state:Dictionary):
|
||||
var substate:Dictionary = {}
|
||||
state["tool_properties"] = substate
|
||||
|
||||
|
||||
func load_state(state:Dictionary):
|
||||
if state == null || !state.has("tool_properties"):
|
||||
return
|
||||
|
||||
var substate:Dictionary = state["tool_properties"]
|
@ -0,0 +1,20 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://caoy37s0y5a8y"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/cyclops_level_builder/docks/tool_properties/tool_properties_dock.gd" id="1_7262j"]
|
||||
|
||||
[node name="Tool Properties" type="Control"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_7262j")
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
@ -0,0 +1,79 @@
|
||||
# MIT License
|
||||
#
|
||||
# Copyright (c) 2023 Mark McKay
|
||||
# https://github.com/blackears/cyclopsLevelBuilder
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
@tool
|
||||
extends SubViewport
|
||||
class_name UvEditorPreview
|
||||
|
||||
|
||||
|
||||
@export var target_material:Material:
|
||||
get:
|
||||
return target_material
|
||||
set(value):
|
||||
target_material = value
|
||||
#$Node3D/MeshInstance3D.material_override = target_material
|
||||
#dirty = true
|
||||
# var studio:UvEditorPreviewStudio = get_node("UvPreviewStudio")
|
||||
# studio.target_material = target_material
|
||||
# if $UvPreviewStudio:
|
||||
# $UvPreviewStudio.target_material = target_material
|
||||
dirty = true
|
||||
|
||||
@export var uv_transform:Transform2D = Transform2D.IDENTITY:
|
||||
get:
|
||||
return uv_transform
|
||||
set(value):
|
||||
if value == uv_transform:
|
||||
return
|
||||
uv_transform = value
|
||||
# dirty = true
|
||||
# $UvPreviewStudio.uv_transform = uv_transform
|
||||
# var studio:UvEditorPreviewStudio = get_node("UvPreviewStudio")
|
||||
# studio.uv_transform = uv_transform
|
||||
# if $UvPreviewStudio:
|
||||
# $UvPreviewStudio.uv_transform = uv_transform
|
||||
dirty = true
|
||||
|
||||
var dirty:bool = true
|
||||
#var points:PackedVector3Array = [Vector3(0, 0, 0), Vector3(1, 1, 0), Vector3(1, 0, 0), Vector3(0, 1, 0)]
|
||||
|
||||
func take_snapshot()->ImageTexture:
|
||||
#print ("pre-grabbing image %s" % target_material.resource_path)
|
||||
await RenderingServer.frame_post_draw
|
||||
#print ("grabbing image %s" % target_material.resource_path)
|
||||
var image:Image = get_viewport().get_texture().get_image()
|
||||
var tex:ImageTexture = ImageTexture.create_from_image(image)
|
||||
return tex
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
pass # Replace with function body.
|
||||
|
||||
func _process(delta):
|
||||
if dirty:
|
||||
$UvPreviewStudio.target_material = target_material
|
||||
$UvPreviewStudio.uv_transform = uv_transform
|
||||
dirty = false
|
||||
|
||||
|
@ -0,0 +1,15 @@
|
||||
[gd_scene load_steps=4 format=3 uid="uid://bbfgpupliiqnm"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview.gd" id="1_57x0n"]
|
||||
[ext_resource type="Material" uid="uid://rdhrhgrb78ls" path="res://addons/cyclops_level_builder/materials/grid.tres" id="2_kxmas"]
|
||||
[ext_resource type="PackedScene" path="res://addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview_studio.tscn" id="3_7qfos"]
|
||||
|
||||
[node name="UvPreview" type="SubViewport"]
|
||||
own_world_3d = true
|
||||
size = Vector2i(256, 256)
|
||||
render_target_update_mode = 4
|
||||
script = ExtResource("1_57x0n")
|
||||
target_material = ExtResource("2_kxmas")
|
||||
|
||||
[node name="UvPreviewStudio" parent="." instance=ExtResource("3_7qfos")]
|
||||
target_material = ExtResource("2_kxmas")
|
@ -0,0 +1,67 @@
|
||||
# MIT License
|
||||
#
|
||||
# Copyright (c) 2023 Mark McKay
|
||||
# https://github.com/blackears/cyclopsLevelBuilder
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
@tool
|
||||
extends Node3D
|
||||
class_name UvEditorPreviewStudio
|
||||
|
||||
|
||||
@export var target_material:Material:
|
||||
get:
|
||||
return target_material
|
||||
set(value):
|
||||
target_material = value
|
||||
#$Node3D/MeshInstance3D.material_override = target_material
|
||||
dirty = true
|
||||
|
||||
@export var uv_transform:Transform2D = Transform2D.IDENTITY:
|
||||
get:
|
||||
return uv_transform
|
||||
set(value):
|
||||
if value == uv_transform:
|
||||
return
|
||||
uv_transform = value
|
||||
dirty = true
|
||||
|
||||
var dirty:bool = true
|
||||
var points:PackedVector3Array = [Vector3(-1, 1, 0), Vector3(1, 1, 0), Vector3(-1, -1, 0), Vector3(1, -1, 0)]
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(delta):
|
||||
# print("_process")
|
||||
if dirty:
|
||||
var mesh:ImmediateMesh = ImmediateMesh.new()
|
||||
|
||||
mesh.surface_begin(Mesh.PRIMITIVE_TRIANGLE_STRIP, target_material)
|
||||
|
||||
mesh.surface_set_normal(Vector3(0, 0, 1))
|
||||
for p in points:
|
||||
mesh.surface_set_uv(uv_transform * Vector2(p.x, -p.y))
|
||||
mesh.surface_add_vertex(p)
|
||||
|
||||
mesh.surface_end()
|
||||
|
||||
# print("Building preview mesh")
|
||||
$MeshInstance3D.mesh = mesh
|
||||
dirty = false
|
@ -0,0 +1,18 @@
|
||||
[gd_scene load_steps=3 format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/cyclops_level_builder/docks/uv_editor/uv_editor_preview_studio.gd" id="1_38c8p"]
|
||||
|
||||
[sub_resource type="ImmediateMesh" id="ImmediateMesh_23b3x"]
|
||||
|
||||
[node name="Node3D" type="Node3D"]
|
||||
script = ExtResource("1_38c8p")
|
||||
|
||||
[node name="Camera3D" type="Camera3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1)
|
||||
projection = 1
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
|
||||
mesh = SubResource("ImmediateMesh_23b3x")
|
||||
|
||||
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.0684279)
|
@ -0,0 +1,182 @@
|
||||
# MIT License
|
||||
#
|
||||
# Copyright (c) 2023 Mark McKay
|
||||
# https://github.com/blackears/cyclopsLevelBuilder
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
@tool
|
||||
extends Control
|
||||
class_name UvEdtiorViewport
|
||||
|
||||
var material_thumbnail_dirty:bool = true
|
||||
|
||||
var target_material:Material
|
||||
var empty_material:Material
|
||||
|
||||
var uv_transform:Transform2D = Transform2D.IDENTITY
|
||||
|
||||
var builder:CyclopsLevelBuilder:
|
||||
get:
|
||||
return builder
|
||||
set(value):
|
||||
if builder:
|
||||
builder.selection_changed.disconnect(on_selection_changed)
|
||||
|
||||
builder = value
|
||||
|
||||
if builder:
|
||||
builder.selection_changed.connect(on_selection_changed)
|
||||
|
||||
var spin_offset_x:NumbericLineEdit
|
||||
var spin_offset_y:NumbericLineEdit
|
||||
var spin_scale_x:NumbericLineEdit
|
||||
var spin_scale_y:NumbericLineEdit
|
||||
var spin_rotation:NumbericLineEdit
|
||||
var spin_skew:NumbericLineEdit
|
||||
|
||||
#var test_slider:EditorSpinSlider
|
||||
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready():
|
||||
empty_material = StandardMaterial3D.new()
|
||||
empty_material.albedo_color = Color.BLACK
|
||||
|
||||
spin_offset_x = $VBoxContainer/GridContainer2/HBoxContainer2/offset_x
|
||||
spin_offset_y = $VBoxContainer/GridContainer2/HBoxContainer/offset_y
|
||||
spin_scale_x = $VBoxContainer/GridContainer3/HBoxContainer2/scale_x
|
||||
spin_scale_y = $VBoxContainer/GridContainer3/HBoxContainer/scale_y
|
||||
spin_rotation = $VBoxContainer/GridContainer4/HBoxContainer2/rotation
|
||||
spin_skew = $VBoxContainer/GridContainer4/HBoxContainer/skew
|
||||
|
||||
# test_slider = EditorSpinSlider.new()
|
||||
# test_slider.size_flags_horizontal = Control.SIZE_EXPAND
|
||||
# $VBoxContainer.add_child(test_slider)
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(delta):
|
||||
|
||||
if material_thumbnail_dirty:
|
||||
material_thumbnail_dirty = false
|
||||
|
||||
$UvPreview.target_material = target_material
|
||||
$UvPreview.uv_transform = uv_transform
|
||||
|
||||
var tex:ImageTexture = await $UvPreview.take_snapshot()
|
||||
$VBoxContainer/Preview.texture = tex
|
||||
pass
|
||||
|
||||
func on_selection_changed():
|
||||
material_thumbnail_dirty = true
|
||||
target_material = empty_material
|
||||
|
||||
if builder.active_node:
|
||||
var block:CyclopsConvexBlock = builder.active_node.get_active_block()
|
||||
if block:
|
||||
var vol:ConvexVolume = block.control_mesh
|
||||
var face_idx = vol.active_face if vol.active_face != -1 else 0
|
||||
|
||||
var f:ConvexVolume.FaceInfo = vol.get_face(face_idx)
|
||||
|
||||
|
||||
spin_offset_x.value = f.uv_transform.origin.x
|
||||
spin_offset_y.value = f.uv_transform.origin.y
|
||||
spin_scale_x.value = f.uv_transform.get_scale().x
|
||||
spin_scale_y.value = f.uv_transform.get_scale().y
|
||||
spin_rotation.value = rad_to_deg(f.uv_transform.get_rotation())
|
||||
spin_skew.value = rad_to_deg(f.uv_transform.get_skew())
|
||||
|
||||
if f.material_id != -1:
|
||||
var mat:Material = block.materials[f.material_id]
|
||||
target_material = mat
|
||||
else:
|
||||
target_material = null
|
||||
|
||||
uv_transform = f.uv_transform
|
||||
|
||||
|
||||
|
||||
func save_state(state:Dictionary):
|
||||
var substate:Dictionary = {}
|
||||
state["uv_editor_dock"] = substate
|
||||
|
||||
# substate["materials"] = material_list.duplicate()
|
||||
|
||||
func load_state(state:Dictionary):
|
||||
if state == null || !state.has("uv_editor_dock"):
|
||||
return
|
||||
|
||||
var substate:Dictionary = state["uv_editor_dock"]
|
||||
|
||||
|
||||
func apply_uv_transform():
|
||||
var xform:Transform2D = Transform2D(deg_to_rad(spin_rotation.value), \
|
||||
Vector2(spin_scale_x.value, spin_scale_y.value), \
|
||||
deg_to_rad(spin_skew.value), \
|
||||
Vector2(spin_offset_x.value, spin_offset_y.value))
|
||||
|
||||
uv_transform = xform
|
||||
|
||||
var cmd:CommandSetUvTransform = CommandSetUvTransform.new()
|
||||
cmd.builder = builder
|
||||
cmd.uv_transform = xform
|
||||
|
||||
# print("setting xform %s " % xform)
|
||||
|
||||
if builder.active_node:
|
||||
for child in builder.active_node.get_children():
|
||||
if child is CyclopsConvexBlock:
|
||||
var block:CyclopsConvexBlock = child
|
||||
if block.selected:
|
||||
var vol:ConvexVolume = block.control_mesh
|
||||
for f_idx in vol.faces.size():
|
||||
var f:ConvexVolume.FaceInfo = vol.faces[f_idx]
|
||||
if f.selected:
|
||||
cmd.add_face(block.get_path(), f_idx)
|
||||
|
||||
|
||||
if cmd.will_change_anything():
|
||||
var undo:EditorUndoRedoManager = builder.get_undo_redo()
|
||||
cmd.add_to_undo_manager(undo)
|
||||
|
||||
|
||||
func _on_offset_x_value_changed(value):
|
||||
apply_uv_transform()
|
||||
|
||||
|
||||
func _on_offset_y_value_changed(value):
|
||||
apply_uv_transform()
|
||||
|
||||
|
||||
func _on_scale_x_value_changed(value):
|
||||
apply_uv_transform()
|
||||
|
||||
|
||||
func _on_scale_y_value_changed(value):
|
||||
apply_uv_transform()
|
||||
|
||||
|
||||
func _on_rotation_value_changed(value):
|
||||
apply_uv_transform()
|
||||
|
||||
|
||||
func _on_skew_value_changed(value):
|
||||
apply_uv_transform()
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user