initial commit

This commit is contained in:
2023-05-24 00:27:34 +03:00
commit 11ee2c7949
174 changed files with 13452 additions and 0 deletions

View File

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

View File

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

View File

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

View File

@ -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"]

View File

@ -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

View File

@ -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")

View File

@ -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

View File

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

View File

@ -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")

View File

@ -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")

View File

@ -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"]

View File

@ -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

View File

@ -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

View File

@ -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")

View File

@ -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

View File

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

View File

@ -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