diff --git a/addons/.DS_Store b/addons/.DS_Store deleted file mode 100644 index a8b392c..0000000 Binary files a/addons/.DS_Store and /dev/null differ diff --git a/addons/scatter-4/.DS_Store b/addons/scatter-4/.DS_Store deleted file mode 100644 index de125fb..0000000 Binary files a/addons/scatter-4/.DS_Store and /dev/null differ diff --git a/addons/scatter-4/.gitignore b/addons/scatter-4/.gitignore deleted file mode 100755 index 3063d8d..0000000 --- a/addons/scatter-4/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ - -# Godot-specific ignores -.import/ -export.cfg -export_presets.cfg - -# Mono-specific ignores -.mono/ -*.import diff --git a/addons/scatter-4/LICENSE b/addons/scatter-4/LICENSE deleted file mode 100755 index ba6eddb..0000000 --- a/addons/scatter-4/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2019 HungryProton - -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. diff --git a/addons/scatter-4/README.md b/addons/scatter-4/README.md deleted file mode 100644 index 15624bf..0000000 --- a/addons/scatter-4/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# Scatter - -![scatter](https://user-images.githubusercontent.com/52043844/103457605-08084d80-4d01-11eb-98a3-3cdb523d5410.png) -Addon for the Godot game engine to randomly place anything in your scenes. -[See it in action here](https://twitter.com/HungryProton/status/1344623041620402176) - -## THIS IS A WORK IN PROGRESS - -**This is the version 4 of ProtonScatter. It's only compatible with Godot 4.** - -If you're looking for a version compatible with Godot 3.x, check the releases -page or the legacy branch. - -V4 is currently being ported from v2.8.x, but it's **breaking compatibility** -due to core changes. You will have to redo your scatter nodes when -moving to v4. (I might write a conversion script if it's technically possible -and not too time consuming but that will have to wait until v4 is stable) - - -## How to use it - -Demos and documentation will return as soon as the addon is in a usable state - -## Licence -- This addon is published under the MIT licence. -- Most 2D and 3D assets in the demos folder are MIT, with a few exceptions. -Refer the the LICENCE.md in the assets folder for more details. diff --git a/addons/scatter-4/demos/assets/brick.tscn b/addons/scatter-4/demos/assets/brick.tscn deleted file mode 100644 index ed27fb7..0000000 --- a/addons/scatter-4/demos/assets/brick.tscn +++ /dev/null @@ -1,23 +0,0 @@ -[gd_scene load_steps=5 format=3 uid="uid://b4ted6l27vuyd"] - -[ext_resource type="PackedScene" uid="uid://d1d1fag0m04yc" path="res://addons/proton_scatter/demos/assets/models/brick.glb" id="1_bkmk2"] -[ext_resource type="Texture2D" uid="uid://dqa2jfs1jy0hq" path="res://addons/proton_scatter/demos/assets/textures/t_rock.jpg" id="2_235bd"] - -[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_nwvh2"] -albedo_color = Color(0.678431, 0.596078, 0.466667, 1) -albedo_texture = ExtResource("2_235bd") -uv1_scale = Vector3(0.75, 0.75, 0.75) -uv1_triplanar = true - -[sub_resource type="BoxShape3D" id="BoxShape3D_0rrnn"] -size = Vector3(0.4, 0.4, 0.4) - -[node name="brick" instance=ExtResource("1_bkmk2")] - -[node name="Cube" parent="." index="0"] -material_override = SubResource("StandardMaterial3D_nwvh2") - -[node name="StaticBody3D" type="StaticBody3D" parent="." index="1"] - -[node name="CollisionShape3D" type="CollisionShape3D" parent="." index="2"] -shape = SubResource("BoxShape3D_0rrnn") diff --git a/addons/scatter-4/demos/assets/bush.tscn b/addons/scatter-4/demos/assets/bush.tscn deleted file mode 100644 index 7e0d3a8..0000000 --- a/addons/scatter-4/demos/assets/bush.tscn +++ /dev/null @@ -1,10 +0,0 @@ -[gd_scene load_steps=3 format=3 uid="uid://b8abs8me7ckgo"] - -[ext_resource type="PackedScene" uid="uid://dbb4culid55v5" path="res://addons/proton_scatter/demos/assets/models/bush.glb" id="1_kv8tm"] -[ext_resource type="Material" uid="uid://bn3fr3m3glrnp" path="res://addons/proton_scatter/demos/assets/materials/m_bush.tres" id="2_bkwoq"] - -[node name="bush" instance=ExtResource("1_kv8tm")] - -[node name="Bush" parent="." index="0"] -material_override = ExtResource("2_bkwoq") -instance_shader_parameters/camera_bend_strength = 0.0 diff --git a/addons/scatter-4/demos/assets/dead_branch.tscn b/addons/scatter-4/demos/assets/dead_branch.tscn deleted file mode 100644 index 956a667..0000000 --- a/addons/scatter-4/demos/assets/dead_branch.tscn +++ /dev/null @@ -1,9 +0,0 @@ -[gd_scene load_steps=3 format=3 uid="uid://ctkii8aivl17n"] - -[ext_resource type="PackedScene" uid="uid://cmqlv88xp71tw" path="res://addons/proton_scatter/demos/assets/models/dead_branch.glb" id="1_5foyv"] -[ext_resource type="Material" uid="uid://d01d0h08lqqn6" path="res://addons/proton_scatter/demos/assets/materials/m_trunk.tres" id="2_tldro"] - -[node name="dead_branch" instance=ExtResource("1_5foyv")] - -[node name="DeadBranch" parent="." index="0"] -surface_material_override/0 = ExtResource("2_tldro") diff --git a/addons/scatter-4/demos/assets/fence_planks.tscn b/addons/scatter-4/demos/assets/fence_planks.tscn deleted file mode 100644 index 7a60b84..0000000 --- a/addons/scatter-4/demos/assets/fence_planks.tscn +++ /dev/null @@ -1,18 +0,0 @@ -[gd_scene load_steps=4 format=3 uid="uid://bfcjigq0vdl4d"] - -[ext_resource type="PackedScene" uid="uid://6gxiul1pw13t" path="res://addons/proton_scatter/demos/assets/models/fence_planks.glb" id="1"] -[ext_resource type="Material" path="res://addons/proton_scatter/demos/assets/materials/m_fence.tres" id="2"] - -[sub_resource type="BoxShape3D" id="BoxShape3D_fesk1"] -size = Vector3(1, 0.5, 0.1) - -[node name="fence_planks" instance=ExtResource("1")] - -[node name="fence_planks2" parent="." index="0"] -surface_material_override/0 = ExtResource("2") - -[node name="StaticBody3D" type="StaticBody3D" parent="." index="1"] - -[node name="CollisionShape3D" type="CollisionShape3D" parent="StaticBody3D" index="0"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.197684, 0.0236663) -shape = SubResource("BoxShape3D_fesk1") diff --git a/addons/scatter-4/demos/assets/gobot.tscn b/addons/scatter-4/demos/assets/gobot.tscn deleted file mode 100644 index 5b005eb..0000000 --- a/addons/scatter-4/demos/assets/gobot.tscn +++ /dev/null @@ -1,16 +0,0 @@ -[gd_scene load_steps=3 format=3 uid="uid://bmglbfn5jaubp"] - -[ext_resource type="PackedScene" uid="uid://d3f4d3m7n8tpr" path="res://addons/proton_scatter/demos/assets/models/gobot.glb" id="1_gfyx7"] - -[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_rhuea"] -albedo_color = Color(0.278431, 0.54902, 0.74902, 1) -metallic = 0.4 -metallic_specular = 0.2 -roughness = 0.15 -rim_enabled = true -rim = 0.3 - -[node name="gobot" instance=ExtResource("1_gfyx7")] - -[node name="Sphere001" parent="." index="0"] -surface_material_override/0 = SubResource("StandardMaterial3D_rhuea") diff --git a/addons/scatter-4/demos/assets/grass.tscn b/addons/scatter-4/demos/assets/grass.tscn deleted file mode 100644 index 36260f3..0000000 --- a/addons/scatter-4/demos/assets/grass.tscn +++ /dev/null @@ -1,10 +0,0 @@ -[gd_scene load_steps=3 format=3 uid="uid://c3c76je2y6vfj"] - -[ext_resource type="PackedScene" uid="uid://018flajgtx7t" path="res://addons/proton_scatter/demos/assets/models/grass.glb" id="1_203fe"] -[ext_resource type="Material" uid="uid://c4mot1fo3siox" path="res://addons/proton_scatter/demos/assets/materials/m_grass.tres" id="2_sv1ar"] - -[node name="grass" instance=ExtResource("1_203fe")] - -[node name="Plane011" parent="." index="0"] -instance_shader_parameters/camera_bend_strength = 0.35 -surface_material_override/0 = ExtResource("2_sv1ar") diff --git a/addons/scatter-4/demos/assets/grass_2.tscn b/addons/scatter-4/demos/assets/grass_2.tscn deleted file mode 100644 index 6810785..0000000 --- a/addons/scatter-4/demos/assets/grass_2.tscn +++ /dev/null @@ -1,9 +0,0 @@ -[gd_scene load_steps=3 format=3 uid="uid://cia3jakp3wj1d"] - -[ext_resource type="PackedScene" uid="uid://dcnm2ijk7hj4j" path="res://addons/proton_scatter/demos/assets/models/grass_2.glb" id="1_xyqky"] -[ext_resource type="Material" uid="uid://c4mot1fo3siox" path="res://addons/proton_scatter/demos/assets/materials/m_grass.tres" id="2_63qe5"] - -[node name="grass_2" instance=ExtResource("1_xyqky")] - -[node name="Grass" parent="." index="0"] -surface_material_override/0 = ExtResource("2_63qe5") diff --git a/addons/scatter-4/demos/assets/large_rock.tscn b/addons/scatter-4/demos/assets/large_rock.tscn deleted file mode 100644 index 2234439..0000000 --- a/addons/scatter-4/demos/assets/large_rock.tscn +++ /dev/null @@ -1,17 +0,0 @@ -[gd_scene load_steps=4 format=3 uid="uid://8ay5rlrutcmx"] - -[ext_resource type="PackedScene" uid="uid://bxqkgplyoipsx" path="res://addons/proton_scatter/demos/assets/models/large_rock.glb" id="1_etns1"] -[ext_resource type="Material" uid="uid://i0jgjmbbl2m5" path="res://addons/proton_scatter/demos/assets/materials/m_rock.tres" id="2_fes1d"] - -[sub_resource type="ConcavePolygonShape3D" id="ConcavePolygonShape3D_6ssqc"] -data = PackedVector3Array(0.0629, 0.1755, -1.8335, -0.0082, 0.0041, -1.6822, 0.2717, -0.1032, -1.6837, 0.6881, 0.5954, 1.4818, 1.1748, -0.0814, 1.7311, 0.3761, 0.3877, 1.5951, 0.8004, 0.2889, -1.6673, 0.453, 0.787, -1.6234, 0.2234, 0.3394, -1.8428, 0.0438, -0.3535, -1.5059, 0.0958, -0.4313, -1.5075, 0.2334, -0.4206, -1.5131, 1.7542, -0.4854, 0.9086, 1.6573, -0.2166, 1.2501, 1.8018, -0.1166, 1.0465, -0.9001, 0.6982, -1.3812, 0.4904, 0.8361, -0.4902, -1.2997, 0.5397, -0.7858, -1.3066, -0.6146, -0.0152, -1.3934, -0.7148, -0.3785, -1.6779, -0.4855, -0.1607, -1.6422, -0.27, -0.3156, -1.3474, 0.367, -0.2501, -1.5688, -0.3115, 0.1105, 0.7765, -0.6276, -1.2561, 0.9699, -0.5671, -1.2091, 0.6074, -0.5308, -1.4001, -0.9001, 0.6982, -1.3812, -0.534, 0.3122, -1.6595, -0.4893, 0.652, -1.605, 1.5141, -0.6082, 1.2539, 1.502, -0.4979, 1.4563, 1.5644, -0.4551, 1.31, 1.6136, 0.2882, 1.3723, 1.2715, 0.1425, 1.7004, 1.307, 0.4153, 1.6132, -0.0974, 0.1771, -1.7741, -0.0692, 0.1191, -1.7434, -0.0832, 0.1572, -1.7751, -0.0258, 0.0213, -1.688, -0.3113, -0.1613, -1.5779, 0.0157, -0.0532, -1.6436, -0.0864, 0.2978, -1.7808, 0.0784, 0.5885, -1.8004, -0.0895, 0.5831, -1.6991, 1.8072, -0.4701, -0.0799, 1.571, 0.5779, 0.2372, 1.7035, -0.1804, -0.405, 0.7935, 0.8229, -1.3081, 0.9762, 0.8279, -1.1273, 0.6719, 0.9108, -1.1199, -1.2328, -0.714, -0.1886, -1.3066, -0.6146, -0.0152, -1.0843, -0.5896, 0.1569, -1.6727, -0.3783, -0.0804, -1.6583, -0.5073, -0.3071, -1.6422, -0.27, -0.3156, 1.7542, -0.4854, 0.9086, 1.4359, -0.8794, 0.8237, 1.5663, -0.6718, 1.1167, 0.6096, -0.219, -1.5025, 0.6415, -0.1642, -1.5814, 0.2717, -0.1032, -1.6837, -0.0258, 0.0213, -1.688, 0.0157, -0.0532, -1.6436, -0.0082, 0.0041, -1.6822, 0.4631, 0.9672, -1.1988, 0.6719, 0.9108, -1.1199, 0.5883, 0.9628, -1.0063, 1.6466, 0.5513, 1.0625, 1.6113, 0.4774, 1.1526, 1.487, 0.6285, 1.1421, 1.259, -0.746, -0.7881, 0.8809, -0.6144, -1.19, -0.8459, -0.6965, -0.1217, 1.2972, 0.6831, -0.5577, 1.3496, 0.6378, -0.4421, 1.3469, 0.6517, -0.3691, 1.0299, -0.8113, 1.3675, 1.1519, -0.8005, 1.3807, 1.0338, -0.9119, 1.2882, 0.1273, -0.231, -1.5631, 0.2717, -0.1032, -1.6837, 0.0157, -0.0532, -1.6436, 0.0157, -0.0532, -1.6436, 0.2717, -0.1032, -1.6837, -0.0082, 0.0041, -1.6822, -0.0082, 0.0041, -1.6822, 0.0629, 0.1755, -1.8335, -0.0258, 0.0213, -1.688, -0.0258, 0.0213, -1.688, 0.0629, 0.1755, -1.8335, -0.0692, 0.1191, -1.7434, -0.0832, 0.1572, -1.7751, -0.0864, 0.2978, -1.7808, -0.0974, 0.1771, -1.7741, -0.0692, 0.1191, -1.7434, 0.0629, 0.1755, -1.8335, -0.0832, 0.1572, -1.7751, -0.0864, 0.2978, -1.7808, -0.0832, 0.1572, -1.7751, 0.0629, 0.1755, -1.8335, 0.1504, 0.3249, 1.5256, 0.2321, -0.5546, 1.2968, -0.1811, 0.3534, 1.33, -0.1811, 0.3534, 1.33, -0.7713, -0.4525, 0.8629, -0.8882, 0.3173, 0.8972, -0.8882, 0.3173, 0.8972, -0.7713, -0.4525, 0.8629, -1.057, 0.126, 0.9512, -1.057, 0.126, 0.9512, -0.7713, -0.4525, 0.8629, -1.1208, -0.2211, 0.8364, -0.7713, -0.4525, 0.8629, -0.1811, 0.3534, 1.33, 0.2321, -0.5546, 1.2968, 0.2321, -0.5546, 1.2968, 0.5577, -0.3719, 1.5982, 0.5902, -0.5067, 1.4887, 0.6927, -0.351, 1.6834, 1.1748, -0.0814, 1.7311, 1.0161, -0.3973, 1.7034, 0.2321, -0.5546, 1.2968, 0.1504, 0.3249, 1.5256, 0.5577, -0.3719, 1.5982, 0.1504, 0.3249, 1.5256, 0.3761, 0.3877, 1.5951, 0.5577, -0.3719, 1.5982, 0.5577, -0.3719, 1.5982, 0.3761, 0.3877, 1.5951, 0.6927, -0.351, 1.6834, 0.6927, -0.351, 1.6834, 0.3761, 0.3877, 1.5951, 1.1748, -0.0814, 1.7311, 1.1748, -0.0814, 1.7311, 0.6881, 0.5954, 1.4818, 1.2715, 0.1425, 1.7004, 1.2715, 0.1425, 1.7004, 0.6881, 0.5954, 1.4818, 1.307, 0.4153, 1.6132, 1.307, 0.4153, 1.6132, 1.0721, 0.6892, 1.1619, 1.3943, 0.5306, 1.4472, 1.0721, 0.6892, 1.1619, 1.307, 0.4153, 1.6132, 0.6881, 0.5954, 1.4818, 0.5536, 0.8275, -1.4892, 0.7935, 0.8229, -1.3081, 0.606, 0.847, -1.3151, 0.5536, 0.8275, -1.4892, 0.8004, 0.2889, -1.6673, 0.7935, 0.8229, -1.3081, 0.7935, 0.8229, -1.3081, 0.8004, 0.2889, -1.6673, 0.9175, 0.7849, -1.3125, 0.0784, 0.5885, -1.8004, 0.2234, 0.3394, -1.8428, 0.2304, 0.721, -1.7333, 0.2304, 0.721, -1.7333, 0.2234, 0.3394, -1.8428, 0.453, 0.787, -1.6234, 0.453, 0.787, -1.6234, 0.8004, 0.2889, -1.6673, 0.5536, 0.8275, -1.4892, 0.9625, 0.7976, -1.2398, 1.1721, 0.7244, -1.0147, 0.9762, 0.8279, -1.1273, 0.8004, 0.2889, -1.6673, 1.0764, 0.3168, -1.4944, 0.9175, 0.7849, -1.3125, 0.9175, 0.7849, -1.3125, 1.0764, 0.3168, -1.4944, 0.9625, 0.7976, -1.2398, 0.9625, 0.7976, -1.2398, 1.1928, 0.2492, -1.3592, 1.1721, 0.7244, -1.0147, 1.0764, 0.3168, -1.4944, 1.1928, 0.2492, -1.3592, 0.9625, 0.7976, -1.2398, 1.1721, 0.7244, -1.0147, 1.1928, 0.2492, -1.3592, 1.3553, 0.3188, -1.0845, 0.0438, -0.3535, -1.5059, 0.2334, -0.4206, -1.5131, 0.1273, -0.231, -1.5631, 1.8018, -0.1166, 1.0465, 1.6936, -0.0517, 1.195, 1.7358, 0.1659, 1.068, 1.7358, 0.1659, 1.068, 1.6944, 0.1451, 1.1403, 1.7079, 0.2069, 1.098, 1.6936, -0.0517, 1.195, 1.6944, 0.1451, 1.1403, 1.7358, 0.1659, 1.068, 1.6936, -0.0517, 1.195, 1.8018, -0.1166, 1.0465, 1.6573, -0.2166, 1.2501, 1.6573, -0.2166, 1.2501, 1.7542, -0.4854, 0.9086, 1.5644, -0.4551, 1.31, 1.7542, -0.4854, 0.9086, 1.5663, -0.6718, 1.1167, 1.5644, -0.4551, 1.31, 1.5644, -0.4551, 1.31, 1.5663, -0.6718, 1.1167, 1.5141, -0.6082, 1.2539, 0.3565, 0.8862, -1.3307, 0.5536, 0.8275, -1.4892, 0.606, 0.847, -1.3151, 0.5536, 0.8275, -1.4892, 0.3565, 0.8862, -1.3307, 0.453, 0.787, -1.6234, 0.453, 0.787, -1.6234, 0.3565, 0.8862, -1.3307, 0.2304, 0.721, -1.7333, 0.2304, 0.721, -1.7333, -0.0895, 0.5831, -1.6991, 0.0784, 0.5885, -1.8004, -0.2181, 0.7012, -1.5976, -0.9001, 0.6982, -1.3812, -0.4893, 0.652, -1.605, 0.2304, 0.721, -1.7333, 0.3565, 0.8862, -1.3307, -0.0895, 0.5831, -1.6991, -0.0895, 0.5831, -1.6991, 0.3565, 0.8862, -1.3307, -0.2181, 0.7012, -1.5976, 0.5883, 0.9628, -1.0063, 0.4904, 0.8361, -0.4902, 0.4631, 0.9672, -1.1988, 0.4631, 0.9672, -1.1988, 0.4904, 0.8361, -0.4902, 0.3565, 0.8862, -1.3307, 0.3127, 0.6878, 0.2041, -1.2997, 0.5397, -0.7858, 0.4904, 0.8361, -0.4902, 1.0721, 0.6892, 1.1619, 0.6881, 0.5954, 1.4818, 0.6961, 0.7351, 0.3218, 0.6961, 0.7351, 0.3218, 0.6881, 0.5954, 1.4818, 0.3127, 0.6878, 0.2041, 0.3761, 0.3877, 1.5951, 0.1504, 0.3249, 1.5256, 0.6881, 0.5954, 1.4818, -0.1811, 0.3534, 1.33, 0.3127, 0.6878, 0.2041, 0.1504, 0.3249, 1.5256, 0.3127, 0.6878, 0.2041, 0.6881, 0.5954, 1.4818, 0.1504, 0.3249, 1.5256, -1.2352, 0.3268, 0.2088, 0.3127, 0.6878, 0.2041, -0.8882, 0.3173, 0.8972, -0.8882, 0.3173, 0.8972, 0.3127, 0.6878, 0.2041, -0.1811, 0.3534, 1.33, -1.2997, 0.5397, -0.7858, 0.3127, 0.6878, 0.2041, -1.3474, 0.367, -0.2501, -1.3474, 0.367, -0.2501, 0.3127, 0.6878, 0.2041, -1.2352, 0.3268, 0.2088, -0.9001, 0.6982, -1.3812, -1.2997, 0.5397, -0.7858, -1.1636, 0.6589, -1.169, -0.2181, 0.7012, -1.5976, 0.4904, 0.8361, -0.4902, -0.9001, 0.6982, -1.3812, 0.3565, 0.8862, -1.3307, 0.4904, 0.8361, -0.4902, -0.2181, 0.7012, -1.5976, -1.1208, -0.2211, 0.8364, -1.0843, -0.5896, 0.1569, -1.4177, -0.2864, 0.367, -1.4177, -0.2864, 0.367, -1.3066, -0.6146, -0.0152, -1.5688, -0.3115, 0.1105, -1.0843, -0.5896, 0.1569, -1.3066, -0.6146, -0.0152, -1.4177, -0.2864, 0.367, -1.5688, -0.3115, 0.1105, -1.3066, -0.6146, -0.0152, -1.6727, -0.3783, -0.0804, -1.6727, -0.3783, -0.0804, -1.3066, -0.6146, -0.0152, -1.6779, -0.4855, -0.1607, -1.6779, -0.4855, -0.1607, -1.3934, -0.7148, -0.3785, -1.6583, -0.5073, -0.3071, -1.6583, -0.5073, -0.3071, -1.3934, -0.7148, -0.3785, -1.5776, -0.5652, -0.4479, -1.5776, -0.5652, -0.4479, -1.3934, -0.7148, -0.3785, -1.4282, -0.6229, -0.5707, -1.3934, -0.7148, -0.3785, -1.3066, -0.6146, -0.0152, -1.2328, -0.714, -0.1886, -1.0843, -0.5896, 0.1569, -1.1208, -0.2211, 0.8364, -0.7713, -0.4525, 0.8629, -1.4177, -0.2864, 0.367, -1.2352, 0.3268, 0.2088, -1.1208, -0.2211, 0.8364, -1.1208, -0.2211, 0.8364, -1.2352, 0.3268, 0.2088, -1.057, 0.126, 0.9512, -1.057, 0.126, 0.9512, -1.2352, 0.3268, 0.2088, -0.8882, 0.3173, 0.8972, -1.2352, 0.3268, 0.2088, -1.5688, -0.3115, 0.1105, -1.3474, 0.367, -0.2501, -1.5688, -0.3115, 0.1105, -1.2352, 0.3268, 0.2088, -1.4177, -0.2864, 0.367, -1.6422, -0.27, -0.3156, -1.5688, -0.3115, 0.1105, -1.6727, -0.3783, -0.0804, -1.387, 0.0341, -0.9932, -1.2997, 0.5397, -0.7858, -1.4997, -0.1393, -0.7307, -1.4997, -0.1393, -0.7307, -1.3474, 0.367, -0.2501, -1.6422, -0.27, -0.3156, -1.2722, 0.4609, -1.2479, -1.387, 0.0341, -0.9932, -1.1493, 0.3036, -1.3146, -1.1636, 0.6589, -1.169, -1.2997, 0.5397, -0.7858, -1.2362, 0.5774, -1.237, -1.2362, 0.5774, -1.237, -1.2997, 0.5397, -0.7858, -1.2722, 0.4609, -1.2479, -1.2722, 0.4609, -1.2479, -1.2997, 0.5397, -0.7858, -1.387, 0.0341, -0.9932, -1.4997, -0.1393, -0.7307, -1.2997, 0.5397, -0.7858, -1.3474, 0.367, -0.2501, 1.1928, 0.2492, -1.3592, 1.0502, -0.6021, -1.1682, 1.3553, 0.3188, -1.0845, 1.3553, 0.3188, -1.0845, 1.259, -0.746, -0.7881, 1.7035, -0.1804, -0.405, 1.3553, 0.3188, -1.0845, 1.1109, -0.6863, -1.0196, 1.259, -0.746, -0.7881, 1.7035, -0.1804, -0.405, 1.5814, -0.7117, -0.4108, 1.8072, -0.4701, -0.0799, 1.8072, -0.4701, -0.0799, 1.6645, -0.7082, -0.1973, 1.7652, -0.6177, 0.216, 1.5814, -0.7117, -0.4108, 1.6645, -0.7082, -0.1973, 1.8072, -0.4701, -0.0799, 1.7652, -0.6177, 0.216, 1.6645, -0.7082, -0.1973, 1.6461, -0.7592, 0.1617, 1.436, -0.7221, -0.624, 1.5814, -0.7117, -0.4108, 1.7035, -0.1804, -0.405, 0.8004, 0.2889, -1.6673, 0.6415, -0.1642, -1.5814, 1.0764, 0.3168, -1.4944, 1.0764, 0.3168, -1.4944, 0.6415, -0.1642, -1.5814, 1.1928, 0.2492, -1.3592, 0.6415, -0.1642, -1.5814, 0.6096, -0.219, -1.5025, 1.1928, 0.2492, -1.3592, 0.0629, 0.1755, -1.8335, 0.2717, -0.1032, -1.6837, 0.2234, 0.3394, -1.8428, 0.2234, 0.3394, -1.8428, 0.2717, -0.1032, -1.6837, 0.8004, 0.2889, -1.6673, 0.6415, -0.1642, -1.5814, 0.8004, 0.2889, -1.6673, 0.2717, -0.1032, -1.6837, 0.2334, -0.4206, -1.5131, 0.6096, -0.219, -1.5025, 0.1273, -0.231, -1.5631, 0.6074, -0.5308, -1.4001, 0.6096, -0.219, -1.5025, 0.2334, -0.4206, -1.5131, 1.7035, -0.1804, -0.405, 1.259, -0.746, -0.7881, 1.436, -0.7221, -0.624, 1.1928, 0.2492, -1.3592, 0.9699, -0.5671, -1.2091, 1.0502, -0.6021, -1.1682, 1.1109, -0.6863, -1.0196, 1.3553, 0.3188, -1.0845, 1.0502, -0.6021, -1.1682, 0.6074, -0.5308, -1.4001, 0.9699, -0.5671, -1.2091, 0.6096, -0.219, -1.5025, 0.9699, -0.5671, -1.2091, 1.1928, 0.2492, -1.3592, 0.6096, -0.219, -1.5025, 0.8809, -0.6144, -1.19, 0.9699, -0.5671, -1.2091, 0.7765, -0.6276, -1.2561, -0.534, 0.3122, -1.6595, -0.9001, 0.6982, -1.3812, -1.1493, 0.3036, -1.3146, -1.1493, 0.3036, -1.3146, -1.2362, 0.5774, -1.237, -1.2722, 0.4609, -1.2479, -0.9001, 0.6982, -1.3812, -1.2362, 0.5774, -1.237, -1.1493, 0.3036, -1.3146, -1.2362, 0.5774, -1.237, -0.9001, 0.6982, -1.3812, -1.1636, 0.6589, -1.169, 1.502, -0.4979, 1.4563, 1.5141, -0.6082, 1.2539, 1.3317, -0.6356, 1.518, 1.3317, -0.6356, 1.518, 1.5141, -0.6082, 1.2539, 1.2689, -0.7439, 1.3995, 1.2689, -0.7439, 1.3995, 1.124, -0.9978, 1.0499, 1.1519, -0.8005, 1.3807, 1.1519, -0.8005, 1.3807, 1.124, -0.9978, 1.0499, 1.0338, -0.9119, 1.2882, 1.0338, -0.9119, 1.2882, 1.124, -0.9978, 1.0499, 1.0169, -0.9992, 1.153, 1.124, -0.9978, 1.0499, 1.5663, -0.6718, 1.1167, 1.2368, -0.9984, 0.9293, 1.2368, -0.9984, 0.9293, 1.5663, -0.6718, 1.1167, 1.4359, -0.8794, 0.8237, 1.5663, -0.6718, 1.1167, 1.2689, -0.7439, 1.3995, 1.5141, -0.6082, 1.2539, 1.124, -0.9978, 1.0499, 1.2689, -0.7439, 1.3995, 1.5663, -0.6718, 1.1167, 1.2715, 0.1425, 1.7004, 1.6307, -0.0932, 1.3908, 1.1748, -0.0814, 1.7311, 1.1748, -0.0814, 1.7311, 1.1624, -0.5844, 1.6321, 1.0161, -0.3973, 1.7034, 1.502, -0.4979, 1.4563, 1.3317, -0.6356, 1.518, 1.1624, -0.5844, 1.6321, 1.1748, -0.0814, 1.7311, 1.502, -0.4979, 1.4563, 1.1624, -0.5844, 1.6321, 1.502, -0.4979, 1.4563, 1.1748, -0.0814, 1.7311, 1.5954, -0.2805, 1.4511, 1.5954, -0.2805, 1.4511, 1.1748, -0.0814, 1.7311, 1.6307, -0.0932, 1.3908, 1.6307, -0.0932, 1.3908, 1.2715, 0.1425, 1.7004, 1.6136, 0.2882, 1.3723, 1.6136, 0.2882, 1.3723, 1.307, 0.4153, 1.6132, 1.3943, 0.5306, 1.4472, -0.534, 0.3122, -1.6595, -0.2181, 0.7012, -1.5976, -0.4893, 0.652, -1.605, -0.2181, 0.7012, -1.5976, -0.534, 0.3122, -1.6595, -0.0895, 0.5831, -1.6991, -0.0895, 0.5831, -1.6991, -0.534, 0.3122, -1.6595, -0.0864, 0.2978, -1.7808, -0.0974, 0.1771, -1.7741, -0.3113, -0.1613, -1.5779, -0.0692, 0.1191, -1.7434, -0.0692, 0.1191, -1.7434, -0.3113, -0.1613, -1.5779, -0.0258, 0.0213, -1.688, -0.0864, 0.2978, -1.7808, -0.534, 0.3122, -1.6595, -0.0974, 0.1771, -1.7741, -0.3113, -0.1613, -1.5779, -0.0974, 0.1771, -1.7741, -0.534, 0.3122, -1.6595, 0.0157, -0.0532, -1.6436, -0.3113, -0.1613, -1.5779, 0.1273, -0.231, -1.5631, 0.0784, 0.5885, -1.8004, -0.0864, 0.2978, -1.7808, 0.2234, 0.3394, -1.8428, 0.2234, 0.3394, -1.8428, -0.0864, 0.2978, -1.7808, 0.0629, 0.1755, -1.8335, 1.7035, -0.1804, -0.405, 1.3496, 0.6378, -0.4421, 1.3553, 0.3188, -1.0845, 1.3553, 0.3188, -1.0845, 1.2972, 0.6831, -0.5577, 1.1721, 0.7244, -1.0147, 1.3496, 0.6378, -0.4421, 1.2972, 0.6831, -0.5577, 1.3553, 0.3188, -1.0845, 1.3496, 0.6378, -0.4421, 1.5036, 0.5972, -0.0994, 1.3469, 0.6517, -0.3691, 1.571, 0.5779, 0.2372, 1.8018, -0.1166, 1.0465, 1.5632, 0.6125, 0.4668, 1.5632, 0.6125, 0.4668, 1.6466, 0.5513, 1.0625, 1.559, 0.6543, 0.9634, 1.5632, 0.6125, 0.4668, 1.7358, 0.1659, 1.068, 1.6466, 0.5513, 1.0625, 1.7358, 0.1659, 1.068, 1.7079, 0.2069, 1.098, 1.6466, 0.5513, 1.0625, 1.6466, 0.5513, 1.0625, 1.7079, 0.2069, 1.098, 1.6113, 0.4774, 1.1526, 1.6113, 0.4774, 1.1526, 1.7079, 0.2069, 1.098, 1.6616, 0.3586, 1.2649, 1.6616, 0.3586, 1.2649, 1.6944, 0.1451, 1.1403, 1.6136, 0.2882, 1.3723, 1.6136, 0.2882, 1.3723, 1.6944, 0.1451, 1.1403, 1.6307, -0.0932, 1.3908, 1.6307, -0.0932, 1.3908, 1.6573, -0.2166, 1.2501, 1.5954, -0.2805, 1.4511, 1.5954, -0.2805, 1.4511, 1.5644, -0.4551, 1.31, 1.502, -0.4979, 1.4563, 1.6573, -0.2166, 1.2501, 1.5644, -0.4551, 1.31, 1.5954, -0.2805, 1.4511, 1.6573, -0.2166, 1.2501, 1.6307, -0.0932, 1.3908, 1.6936, -0.0517, 1.195, 1.6936, -0.0517, 1.195, 1.6307, -0.0932, 1.3908, 1.6944, 0.1451, 1.1403, 1.5036, 0.5972, -0.0994, 1.7035, -0.1804, -0.405, 1.571, 0.5779, 0.2372, 1.6616, 0.3586, 1.2649, 1.7079, 0.2069, 1.098, 1.6944, 0.1451, 1.1403, 1.5632, 0.6125, 0.4668, 1.8018, -0.1166, 1.0465, 1.7358, 0.1659, 1.068, 1.8018, -0.1166, 1.0465, 1.7652, -0.6177, 0.216, 1.7542, -0.4854, 0.9086, 1.7652, -0.6177, 0.216, 1.8018, -0.1166, 1.0465, 1.571, 0.5779, 0.2372, 1.3496, 0.6378, -0.4421, 1.7035, -0.1804, -0.405, 1.5036, 0.5972, -0.0994, 1.571, 0.5779, 0.2372, 1.8072, -0.4701, -0.0799, 1.7652, -0.6177, 0.216, 1.487, 0.6285, 1.1421, 1.0721, 0.6892, 1.1619, 1.559, 0.6543, 0.9634, 1.559, 0.6543, 0.9634, 1.0721, 0.6892, 1.1619, 1.5632, 0.6125, 0.4668, 1.5632, 0.6125, 0.4668, 0.6961, 0.7351, 0.3218, 1.571, 0.5779, 0.2372, 1.571, 0.5779, 0.2372, 0.6961, 0.7351, 0.3218, 1.5036, 0.5972, -0.0994, 1.5036, 0.5972, -0.0994, 0.6961, 0.7351, 0.3218, 1.3469, 0.6517, -0.3691, 1.6616, 0.3586, 1.2649, 1.6136, 0.2882, 1.3723, 1.6113, 0.4774, 1.1526, 1.6113, 0.4774, 1.1526, 1.6136, 0.2882, 1.3723, 1.487, 0.6285, 1.1421, 1.2972, 0.6831, -0.5577, 0.4904, 0.8361, -0.4902, 1.1721, 0.7244, -1.0147, 1.1721, 0.7244, -1.0147, 0.4904, 0.8361, -0.4902, 0.9762, 0.8279, -1.1273, 1.5632, 0.6125, 0.4668, 1.0721, 0.6892, 1.1619, 0.6961, 0.7351, 0.3218, 1.3469, 0.6517, -0.3691, 0.4904, 0.8361, -0.4902, 1.2972, 0.6831, -0.5577, 0.6961, 0.7351, 0.3218, 0.4904, 0.8361, -0.4902, 1.3469, 0.6517, -0.3691, 1.0721, 0.6892, 1.1619, 1.487, 0.6285, 1.1421, 1.3943, 0.5306, 1.4472, 1.3943, 0.5306, 1.4472, 1.487, 0.6285, 1.1421, 1.6136, 0.2882, 1.3723, 0.4904, 0.8361, -0.4902, 0.6961, 0.7351, 0.3218, 0.3127, 0.6878, 0.2041, 0.5883, 0.9628, -1.0063, 0.9762, 0.8279, -1.1273, 0.4904, 0.8361, -0.4902, 0.7935, 0.8229, -1.3081, 0.6719, 0.9108, -1.1199, 0.606, 0.847, -1.3151, 0.6719, 0.9108, -1.1199, 0.9762, 0.8279, -1.1273, 0.5883, 0.9628, -1.0063, 0.9762, 0.8279, -1.1273, 0.7935, 0.8229, -1.3081, 0.9625, 0.7976, -1.2398, 0.9625, 0.7976, -1.2398, 0.7935, 0.8229, -1.3081, 0.9175, 0.7849, -1.3125, -1.2328, -0.714, -0.1886, -1.0843, -0.5896, 0.1569, -0.8459, -0.6965, -0.1217, -1.1493, 0.3036, -1.3146, -0.8122, -0.4144, -1.2617, -0.534, 0.3122, -1.6595, -0.534, 0.3122, -1.6595, -0.8122, -0.4144, -1.2617, -0.3113, -0.1613, -1.5779, -0.8122, -0.4144, -1.2617, -1.387, 0.0341, -0.9932, -1.1401, -0.5073, -0.9935, -1.1493, 0.3036, -1.3146, -1.387, 0.0341, -0.9932, -0.8122, -0.4144, -1.2617, -1.1401, -0.5073, -0.9935, -1.4997, -0.1393, -0.7307, -1.4282, -0.6229, -0.5707, -1.4282, -0.6229, -0.5707, -1.4997, -0.1393, -0.7307, -1.5776, -0.5652, -0.4479, -1.6583, -0.5073, -0.3071, -1.6727, -0.3783, -0.0804, -1.6779, -0.4855, -0.1607, -1.5776, -0.5652, -0.4479, -1.6422, -0.27, -0.3156, -1.6583, -0.5073, -0.3071, -1.4997, -0.1393, -0.7307, -1.6422, -0.27, -0.3156, -1.5776, -0.5652, -0.4479, -1.4997, -0.1393, -0.7307, -1.1401, -0.5073, -0.9935, -1.387, 0.0341, -0.9932, 1.6461, -0.7592, 0.1617, 1.4359, -0.8794, 0.8237, 1.7652, -0.6177, 0.216, 1.7652, -0.6177, 0.216, 1.4359, -0.8794, 0.8237, 1.7542, -0.4854, 0.9086, 0.6096, -0.219, -1.5025, 0.2717, -0.1032, -1.6837, 0.1273, -0.231, -1.5631, 0.6719, 0.9108, -1.1199, 0.4631, 0.9672, -1.1988, 0.606, 0.847, -1.3151, 0.606, 0.847, -1.3151, 0.4631, 0.9672, -1.1988, 0.3565, 0.8862, -1.3307, 1.6466, 0.5513, 1.0625, 1.487, 0.6285, 1.1421, 1.559, 0.6543, 0.9634, 1.1624, -0.5844, 1.6321, 1.0299, -0.8113, 1.3675, 1.0161, -0.3973, 1.7034, 1.0161, -0.3973, 1.7034, 1.0299, -0.8113, 1.3675, 0.6927, -0.351, 1.6834, 0.6927, -0.351, 1.6834, 0.5902, -0.5067, 1.4887, 0.5577, -0.3719, 1.5982, 0.2321, -0.5546, 1.2968, -0.8459, -0.6965, -0.1217, -0.7713, -0.4525, 0.8629, -0.7713, -0.4525, 0.8629, -0.8459, -0.6965, -0.1217, -1.0843, -0.5896, 0.1569, 0.6927, -0.351, 1.6834, 1.0299, -0.8113, 1.3675, 0.5902, -0.5067, 1.4887, 0.5902, -0.5067, 1.4887, 1.0169, -0.9992, 1.153, 0.2321, -0.5546, 1.2968, -0.8459, -0.6965, -0.1217, -1.3934, -0.7148, -0.3785, -1.2328, -0.714, -0.1886, 0.2321, -0.5546, 1.2968, 1.259, -0.746, -0.7881, -0.8459, -0.6965, -0.1217, 1.2368, -0.9984, 0.9293, 1.259, -0.746, -0.7881, 0.2321, -0.5546, 1.2968, 1.3317, -0.6356, 1.518, 1.1519, -0.8005, 1.3807, 1.1624, -0.5844, 1.6321, 1.1519, -0.8005, 1.3807, 1.3317, -0.6356, 1.518, 1.2689, -0.7439, 1.3995, 1.0169, -0.9992, 1.153, 0.5902, -0.5067, 1.4887, 1.0338, -0.9119, 1.2882, 1.0338, -0.9119, 1.2882, 0.5902, -0.5067, 1.4887, 1.0299, -0.8113, 1.3675, 1.0299, -0.8113, 1.3675, 1.1624, -0.5844, 1.6321, 1.1519, -0.8005, 1.3807, -0.8459, -0.6965, -0.1217, -1.4282, -0.6229, -0.5707, -1.3934, -0.7148, -0.3785, -1.4282, -0.6229, -0.5707, -0.8459, -0.6965, -0.1217, -1.1401, -0.5073, -0.9935, -1.1401, -0.5073, -0.9935, -0.8459, -0.6965, -0.1217, -0.8122, -0.4144, -1.2617, -0.8122, -0.4144, -1.2617, 0.0438, -0.3535, -1.5059, -0.3113, -0.1613, -1.5779, -0.3113, -0.1613, -1.5779, 0.0438, -0.3535, -1.5059, 0.1273, -0.231, -1.5631, 1.2368, -0.9984, 0.9293, 0.2321, -0.5546, 1.2968, 1.124, -0.9978, 1.0499, 1.124, -0.9978, 1.0499, 0.2321, -0.5546, 1.2968, 1.0169, -0.9992, 1.153, -0.8459, -0.6965, -0.1217, 0.0438, -0.3535, -1.5059, -0.8122, -0.4144, -1.2617, 0.0958, -0.4313, -1.5075, 0.0438, -0.3535, -1.5059, -0.8459, -0.6965, -0.1217, 0.0958, -0.4313, -1.5075, 0.6074, -0.5308, -1.4001, 0.2334, -0.4206, -1.5131, 0.0958, -0.4313, -1.5075, 0.7765, -0.6276, -1.2561, 0.6074, -0.5308, -1.4001, -0.8459, -0.6965, -0.1217, 0.7765, -0.6276, -1.2561, 0.0958, -0.4313, -1.5075, 1.6461, -0.7592, 0.1617, 1.2368, -0.9984, 0.9293, 1.4359, -0.8794, 0.8237, 1.5814, -0.7117, -0.4108, 1.6461, -0.7592, 0.1617, 1.6645, -0.7082, -0.1973, 1.259, -0.746, -0.7881, 1.6461, -0.7592, 0.1617, 1.436, -0.7221, -0.624, 1.436, -0.7221, -0.624, 1.6461, -0.7592, 0.1617, 1.5814, -0.7117, -0.4108, 0.9699, -0.5671, -1.2091, 0.8809, -0.6144, -1.19, 1.0502, -0.6021, -1.1682, 1.0502, -0.6021, -1.1682, 0.8809, -0.6144, -1.19, 1.1109, -0.6863, -1.0196, 1.1109, -0.6863, -1.0196, 0.8809, -0.6144, -1.19, 1.259, -0.746, -0.7881, 0.7765, -0.6276, -1.2561, -0.8459, -0.6965, -0.1217, 0.8809, -0.6144, -1.19, 1.259, -0.746, -0.7881, 1.2368, -0.9984, 0.9293, 1.6461, -0.7592, 0.1617) - -[node name="large_rock" instance=ExtResource("1_etns1")] - -[node name="LargeRock" parent="." index="0"] -surface_material_override/0 = ExtResource("2_fes1d") - -[node name="StaticBody3D" type="StaticBody3D" parent="LargeRock" index="0"] - -[node name="CollisionShape3D" type="CollisionShape3D" parent="LargeRock/StaticBody3D" index="0"] -shape = SubResource("ConcavePolygonShape3D_6ssqc") diff --git a/addons/scatter-4/demos/assets/materials/grass.gdshader b/addons/scatter-4/demos/assets/materials/grass.gdshader deleted file mode 100644 index 9850b66..0000000 --- a/addons/scatter-4/demos/assets/materials/grass.gdshader +++ /dev/null @@ -1,62 +0,0 @@ -shader_type spatial; - -render_mode depth_draw_opaque, cull_disabled; - -// Texture settings -uniform sampler2D texture_albedo : hint_default_white, repeat_disable; -uniform sampler2D texture_gradient : hint_default_white, repeat_disable; -uniform sampler2D texture_noise : hint_default_white; -uniform float alpha_scissor_threshold : hint_range(0.0, 1.0); -uniform vec4 transmission : source_color; -uniform vec4 secondary_color : source_color; -uniform float secondary_attenuation = 0.2; -uniform float grass_height = 1.0; - -// Wind settings -uniform vec2 wind_direction = vec2(1, -0.5); -uniform float wind_speed = 1.0; -uniform float wind_strength = 2.0; -uniform float noise_scale = 20.0; - -instance uniform float camera_bend_strength : hint_range(0.0, 3.0) = 0.2; - -varying float color; -varying float height; - -void vertex() { - height = VERTEX.y; - float influence = smoothstep(0, 1, height / 2.0); - vec4 world_pos = MODEL_MATRIX * vec4(VERTEX, 1.0); - vec2 uv = world_pos.xz / (noise_scale + 1e-2); - vec2 panning_uv = uv + fract(TIME * wind_direction * wind_speed); - float wind = texture(texture_noise, panning_uv).r * 2.0 - 0.4; - color = texture(texture_noise, uv).r; - - vec2 wind_offset = -wind_direction * wind_strength * influence * wind; - world_pos.xz += wind_offset; - world_pos.y -= wind * influence * smoothstep(0.0, height, wind_strength); - - //Push the top vertex away from the camera to bend the grass clump - float ndotv = 1.0 - dot(vec3(0.0, 1.0, 0.0), normalize(INV_VIEW_MATRIX[1].xyz)); - world_pos.xz += INV_VIEW_MATRIX[1].xz * camera_bend_strength * height * ndotv; - - vec4 local_pos = inverse(MODEL_MATRIX) * world_pos; - local_pos.x += wind_strength * influence * cos(TIME * 1.0) / 8.0; - local_pos.z += wind_strength * influence * sin(TIME * 1.5) / 8.0; - - VERTEX = local_pos.xyz; - //NORMAL = vec3(0.0, 1.0, 0.0); -} - -void fragment() { - vec4 tex = texture(texture_albedo, UV); - if (tex.a < alpha_scissor_threshold) { - discard; - } - - BACKLIGHT = transmission.rgb; - vec4 gradient = texture(texture_gradient, vec2(height / grass_height, 0.0)); - float secondary_weight = smoothstep(0.0, 1.0, color - secondary_attenuation); - ALBEDO = tex.rbg * gradient.rgb; - //ALBEDO = mix(ALBEDO, secondary_color.rgb, secondary_weight); -} diff --git a/addons/scatter-4/demos/assets/materials/leaves.gdshader b/addons/scatter-4/demos/assets/materials/leaves.gdshader deleted file mode 100644 index ca84300..0000000 --- a/addons/scatter-4/demos/assets/materials/leaves.gdshader +++ /dev/null @@ -1,51 +0,0 @@ -shader_type spatial; - -render_mode depth_draw_opaque, cull_disabled; - -// Texture settings -uniform sampler2D texture_albedo : hint_default_white, repeat_disable; -uniform sampler2D texture_gradient : hint_default_white; -uniform sampler2D texture_noise : hint_default_white; -uniform float alpha_scissor_threshold : hint_range(0.0, 1.0); -uniform vec4 transmission : source_color; -uniform float total_height = 1.0; - -// Wind settings -uniform vec2 wind_direction = vec2(1, -0.5); -uniform float wind_speed = 1.0; -uniform float wind_strength = 2.0; -uniform float noise_scale = 20.0; - -varying float color; -varying float height; - -void vertex() { - height = VERTEX.y; - - vec4 world_pos = MODEL_MATRIX * vec4(VERTEX, 1.0); - vec2 uv = (world_pos.xz + VERTEX.yy) / (noise_scale + 1e-2) ; - vec2 panning_uv = uv + fract(TIME * wind_direction * wind_speed); - float wind = texture(texture_noise, panning_uv).r * 2.0 - 0.4; - color = texture(texture_noise, uv).r; - - float wind_influence = smoothstep(0, 1, 1.0 - UV.y); - vec2 wind_offset = -wind_direction * wind_strength * wind_influence * wind; - world_pos.xz += wind_offset; - world_pos.y -= wind * wind_influence * wind_strength * 0.45; - - vec4 local_pos = inverse(MODEL_MATRIX) * world_pos; - - VERTEX = local_pos.xyz; - //NORMAL = vec3(0.0, 1.0, 0.0); -} - -void fragment() { - vec4 tex = texture(texture_albedo, UV); - if (tex.a < alpha_scissor_threshold) { - discard; - } - - BACKLIGHT = transmission.rgb; - vec4 gradient = texture(texture_gradient, vec2(height / total_height, 0.0)); - ALBEDO = tex.rbg * gradient.rgb; -} diff --git a/addons/scatter-4/demos/assets/materials/m_bush.tres b/addons/scatter-4/demos/assets/materials/m_bush.tres deleted file mode 100644 index d38f6e1..0000000 --- a/addons/scatter-4/demos/assets/materials/m_bush.tres +++ /dev/null @@ -1,37 +0,0 @@ -[gd_resource type="ShaderMaterial" load_steps=7 format=3 uid="uid://bn3fr3m3glrnp"] - -[ext_resource type="Shader" path="res://addons/proton_scatter/demos/assets/materials/grass.gdshader" id="1_peshr"] -[ext_resource type="Texture2D" uid="uid://b2a6ylo2enm4g" path="res://addons/proton_scatter/demos/assets/textures/t_bush.png" id="2_mbhvd"] - -[sub_resource type="Gradient" id="Gradient_122hb"] -offsets = PackedFloat32Array(0, 0.5, 1) -colors = PackedColorArray(0.179688, 0.0759602, 0.0183228, 1, 0.386532, 0.390625, 0.0230687, 1, 1, 0.693237, 0.0687054, 1) - -[sub_resource type="GradientTexture1D" id="GradientTexture1D_i0bw2"] -gradient = SubResource("Gradient_122hb") - -[sub_resource type="FastNoiseLite" id="FastNoiseLite_eeqpx"] -seed = 1 -frequency = 0.002 - -[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_7l0n1"] -in_3d_space = true -seamless = true -seamless_blend_skirt = 0.65 -noise = SubResource("FastNoiseLite_eeqpx") - -[resource] -render_priority = 0 -shader = ExtResource("1_peshr") -shader_parameter/alpha_scissor_threshold = 0.25 -shader_parameter/transmission = Color(0.619608, 0.541176, 0.101961, 1) -shader_parameter/secondary_color = Color(0, 0, 0, 1) -shader_parameter/secondary_attenuation = 0.2 -shader_parameter/grass_height = 0.829 -shader_parameter/wind_direction = Vector2(1, -0.5) -shader_parameter/wind_speed = 0.5 -shader_parameter/wind_strength = 0.15 -shader_parameter/noise_scale = 6.0 -shader_parameter/texture_albedo = ExtResource("2_mbhvd") -shader_parameter/texture_gradient = SubResource("GradientTexture1D_i0bw2") -shader_parameter/texture_noise = SubResource("NoiseTexture2D_7l0n1") diff --git a/addons/scatter-4/demos/assets/materials/m_fence.tres b/addons/scatter-4/demos/assets/materials/m_fence.tres deleted file mode 100644 index d2cedf3..0000000 --- a/addons/scatter-4/demos/assets/materials/m_fence.tres +++ /dev/null @@ -1,6 +0,0 @@ -[gd_resource type="SpatialMaterial" format=2] - -[resource] -resource_name = "wood" -vertex_color_use_as_albedo = true -albedo_color = Color( 0.568627, 0.466667, 0.372549, 1 ) diff --git a/addons/scatter-4/demos/assets/materials/m_grass.tres b/addons/scatter-4/demos/assets/materials/m_grass.tres deleted file mode 100644 index 3cf26c6..0000000 --- a/addons/scatter-4/demos/assets/materials/m_grass.tres +++ /dev/null @@ -1,38 +0,0 @@ -[gd_resource type="ShaderMaterial" load_steps=7 format=3 uid="uid://c4mot1fo3siox"] - -[ext_resource type="Shader" path="res://addons/proton_scatter/demos/assets/materials/grass.gdshader" id="1_fntgl"] -[ext_resource type="Texture2D" uid="uid://d23p13yi7asw0" path="res://addons/proton_scatter/demos/assets/textures/t_grass_2.png" id="2_1odx0"] - -[sub_resource type="Gradient" id="Gradient_122hb"] -offsets = PackedFloat32Array(0, 0.473451, 1) -colors = PackedColorArray(0.179688, 0.0855483, 0.00322032, 1, 0.251693, 0.390625, 0.0117187, 1, 1, 0.964706, 0.129412, 1) - -[sub_resource type="GradientTexture1D" id="GradientTexture1D_i0bw2"] -gradient = SubResource("Gradient_122hb") - -[sub_resource type="FastNoiseLite" id="FastNoiseLite_eeqpx"] -seed = 1 -frequency = 0.002 - -[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_7l0n1"] -in_3d_space = true -seamless = true -seamless_blend_skirt = 0.65 -noise = SubResource("FastNoiseLite_eeqpx") - -[resource] -render_priority = 0 -shader = ExtResource("1_fntgl") -shader_parameter/alpha_scissor_threshold = 0.3 -shader_parameter/transmission = Color(0.737255, 0.72549, 0, 1) -shader_parameter/secondary_color = Color(0, 0, 0, 1) -shader_parameter/secondary_attenuation = 0.2 -shader_parameter/grass_height = 0.6 -shader_parameter/wind_direction = Vector2(1, -0.5) -shader_parameter/wind_speed = 0.5 -shader_parameter/wind_strength = 0.15 -shader_parameter/noise_scale = 6.0 -shader_parameter/camera_bend_strength = 0.3 -shader_parameter/texture_albedo = ExtResource("2_1odx0") -shader_parameter/texture_gradient = SubResource("GradientTexture1D_i0bw2") -shader_parameter/texture_noise = SubResource("NoiseTexture2D_7l0n1") diff --git a/addons/scatter-4/demos/assets/materials/m_leaves.tres b/addons/scatter-4/demos/assets/materials/m_leaves.tres deleted file mode 100644 index a73f1c1..0000000 --- a/addons/scatter-4/demos/assets/materials/m_leaves.tres +++ /dev/null @@ -1,38 +0,0 @@ -[gd_resource type="ShaderMaterial" load_steps=7 format=3 uid="uid://djo80ucamk643"] - -[ext_resource type="Shader" path="res://addons/proton_scatter/demos/assets/materials/grass.gdshader" id="1_8py1k"] -[ext_resource type="Texture2D" uid="uid://cgenco43aneod" path="res://addons/proton_scatter/demos/assets/textures/t_leaves_1.png" id="2_l2uea"] - -[sub_resource type="Gradient" id="Gradient_yy7fg"] -offsets = PackedFloat32Array(0, 0.726872, 0.934272) -colors = PackedColorArray(0.333333, 0.486275, 0.556863, 1, 0.496467, 0.55, 0.1485, 1, 0.898039, 0.670588, 0.0196078, 1) - -[sub_resource type="GradientTexture1D" id="GradientTexture1D_rwvaq"] -gradient = SubResource("Gradient_yy7fg") - -[sub_resource type="FastNoiseLite" id="FastNoiseLite_wpihy"] -seed = 1 -frequency = 0.002 - -[sub_resource type="NoiseTexture2D" id="NoiseTexture_tgrrr"] -in_3d_space = true -seamless = true -seamless_blend_skirt = 0.65 -noise = SubResource("FastNoiseLite_wpihy") - -[resource] -render_priority = 0 -shader = ExtResource("1_8py1k") -shader_parameter/alpha_scissor_threshold = 0.5 -shader_parameter/camera_bend_strength = 0.0 -shader_parameter/grass_height = 1.0 -shader_parameter/noise_scale = 12.0 -shader_parameter/secondary_attenuation = 0.2 -shader_parameter/secondary_color = Color(0, 0.305882, 0.211765, 1) -shader_parameter/texture_albedo = ExtResource("2_l2uea") -shader_parameter/texture_gradient = SubResource("GradientTexture1D_rwvaq") -shader_parameter/texture_noise = SubResource("NoiseTexture_tgrrr") -shader_parameter/transmission = Color(1, 0.975296, 0.943663, 1) -shader_parameter/wind_direction = Vector2(1, -0.5) -shader_parameter/wind_speed = 0.5 -shader_parameter/wind_strength = 0.05 diff --git a/addons/scatter-4/demos/assets/materials/m_mushroom.tres b/addons/scatter-4/demos/assets/materials/m_mushroom.tres deleted file mode 100644 index 04ca9b8..0000000 --- a/addons/scatter-4/demos/assets/materials/m_mushroom.tres +++ /dev/null @@ -1,6 +0,0 @@ -[gd_resource type="StandardMaterial3D" load_steps=2 format=3 uid="uid://ds2hjlo70hglg"] - -[ext_resource type="Texture2D" uid="uid://bay670hln3ji5" path="res://addons/proton_scatter/demos/assets/textures/mushroom.png" id="1_y0tuv"] - -[resource] -albedo_texture = ExtResource("1_y0tuv") diff --git a/addons/scatter-4/demos/assets/materials/m_pine_leaves.tres b/addons/scatter-4/demos/assets/materials/m_pine_leaves.tres deleted file mode 100644 index 6815dae..0000000 --- a/addons/scatter-4/demos/assets/materials/m_pine_leaves.tres +++ /dev/null @@ -1,35 +0,0 @@ -[gd_resource type="ShaderMaterial" load_steps=7 format=3 uid="uid://d28lq2qtgdyie"] - -[ext_resource type="Shader" path="res://addons/proton_scatter/demos/assets/materials/leaves.gdshader" id="1_hlncd"] -[ext_resource type="Texture2D" uid="uid://ctpb1w0cr8tqc" path="res://addons/proton_scatter/demos/assets/textures/t_pine_branch.png" id="2_yef44"] - -[sub_resource type="Gradient" id="Gradient_pookg"] -offsets = PackedFloat32Array(0.38342, 0.694301, 1) -colors = PackedColorArray(0.059375, 0.078125, 0.07, 1, 0.628287, 0.73, 0.1752, 1, 0.897921, 1, 0, 1) - -[sub_resource type="GradientTexture1D" id="GradientTexture1D_n86jv"] -gradient = SubResource("Gradient_pookg") - -[sub_resource type="FastNoiseLite" id="FastNoiseLite_t7o5y"] -seed = 1 -frequency = 0.002 - -[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_03p8g"] -in_3d_space = true -seamless = true -seamless_blend_skirt = 0.65 -noise = SubResource("FastNoiseLite_t7o5y") - -[resource] -render_priority = 0 -shader = ExtResource("1_hlncd") -shader_parameter/alpha_scissor_threshold = 0.3 -shader_parameter/transmission = Color(0.745098, 0.741176, 0, 1) -shader_parameter/total_height = 4.046 -shader_parameter/wind_direction = Vector2(1, -0.5) -shader_parameter/wind_speed = 0.2 -shader_parameter/wind_strength = 0.05 -shader_parameter/noise_scale = 12.0 -shader_parameter/texture_albedo = ExtResource("2_yef44") -shader_parameter/texture_gradient = SubResource("GradientTexture1D_n86jv") -shader_parameter/texture_noise = SubResource("NoiseTexture2D_03p8g") diff --git a/addons/scatter-4/demos/assets/materials/m_rock.tres b/addons/scatter-4/demos/assets/materials/m_rock.tres deleted file mode 100644 index 7b165cb..0000000 --- a/addons/scatter-4/demos/assets/materials/m_rock.tres +++ /dev/null @@ -1,10 +0,0 @@ -[gd_resource type="StandardMaterial3D" load_steps=2 format=3 uid="uid://i0jgjmbbl2m5"] - -[ext_resource type="Texture2D" uid="uid://fdcwowhvwiia" path="res://addons/proton_scatter/demos/assets/textures/t_rock_dirty.png" id="1_hx37f"] - -[resource] -albedo_color = Color(0.439216, 0.407843, 0.388235, 1) -albedo_texture = ExtResource("1_hx37f") -metallic_specular = 0.3 -uv1_triplanar = true -uv1_world_triplanar = true diff --git a/addons/scatter-4/demos/assets/materials/m_trunk.tres b/addons/scatter-4/demos/assets/materials/m_trunk.tres deleted file mode 100644 index b1a2ecc..0000000 --- a/addons/scatter-4/demos/assets/materials/m_trunk.tres +++ /dev/null @@ -1,7 +0,0 @@ -[gd_resource type="StandardMaterial3D" load_steps=2 format=3 uid="uid://d01d0h08lqqn6"] - -[ext_resource type="Texture2D" uid="uid://c72s4mvxck84w" path="res://addons/proton_scatter/demos/assets/textures/t_tree_bark_rough.png" id="1_g4son"] - -[resource] -albedo_color = Color(0.470588, 0.376471, 0.309804, 1) -albedo_texture = ExtResource("1_g4son") diff --git a/addons/scatter-4/demos/assets/materials/m_water.gdshader b/addons/scatter-4/demos/assets/materials/m_water.gdshader deleted file mode 100644 index cff66d1..0000000 --- a/addons/scatter-4/demos/assets/materials/m_water.gdshader +++ /dev/null @@ -1,90 +0,0 @@ -// Source: https://godotshaders.com/shader/toon-water-shader/ - -shader_type spatial; - -const float SMOOTHSTEP_AA = 0.01; -uniform sampler2D surfaceNoise; -uniform sampler2D distortNoise; -uniform sampler2D DEPTH_TEXTURE : hint_depth_texture, filter_linear_mipmap; - -uniform float beer_factor = 0.8; - -uniform float foam_distance = 0.01; -uniform float foam_max_distance = 0.4; -uniform float foam_min_distance = 0.04; -uniform vec4 foam_color: source_color = vec4(1.0); - -uniform vec2 surface_noise_tiling = vec2(1.0, 4.0); -uniform vec3 surface_noise_scroll = vec3(0.03, 0.03, 0.0); -uniform float surface_noise_cutoff: hint_range(0, 1) = 0.777; -uniform float surface_distortion_amount: hint_range(0, 1) = 0.27; - -uniform vec4 _DepthGradientShallow: source_color = vec4(0.325, 0.807, 0.971, 0.725); -uniform vec4 _DepthGradientDeep: source_color = vec4(0.086, 0.407, 1, 0.749); -uniform float _DepthMaxDistance: hint_range(0, 1) = 1.0; -uniform float _DepthFactor = 1.0; - -uniform float roughness = 0.25; -uniform float specular = 0.75; - -varying vec2 noiseUV; -varying vec2 distortUV; -varying vec3 viewNormal; - - -vec4 alphaBlend(vec4 top, vec4 bottom) -{ - vec3 color = (top.rgb * top.a) + (bottom.rgb * (1.0 - top.a)); - float alpha = top.a + bottom.a * (1.0 - top.a); - - return vec4(color, alpha); -} - -void vertex() { - viewNormal = (MODELVIEW_MATRIX * vec4(NORMAL, 0.0)).xyz; - noiseUV = UV * surface_noise_tiling; - distortUV = UV; -} - -void fragment(){ - // https://www.youtube.com/watch?v=Jq3he9Lbj7M - float depthVal = texture(DEPTH_TEXTURE, SCREEN_UV).r; - float depth = PROJECTION_MATRIX[3][2] / (depthVal + PROJECTION_MATRIX[2][2]); - depth = depth + VERTEX.z; - depth = exp(-depth * beer_factor); - depth = 1.0 - depth; - - // Still unsure how to get properly the NORMAL from the camera - // This was generated by ChatGPT xD - vec4 view_pos = INV_PROJECTION_MATRIX * vec4(SCREEN_UV * 2.0 - 1.0, depthVal, 1.0); - view_pos /= view_pos.w; - vec3 existingNormal = normalize(cross( dFdx(view_pos.xyz), dFdy(view_pos.xyz))); - - float normalDot = clamp(dot(existingNormal.xyz, viewNormal), 0.0, 1.0); - float foamDistance = mix(foam_max_distance, foam_min_distance, normalDot); - - float foamDepth = clamp(depth / foamDistance, 0.0, 1.0); - float surfaceNoiseCutoff = foamDepth * surface_noise_cutoff; - - vec4 distortNoiseSample = texture(distortNoise, distortUV); - vec2 distortAmount = (distortNoiseSample.xy * 2.0 -1.0) * surface_distortion_amount; - - vec2 noise_uv = vec2( - (noiseUV.x + TIME * surface_noise_scroll.x) + distortAmount.x , - (noiseUV.y + TIME * surface_noise_scroll.y + distortAmount.y) - ); - float surfaceNoiseSample = texture(surfaceNoise, noise_uv).r; - float surfaceNoiseAmount = smoothstep(surfaceNoiseCutoff - SMOOTHSTEP_AA, surfaceNoiseCutoff + SMOOTHSTEP_AA, surfaceNoiseSample); - - float waterDepth = clamp(depth / _DepthMaxDistance, 0.0, 1.0) * _DepthFactor; - vec4 waterColor = mix(_DepthGradientShallow, _DepthGradientDeep, waterDepth); - - vec4 surfaceNoiseColor = foam_color; - surfaceNoiseColor.a *= surfaceNoiseAmount; - vec4 color = alphaBlend(surfaceNoiseColor, waterColor); - - ALBEDO = color.rgb; - ALPHA = color.a; - ROUGHNESS = roughness; - SPECULAR = specular; -} \ No newline at end of file diff --git a/addons/scatter-4/demos/assets/materials/m_water.tres b/addons/scatter-4/demos/assets/materials/m_water.tres deleted file mode 100644 index 9dcd264..0000000 --- a/addons/scatter-4/demos/assets/materials/m_water.tres +++ /dev/null @@ -1,40 +0,0 @@ -[gd_resource type="ShaderMaterial" load_steps=6 format=3 uid="uid://c7mw5tryqfggw"] - -[ext_resource type="Shader" path="res://addons/proton_scatter/demos/assets/materials/m_water.gdshader" id="1_j8rl3"] - -[sub_resource type="FastNoiseLite" id="FastNoiseLite_7bjdc"] -noise_type = 2 -fractal_type = 3 - -[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_wxuht"] -seamless = true -noise = SubResource("FastNoiseLite_7bjdc") - -[sub_resource type="FastNoiseLite" id="FastNoiseLite_dx86n"] -noise_type = 2 -domain_warp_enabled = true - -[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_1j0ob"] -seamless = true -noise = SubResource("FastNoiseLite_dx86n") - -[resource] -render_priority = 0 -shader = ExtResource("1_j8rl3") -shader_parameter/beer_factor = 4.0 -shader_parameter/foam_distance = 0.01 -shader_parameter/foam_max_distance = 0.345 -shader_parameter/foam_min_distance = 0.05 -shader_parameter/foam_color = Color(1, 1, 1, 0.784314) -shader_parameter/surface_noise_tiling = Vector2(1, 4) -shader_parameter/surface_noise_scroll = Vector3(0.03, 0.03, 0) -shader_parameter/surface_noise_cutoff = 0.875 -shader_parameter/surface_distortion_amount = 0.65 -shader_parameter/_DepthGradientShallow = Color(0.435294, 0.647059, 0.972549, 0.72549) -shader_parameter/_DepthGradientDeep = Color(0.0823529, 0.392157, 0.701961, 0.862745) -shader_parameter/_DepthMaxDistance = 1.0 -shader_parameter/_DepthFactor = 1.0 -shader_parameter/roughness = 0.001 -shader_parameter/specular = 0.5 -shader_parameter/surfaceNoise = SubResource("NoiseTexture2D_1j0ob") -shader_parameter/distortNoise = SubResource("NoiseTexture2D_wxuht") diff --git a/addons/scatter-4/demos/assets/models/brick.glb b/addons/scatter-4/demos/assets/models/brick.glb deleted file mode 100644 index 0748793..0000000 Binary files a/addons/scatter-4/demos/assets/models/brick.glb and /dev/null differ diff --git a/addons/scatter-4/demos/assets/models/bush.glb b/addons/scatter-4/demos/assets/models/bush.glb deleted file mode 100644 index e25bf36..0000000 Binary files a/addons/scatter-4/demos/assets/models/bush.glb and /dev/null differ diff --git a/addons/scatter-4/demos/assets/models/dead_branch.glb b/addons/scatter-4/demos/assets/models/dead_branch.glb deleted file mode 100644 index de35d32..0000000 Binary files a/addons/scatter-4/demos/assets/models/dead_branch.glb and /dev/null differ diff --git a/addons/scatter-4/demos/assets/models/fence_planks.glb b/addons/scatter-4/demos/assets/models/fence_planks.glb deleted file mode 100644 index 2ac79fd..0000000 Binary files a/addons/scatter-4/demos/assets/models/fence_planks.glb and /dev/null differ diff --git a/addons/scatter-4/demos/assets/models/gobot.glb b/addons/scatter-4/demos/assets/models/gobot.glb deleted file mode 100644 index f8a83fe..0000000 Binary files a/addons/scatter-4/demos/assets/models/gobot.glb and /dev/null differ diff --git a/addons/scatter-4/demos/assets/models/grass.glb b/addons/scatter-4/demos/assets/models/grass.glb deleted file mode 100644 index f3a2f57..0000000 Binary files a/addons/scatter-4/demos/assets/models/grass.glb and /dev/null differ diff --git a/addons/scatter-4/demos/assets/models/grass_2.glb b/addons/scatter-4/demos/assets/models/grass_2.glb deleted file mode 100644 index 8c20845..0000000 Binary files a/addons/scatter-4/demos/assets/models/grass_2.glb and /dev/null differ diff --git a/addons/scatter-4/demos/assets/models/large_rock.glb b/addons/scatter-4/demos/assets/models/large_rock.glb deleted file mode 100644 index e88cd6c..0000000 Binary files a/addons/scatter-4/demos/assets/models/large_rock.glb and /dev/null differ diff --git a/addons/scatter-4/demos/assets/models/mushrooms.glb b/addons/scatter-4/demos/assets/models/mushrooms.glb deleted file mode 100644 index 6fc402a..0000000 Binary files a/addons/scatter-4/demos/assets/models/mushrooms.glb and /dev/null differ diff --git a/addons/scatter-4/demos/assets/models/pine_tree.glb b/addons/scatter-4/demos/assets/models/pine_tree.glb deleted file mode 100644 index 2081573..0000000 Binary files a/addons/scatter-4/demos/assets/models/pine_tree.glb and /dev/null differ diff --git a/addons/scatter-4/demos/assets/models/small_rock.glb b/addons/scatter-4/demos/assets/models/small_rock.glb deleted file mode 100644 index f30897f..0000000 Binary files a/addons/scatter-4/demos/assets/models/small_rock.glb and /dev/null differ diff --git a/addons/scatter-4/demos/assets/models/tree.glb b/addons/scatter-4/demos/assets/models/tree.glb deleted file mode 100644 index 92e9012..0000000 Binary files a/addons/scatter-4/demos/assets/models/tree.glb and /dev/null differ diff --git a/addons/scatter-4/demos/assets/mushroom.tscn b/addons/scatter-4/demos/assets/mushroom.tscn deleted file mode 100644 index 43d1923..0000000 --- a/addons/scatter-4/demos/assets/mushroom.tscn +++ /dev/null @@ -1,9 +0,0 @@ -[gd_scene load_steps=3 format=3 uid="uid://bodkixm8bubes"] - -[ext_resource type="PackedScene" uid="uid://c38uugpgw7hjm" path="res://addons/proton_scatter/demos/assets/models/mushrooms.glb" id="1_spmys"] -[ext_resource type="Material" uid="uid://ds2hjlo70hglg" path="res://addons/proton_scatter/demos/assets/materials/m_mushroom.tres" id="2_y6jw1"] - -[node name="mushrooms" instance=ExtResource("1_spmys")] - -[node name="Sphere001" parent="." index="0"] -surface_material_override/0 = ExtResource("2_y6jw1") diff --git a/addons/scatter-4/demos/assets/pine_tree.tscn b/addons/scatter-4/demos/assets/pine_tree.tscn deleted file mode 100644 index 9f1b08c..0000000 --- a/addons/scatter-4/demos/assets/pine_tree.tscn +++ /dev/null @@ -1,31 +0,0 @@ -[gd_scene load_steps=6 format=3 uid="uid://caqxfqurbp3ku"] - -[ext_resource type="PackedScene" uid="uid://bhums0j31gm5n" path="res://addons/proton_scatter/demos/assets/models/pine_tree.glb" id="1_hw1e5"] -[ext_resource type="Material" uid="uid://d01d0h08lqqn6" path="res://addons/proton_scatter/demos/assets/materials/m_trunk.tres" id="2_cgtpc"] -[ext_resource type="Material" uid="uid://d28lq2qtgdyie" path="res://addons/proton_scatter/demos/assets/materials/m_pine_leaves.tres" id="2_xnytt"] - -[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_2xqpo"] -radius = 0.0750397 -height = 1.3553 - -[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_uhp33"] -radius = 0.101768 -height = 0.489166 - -[node name="pine_tree" instance=ExtResource("1_hw1e5")] - -[node name="Trunk" parent="." index="0"] -surface_material_override/0 = ExtResource("2_cgtpc") - -[node name="Leaves" parent="." index="1"] -surface_material_override/0 = ExtResource("2_xnytt") - -[node name="StaticBody3D" type="StaticBody3D" parent="." index="2"] - -[node name="CollisionShape3D" type="CollisionShape3D" parent="StaticBody3D" index="0"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.661681, 0) -shape = SubResource("CapsuleShape3D_2xqpo") - -[node name="CollisionShape3D2" type="CollisionShape3D" parent="StaticBody3D" index="1"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.015189, 0) -shape = SubResource("CapsuleShape3D_uhp33") diff --git a/addons/scatter-4/demos/assets/small_rock.tscn b/addons/scatter-4/demos/assets/small_rock.tscn deleted file mode 100644 index 2025b28..0000000 --- a/addons/scatter-4/demos/assets/small_rock.tscn +++ /dev/null @@ -1,9 +0,0 @@ -[gd_scene load_steps=3 format=3 uid="uid://bltmr2xgs8nq1"] - -[ext_resource type="PackedScene" uid="uid://b81l25tbebki4" path="res://addons/proton_scatter/demos/assets/models/small_rock.glb" id="1_e2qk6"] -[ext_resource type="Material" uid="uid://i0jgjmbbl2m5" path="res://addons/proton_scatter/demos/assets/materials/m_rock.tres" id="2_clsfy"] - -[node name="small_rock" instance=ExtResource("1_e2qk6")] - -[node name="SmallRock" parent="." index="0"] -surface_material_override/0 = ExtResource("2_clsfy") diff --git a/addons/scatter-4/demos/assets/source.blend b/addons/scatter-4/demos/assets/source.blend deleted file mode 100644 index f973cf9..0000000 Binary files a/addons/scatter-4/demos/assets/source.blend and /dev/null differ diff --git a/addons/scatter-4/demos/assets/textures/mushroom.png b/addons/scatter-4/demos/assets/textures/mushroom.png deleted file mode 100644 index f1f960d..0000000 Binary files a/addons/scatter-4/demos/assets/textures/mushroom.png and /dev/null differ diff --git a/addons/scatter-4/demos/assets/textures/sky_2.png b/addons/scatter-4/demos/assets/textures/sky_2.png deleted file mode 100644 index 921ae63..0000000 Binary files a/addons/scatter-4/demos/assets/textures/sky_2.png and /dev/null differ diff --git a/addons/scatter-4/demos/assets/textures/t_bush.png b/addons/scatter-4/demos/assets/textures/t_bush.png deleted file mode 100644 index 3afb9f9..0000000 Binary files a/addons/scatter-4/demos/assets/textures/t_bush.png and /dev/null differ diff --git a/addons/scatter-4/demos/assets/textures/t_grass.png b/addons/scatter-4/demos/assets/textures/t_grass.png deleted file mode 100644 index 2f712d4..0000000 Binary files a/addons/scatter-4/demos/assets/textures/t_grass.png and /dev/null differ diff --git a/addons/scatter-4/demos/assets/textures/t_grass_2.png b/addons/scatter-4/demos/assets/textures/t_grass_2.png deleted file mode 100644 index 346a5c1..0000000 Binary files a/addons/scatter-4/demos/assets/textures/t_grass_2.png and /dev/null differ diff --git a/addons/scatter-4/demos/assets/textures/t_leaves_1.png b/addons/scatter-4/demos/assets/textures/t_leaves_1.png deleted file mode 100644 index 1913781..0000000 Binary files a/addons/scatter-4/demos/assets/textures/t_leaves_1.png and /dev/null differ diff --git a/addons/scatter-4/demos/assets/textures/t_pine_branch.png b/addons/scatter-4/demos/assets/textures/t_pine_branch.png deleted file mode 100644 index 26ea314..0000000 Binary files a/addons/scatter-4/demos/assets/textures/t_pine_branch.png and /dev/null differ diff --git a/addons/scatter-4/demos/assets/textures/t_rock.jpg b/addons/scatter-4/demos/assets/textures/t_rock.jpg deleted file mode 100644 index d709604..0000000 Binary files a/addons/scatter-4/demos/assets/textures/t_rock.jpg and /dev/null differ diff --git a/addons/scatter-4/demos/assets/textures/t_rock_dirty.png b/addons/scatter-4/demos/assets/textures/t_rock_dirty.png deleted file mode 100644 index 69ef74c..0000000 Binary files a/addons/scatter-4/demos/assets/textures/t_rock_dirty.png and /dev/null differ diff --git a/addons/scatter-4/demos/assets/textures/t_sand.png b/addons/scatter-4/demos/assets/textures/t_sand.png deleted file mode 100644 index 244c60b..0000000 Binary files a/addons/scatter-4/demos/assets/textures/t_sand.png and /dev/null differ diff --git a/addons/scatter-4/demos/assets/textures/t_tree_bark.png b/addons/scatter-4/demos/assets/textures/t_tree_bark.png deleted file mode 100755 index 73529aa..0000000 Binary files a/addons/scatter-4/demos/assets/textures/t_tree_bark.png and /dev/null differ diff --git a/addons/scatter-4/demos/assets/textures/t_tree_bark_rough.png b/addons/scatter-4/demos/assets/textures/t_tree_bark_rough.png deleted file mode 100644 index 80823c2..0000000 Binary files a/addons/scatter-4/demos/assets/textures/t_tree_bark_rough.png and /dev/null differ diff --git a/addons/scatter-4/demos/showcase.tscn b/addons/scatter-4/demos/showcase.tscn deleted file mode 100644 index fde7ff4..0000000 --- a/addons/scatter-4/demos/showcase.tscn +++ /dev/null @@ -1,715 +0,0 @@ -[gd_scene load_steps=78 format=3 uid="uid://dga4klregd82"] - -[ext_resource type="Texture2D" uid="uid://bgc5rl13dopuj" path="res://addons/proton_scatter/demos/assets/textures/sky_2.png" id="1_bp1wy"] -[ext_resource type="Script" path="res://addons/proton_scatter/src/scatter.gd" id="1_odnwj"] -[ext_resource type="Script" path="res://addons/proton_scatter/src/stack/modifier_stack.gd" id="2_wdwa6"] -[ext_resource type="Script" path="res://addons/proton_scatter/src/scatter_item.gd" id="3_tn31i"] -[ext_resource type="Material" uid="uid://c7mw5tryqfggw" path="res://addons/proton_scatter/demos/assets/materials/m_water.tres" id="3_yrj3o"] -[ext_resource type="Script" path="res://addons/proton_scatter/src/scatter_shape.gd" id="4_5klvy"] -[ext_resource type="Script" path="res://addons/proton_scatter/src/modifiers/create_inside_grid.gd" id="4_cnevb"] -[ext_resource type="Script" path="res://addons/proton_scatter/src/modifiers/randomize_transforms.gd" id="5_h0430"] -[ext_resource type="Script" path="res://addons/proton_scatter/src/shapes/path_shape.gd" id="8_vjeqj"] -[ext_resource type="Script" path="res://addons/proton_scatter/src/shapes/sphere_shape.gd" id="9_mhcwm"] -[ext_resource type="Script" path="res://addons/proton_scatter/src/shapes/box_shape.gd" id="11_lv5tc"] -[ext_resource type="Script" path="res://addons/proton_scatter/src/modifiers/relax.gd" id="12_04tbd"] -[ext_resource type="Script" path="res://addons/proton_scatter/src/modifiers/project_on_geometry.gd" id="13_s5uny"] -[ext_resource type="PackedScene" uid="uid://bmglbfn5jaubp" path="res://addons/proton_scatter/demos/assets/gobot.tscn" id="15_mnk3f"] -[ext_resource type="Script" path="res://addons/proton_scatter/src/modifiers/create_inside_random.gd" id="15_terd0"] -[ext_resource type="Script" path="res://addons/proton_scatter/src/modifiers/randomize_rotation.gd" id="16_qmwrn"] -[ext_resource type="Script" path="res://addons/proton_scatter/src/modifiers/array.gd" id="17_2af2s"] - -[sub_resource type="PanoramaSkyMaterial" id="PanoramaSkyMaterial_bxgb5"] -panorama = ExtResource("1_bp1wy") - -[sub_resource type="Sky" id="Sky_ju840"] -sky_material = SubResource("PanoramaSkyMaterial_bxgb5") - -[sub_resource type="Environment" id="Environment_1kod5"] -background_mode = 2 -background_energy_multiplier = 1.25 -sky = SubResource("Sky_ju840") -sky_rotation = Vector3(0, 1.13446, 0) -ambient_light_color = Color(0.352941, 0.215686, 0.529412, 1) -ambient_light_sky_contribution = 0.2 -ambient_light_energy = 0.5 -tonemap_mode = 3 -tonemap_white = 1.2 -glow_enabled = true -fog_enabled = true -fog_light_color = Color(0.243137, 0.411765, 0.607843, 1) -fog_light_energy = 1.8 -fog_density = 0.02 -fog_sky_affect = 0.05 -fog_height = 4.0 -fog_height_density = 0.02 -volumetric_fog_temporal_reprojection_enabled = false -adjustment_enabled = true -adjustment_contrast = 1.15 -adjustment_saturation = 1.1 - -[sub_resource type="PlaneMesh" id="PlaneMesh_84bvf"] -size = Vector2(300, 300) - -[sub_resource type="Resource" id="Resource_6c8re"] -script = ExtResource("4_cnevb") -spacing = Vector3(1.5, 2, 1) -enabled = true -override_global_seed = false -custom_seed = 0 -restrict_height = true -reference_frame = 0 - -[sub_resource type="Resource" id="Resource_js1jv"] -script = ExtResource("5_h0430") -position = Vector3(0.173, 0.222, 0.918) -rotation = Vector3(10, 360, 10) -scale = Vector3(1.201, 0.399, 1.183) -enabled = true -override_global_seed = true -custom_seed = 4 -restrict_height = false -reference_frame = 2 - -[sub_resource type="Resource" id="Resource_cp6c8"] -script = ExtResource("16_qmwrn") -rotation = Vector3(360, 0, 360) -snap_angle = Vector3(180, 0, 180) -enabled = true -override_global_seed = false -custom_seed = 0 -restrict_height = false -reference_frame = 2 - -[sub_resource type="Resource" id="Resource_8xlqi"] -script = ExtResource("2_wdwa6") -stack = Array[Resource]([SubResource("Resource_6c8re"), SubResource("Resource_js1jv"), SubResource("Resource_cp6c8")]) - -[sub_resource type="Curve3D" id="Curve3D_ew6qf"] -_data = { -"points": PackedVector3Array(3.80872, 0, 0.938568, -3.80872, 0, -0.938568, -5.23002, 0, 0.969148, -4.01273, -4.76837e-07, 0.319402, 4.01273, 4.76837e-07, -0.319402, -4.0201, 0, -3.87154, 0.483762, 0, -2.35326, -0.483762, 0, 2.35326, 2.27396, 0, -0.779812), -"tilts": PackedFloat32Array(0, 0, 0) -} -point_count = 3 - -[sub_resource type="Resource" id="Resource_ftiyl"] -script = ExtResource("8_vjeqj") -closed = true -thickness = 0.0 -curve = SubResource("Curve3D_ew6qf") - -[sub_resource type="Resource" id="Resource_kskpi"] -script = ExtResource("4_cnevb") -spacing = Vector3(4, 4, 4) -enabled = true -override_global_seed = false -custom_seed = 0 -restrict_height = true -reference_frame = 0 - -[sub_resource type="Resource" id="Resource_solyr"] -script = ExtResource("5_h0430") -position = Vector3(10, 4, 10) -rotation = Vector3(10, 180, 10) -scale = Vector3(5, 5, 5) -enabled = true -override_global_seed = true -custom_seed = 25 -restrict_height = false -reference_frame = 2 - -[sub_resource type="Resource" id="Resource_j43hv"] -script = ExtResource("16_qmwrn") -rotation = Vector3(360, 0, 360) -snap_angle = Vector3(180, 0, 180) -enabled = true -override_global_seed = false -custom_seed = 0 -restrict_height = false -reference_frame = 2 - -[sub_resource type="Resource" id="Resource_33b0f"] -script = ExtResource("2_wdwa6") -stack = Array[Resource]([SubResource("Resource_kskpi"), SubResource("Resource_solyr"), SubResource("Resource_j43hv")]) - -[sub_resource type="Resource" id="Resource_1jvqx"] -script = ExtResource("11_lv5tc") -size = Vector3(29.1644, 1, 11.2962) - -[sub_resource type="Resource" id="Resource_2jkyh"] -script = ExtResource("15_terd0") -amount = 14 -enabled = true -override_global_seed = true -custom_seed = 30 -restrict_height = false -reference_frame = 1 - -[sub_resource type="Resource" id="Resource_lh4ex"] -script = ExtResource("12_04tbd") -iterations = 5 -offset_step = 0.1 -consecutive_step_multiplier = 0.5 -enabled = true -override_global_seed = false -custom_seed = 0 -restrict_height = true -reference_frame = 0 - -[sub_resource type="Resource" id="Resource_rgn8a"] -script = ExtResource("13_s5uny") -ray_direction = Vector3(0, -1, 0) -ray_length = 10.0 -ray_offset = 1.0 -remove_points_on_miss = true -align_with_collision_normal = false -max_slope = 90.0 -collision_mask = 1 -enabled = true -override_global_seed = false -custom_seed = 0 -restrict_height = false -reference_frame = 0 - -[sub_resource type="Resource" id="Resource_7pgn6"] -script = ExtResource("5_h0430") -position = Vector3(0, 0, 0) -rotation = Vector3(0, 0, 0) -scale = Vector3(3, 3, 3) -enabled = true -override_global_seed = true -custom_seed = 30 -restrict_height = false -reference_frame = 2 - -[sub_resource type="Resource" id="Resource_bwydp"] -script = ExtResource("2_wdwa6") -stack = Array[Resource]([SubResource("Resource_2jkyh"), SubResource("Resource_lh4ex"), SubResource("Resource_rgn8a"), SubResource("Resource_7pgn6")]) - -[sub_resource type="Curve3D" id="Curve3D_p31po"] -_data = { -"points": PackedVector3Array(0, 0, 0, 0, 0, 0, -5.18137, -4.76837e-07, 0.742086, 0, 0, 0, 0, 0, 0, -6.91097, -2.38419e-07, -2.62414, 0, 0, 0, 0, 0, 0, 4.23263, 0, -2.10494, 0, 0, 0, 0, 0, 0, 4.13477, 0, -0.306146, 0, 0, 0, 0, 0, 0, -1.36184, 0, 1.16488), -"tilts": PackedFloat32Array(0, 0, 0, 0, 0) -} -point_count = 5 - -[sub_resource type="Resource" id="Resource_jto6x"] -script = ExtResource("8_vjeqj") -closed = true -thickness = 0.0 -curve = SubResource("Curve3D_p31po") - -[sub_resource type="Resource" id="Resource_ae4op"] -script = ExtResource("15_terd0") -amount = 500 -enabled = true -override_global_seed = true -custom_seed = 7 -restrict_height = true -reference_frame = 1 - -[sub_resource type="Resource" id="Resource_g4wmd"] -script = ExtResource("5_h0430") -position = Vector3(0, 0, 0) -rotation = Vector3(360, 360, 360) -scale = Vector3(1.5, 1.5, 1.5) -enabled = true -override_global_seed = false -custom_seed = 0 -restrict_height = false -reference_frame = 2 - -[sub_resource type="Resource" id="Resource_jagld"] -script = ExtResource("13_s5uny") -ray_direction = Vector3(0, -1, 0) -ray_length = 10.0 -ray_offset = 1.0 -remove_points_on_miss = true -align_with_collision_normal = false -max_slope = 90.0 -collision_mask = 1 -enabled = true -override_global_seed = false -custom_seed = 0 -restrict_height = false -reference_frame = 0 - -[sub_resource type="Resource" id="Resource_4tdre"] -script = ExtResource("2_wdwa6") -stack = Array[Resource]([SubResource("Resource_ae4op"), SubResource("Resource_g4wmd"), SubResource("Resource_jagld")]) - -[sub_resource type="Resource" id="Resource_0weea"] -script = ExtResource("11_lv5tc") -size = Vector3(11.3737, 0.642154, 5.57444) - -[sub_resource type="Resource" id="Resource_2o5oc"] -script = ExtResource("15_terd0") -amount = 10000 -enabled = true -override_global_seed = false -custom_seed = 0 -restrict_height = true -reference_frame = 1 - -[sub_resource type="Resource" id="Resource_8ser0"] -script = ExtResource("5_h0430") -position = Vector3(0.2, 0, 0.2) -rotation = Vector3(20, 360, 20) -scale = Vector3(6, 5, 6) -enabled = true -override_global_seed = false -custom_seed = 0 -restrict_height = false -reference_frame = 2 - -[sub_resource type="Resource" id="Resource_75nf0"] -script = ExtResource("13_s5uny") -ray_direction = Vector3(0, -1, 0) -ray_length = 10.0 -ray_offset = 1.0 -remove_points_on_miss = true -align_with_collision_normal = false -max_slope = 20.0 -collision_mask = 1 -enabled = true -override_global_seed = false -custom_seed = 0 -restrict_height = false -reference_frame = 0 - -[sub_resource type="Resource" id="Resource_v2tsa"] -script = ExtResource("2_wdwa6") -stack = Array[Resource]([SubResource("Resource_2o5oc"), SubResource("Resource_8ser0"), SubResource("Resource_75nf0")]) - -[sub_resource type="Resource" id="Resource_iou5c"] -script = ExtResource("9_mhcwm") -radius = 3.03782 - -[sub_resource type="Resource" id="Resource_llvm5"] -script = ExtResource("9_mhcwm") -radius = 2.15656 - -[sub_resource type="Resource" id="Resource_5qcqk"] -script = ExtResource("4_cnevb") -spacing = Vector3(0.2, 0.3, 0.2) -enabled = true -override_global_seed = false -custom_seed = 0 -restrict_height = false -reference_frame = 0 - -[sub_resource type="Resource" id="Resource_fxfw2"] -script = ExtResource("16_qmwrn") -rotation = Vector3(0, 360, 0) -snap_angle = Vector3(0, 0, 0) -enabled = true -override_global_seed = false -custom_seed = 0 -restrict_height = false -reference_frame = 2 - -[sub_resource type="Resource" id="Resource_6jn28"] -script = ExtResource("5_h0430") -position = Vector3(0, 0.107, 0) -rotation = Vector3(0, 360, 0) -scale = Vector3(0.75, 0.75, 0.75) -enabled = true -override_global_seed = true -custom_seed = 20 -restrict_height = false -reference_frame = 2 - -[sub_resource type="Resource" id="Resource_hs61a"] -script = ExtResource("13_s5uny") -ray_direction = Vector3(0, 0, 1) -ray_length = 1.0 -ray_offset = 0.5 -remove_points_on_miss = true -align_with_collision_normal = false -max_slope = 90.0 -collision_mask = 1 -enabled = true -override_global_seed = false -custom_seed = 0 -restrict_height = false -reference_frame = 2 - -[sub_resource type="Resource" id="Resource_u4rnr"] -script = ExtResource("2_wdwa6") -stack = Array[Resource]([SubResource("Resource_5qcqk"), SubResource("Resource_fxfw2"), SubResource("Resource_6jn28"), SubResource("Resource_hs61a")]) - -[sub_resource type="Resource" id="Resource_272xj"] -script = ExtResource("11_lv5tc") -size = Vector3(1.64858, 0.539851, 0.847638) - -[sub_resource type="Resource" id="Resource_p1ngd"] -script = ExtResource("11_lv5tc") -size = Vector3(1.07363, 0.537276, 1.1214) - -[sub_resource type="Resource" id="Resource_is18q"] -script = ExtResource("11_lv5tc") -size = Vector3(2.15312, 0.683458, 0.916096) - -[sub_resource type="Resource" id="Resource_jheb7"] -script = ExtResource("15_terd0") -amount = 150 -enabled = true -override_global_seed = false -custom_seed = 0 -restrict_height = false -reference_frame = 1 - -[sub_resource type="Resource" id="Resource_p6u0x"] -script = ExtResource("5_h0430") -position = Vector3(0.058, 0, 0.086) -rotation = Vector3(360, 360, 360) -scale = Vector3(4, 4, 4) -enabled = true -override_global_seed = false -custom_seed = 0 -restrict_height = false -reference_frame = 2 - -[sub_resource type="Resource" id="Resource_mijan"] -script = ExtResource("13_s5uny") -ray_direction = Vector3(0, -1, 0) -ray_length = 10.0 -ray_offset = 1.0 -remove_points_on_miss = true -align_with_collision_normal = true -max_slope = 90.0 -collision_mask = 1 -enabled = true -override_global_seed = false -custom_seed = 0 -restrict_height = false -reference_frame = 0 - -[sub_resource type="Resource" id="Resource_3cg3d"] -script = ExtResource("2_wdwa6") -stack = Array[Resource]([SubResource("Resource_jheb7"), SubResource("Resource_p6u0x"), SubResource("Resource_mijan")]) - -[sub_resource type="Curve3D" id="Curve3D_lorvn"] -_data = { -"points": PackedVector3Array(0, 0, 0, 0, 0, 0, -3.37811, 0, 0.414886, 0, 0, 0, 0, 0, 0, -6.85248, 0, 0.176656, 0, 0, 0, 0, 0, 0, -6.65984, 0, -2.15071, 0, 0, 0, 0, 0, 0, 0.0761006, 0, -2.44185, 0, 0, 0, 0, 0, 0, 0.0166965, 0, -0.474161), -"tilts": PackedFloat32Array(0, 0, 0, 0, 0) -} -point_count = 5 - -[sub_resource type="Resource" id="Resource_ojpr0"] -script = ExtResource("8_vjeqj") -closed = true -thickness = 0.0 -curve = SubResource("Curve3D_lorvn") - -[sub_resource type="Resource" id="Resource_ubw23"] -script = ExtResource("15_terd0") -amount = 13 -enabled = true -override_global_seed = false -custom_seed = 0 -restrict_height = true -reference_frame = 1 - -[sub_resource type="Resource" id="Resource_pwqrf"] -script = ExtResource("12_04tbd") -iterations = 5 -offset_step = 0.02 -consecutive_step_multiplier = 0.35 -enabled = true -override_global_seed = false -custom_seed = 0 -restrict_height = true -reference_frame = 0 - -[sub_resource type="Resource" id="Resource_v58t8"] -script = ExtResource("5_h0430") -position = Vector3(1, 1, 1) -rotation = Vector3(0, 360, 0) -scale = Vector3(0.2, 0.2, 0.2) -enabled = true -override_global_seed = true -custom_seed = 9 -restrict_height = false -reference_frame = 2 - -[sub_resource type="Resource" id="Resource_pdeyv"] -script = ExtResource("13_s5uny") -ray_direction = Vector3(0, -1, 0) -ray_length = 10.0 -ray_offset = 1.0 -remove_points_on_miss = true -align_with_collision_normal = false -max_slope = 90.0 -collision_mask = 1 -enabled = true -override_global_seed = false -custom_seed = 0 -restrict_height = false -reference_frame = 0 - -[sub_resource type="Resource" id="Resource_kuroc"] -script = ExtResource("2_wdwa6") -stack = Array[Resource]([SubResource("Resource_ubw23"), SubResource("Resource_pwqrf"), SubResource("Resource_v58t8"), SubResource("Resource_pdeyv")]) - -[sub_resource type="Resource" id="Resource_bpfxh"] -script = ExtResource("9_mhcwm") -radius = 1.57673 - -[sub_resource type="Resource" id="Resource_rspgw"] -script = ExtResource("9_mhcwm") -radius = 1.57673 - -[sub_resource type="Resource" id="Resource_q8na6"] -script = ExtResource("4_cnevb") -spacing = Vector3(0.78, 2, 0.78) -enabled = true -override_global_seed = false -custom_seed = 0 -restrict_height = true -reference_frame = 1 - -[sub_resource type="Resource" id="Resource_2nnk7"] -script = ExtResource("17_2af2s") -amount = 1 -min_amount = -1 -local_offset = true -offset = Vector3(0.39, 0, 0) -local_rotation = false -rotation = Vector3(0, 0, 0) -individual_rotation_pivots = true -rotation_pivot = Vector3(0, 0, 0) -local_scale = true -scale = Vector3(1, 1, 1) -randomize_indices = false -enabled = true -override_global_seed = false -custom_seed = 0 -restrict_height = false -reference_frame = 0 - -[sub_resource type="Resource" id="Resource_gtgt8"] -script = ExtResource("17_2af2s") -amount = 1 -min_amount = -1 -local_offset = true -offset = Vector3(0.195, 0, 0.39) -local_rotation = false -rotation = Vector3(0, 0, 0) -individual_rotation_pivots = true -rotation_pivot = Vector3(0, 0, 0) -local_scale = true -scale = Vector3(1, 1, 1) -randomize_indices = true -enabled = true -override_global_seed = false -custom_seed = 0 -restrict_height = false -reference_frame = 0 - -[sub_resource type="Resource" id="Resource_jlbar"] -script = ExtResource("5_h0430") -position = Vector3(0, 0.02, 0) -rotation = Vector3(0, 0, 0) -scale = Vector3(0, 0, 0) -enabled = true -override_global_seed = false -custom_seed = 0 -restrict_height = false -reference_frame = 2 - -[sub_resource type="Resource" id="Resource_nle4h"] -script = ExtResource("2_wdwa6") -stack = Array[Resource]([SubResource("Resource_q8na6"), SubResource("Resource_2nnk7"), SubResource("Resource_gtgt8"), SubResource("Resource_jlbar")]) - -[sub_resource type="Resource" id="Resource_3agf6"] -script = ExtResource("11_lv5tc") -size = Vector3(3.74466, 1, 3.51889) - -[node name="ProtonScatterShowcase" type="Node3D"] - -[node name="Lighting" type="Node3D" parent="."] - -[node name="DirectionalLight3D" type="DirectionalLight3D" parent="Lighting"] -transform = Transform3D(0.422618, -0.383022, 0.821394, 0, 0.906308, 0.422618, -0.906308, -0.178606, 0.383022, 0, 2.29496, 0) -light_color = Color(1, 0.941176, 0.921569, 1) -light_energy = 2.0 -light_indirect_energy = 0.5 -shadow_enabled = true -shadow_opacity = 0.85 -shadow_blur = 0.2 -directional_shadow_max_distance = 20.0 - -[node name="WorldEnvironment" type="WorldEnvironment" parent="Lighting"] -environment = SubResource("Environment_1kod5") - -[node name="Camera3D" type="Camera3D" parent="Lighting"] -transform = Transform3D(1, 0, 0, 0, 0.98872, 0.149777, 0, -0.149777, 0.98872, -3.319, 2.435, 4.146) - -[node name="gobot" parent="." instance=ExtResource("15_mnk3f")] -transform = Transform3D(0.269842, -0.00767393, 0.420864, -0.0348094, 0.497798, 0.0313953, -0.419492, -0.0462436, 0.26812, -5.95266, 0.505731, 0.83356) - -[node name="Water" type="MeshInstance3D" parent="."] -material_override = ExtResource("3_yrj3o") -cast_shadow = 0 -mesh = SubResource("PlaneMesh_84bvf") -metadata/_edit_lock_ = true -metadata/_edit_group_ = true - -[node name="MainGround" type="Node3D" parent="."] -script = ExtResource("1_odnwj") -use_instancing = false -modifier_stack = SubResource("Resource_8xlqi") - -[node name="ScatterItem" type="Node3D" parent="MainGround"] -script = ExtResource("3_tn31i") -source_scale_multiplier = 0.4 -path = "res://addons/proton_scatter/demos/assets/large_rock.tscn" - -[node name="PathShape" type="Node3D" parent="MainGround"] -script = ExtResource("4_5klvy") -shape = SubResource("Resource_ftiyl") - -[node name="BackgroundMountain" type="Node3D" parent="."] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 68.323, 0, -80.067) -script = ExtResource("1_odnwj") -modifier_stack = SubResource("Resource_33b0f") - -[node name="ScatterItem" type="Node3D" parent="BackgroundMountain"] -script = ExtResource("3_tn31i") -path = "res://addons/proton_scatter/demos/assets/large_rock.tscn" - -[node name="BoxShape" type="Node3D" parent="BackgroundMountain"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.41334, -0.086071, -0.341324) -script = ExtResource("4_5klvy") -shape = SubResource("Resource_1jvqx") - -[node name="Trees" type="Node3D" parent="."] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.64893, 0, -0.774464) -script = ExtResource("1_odnwj") -use_instancing = false -scatter_parent = NodePath("../MainGround") -modifier_stack = SubResource("Resource_bwydp") - -[node name="ScatterItem" type="Node3D" parent="Trees"] -script = ExtResource("3_tn31i") -source_scale_multiplier = 0.4 -path = "res://addons/proton_scatter/demos/assets/pine_tree.tscn" - -[node name="PathShape" type="Node3D" parent="Trees"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0376822, 0, -0.0782702) -script = ExtResource("4_5klvy") -shape = SubResource("Resource_jto6x") - -[node name="SmallRocks" type="Node3D" parent="."] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.58903, 0.624608, -1.05701) -script = ExtResource("1_odnwj") -scatter_parent = NodePath("../MainGround") -modifier_stack = SubResource("Resource_4tdre") - -[node name="ScatterItem" type="Node3D" parent="SmallRocks"] -script = ExtResource("3_tn31i") -source_scale_multiplier = 0.2 -path = "res://addons/proton_scatter/demos/assets/small_rock.tscn" - -[node name="BoxShape" type="Node3D" parent="SmallRocks"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.279, -0.69077, 0.16165) -script = ExtResource("4_5klvy") -shape = SubResource("Resource_0weea") - -[node name="Grass" type="Node3D" parent="."] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4.53694, 0.590527, -0.866904) -script = ExtResource("1_odnwj") -scatter_parent = NodePath("../MainGround") -modifier_stack = SubResource("Resource_v2tsa") - -[node name="ScatterItem" type="Node3D" parent="Grass"] -script = ExtResource("3_tn31i") -source_scale_multiplier = 0.15 -path = "res://addons/proton_scatter/demos/assets/grass_2.tscn" - -[node name="SphereShape" type="Node3D" parent="Grass"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.66162, 1.19209e-07, -0.977096) -script = ExtResource("4_5klvy") -shape = SubResource("Resource_iou5c") - -[node name="SphereShape2" type="Node3D" parent="Grass"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.21329, 0.0320051, -0.71306) -script = ExtResource("4_5klvy") -shape = SubResource("Resource_llvm5") - -[node name="Mushrooms" type="Node3D" parent="."] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.48012, 0.850601, -0.986201) -script = ExtResource("1_odnwj") -scatter_parent = NodePath("../Trees") -dbg_disable_thread = true -modifier_stack = SubResource("Resource_u4rnr") - -[node name="ScatterItem" type="Node3D" parent="Mushrooms"] -script = ExtResource("3_tn31i") -source_scale_multiplier = 0.2 -path = "res://addons/proton_scatter/demos/assets/mushroom.tscn" - -[node name="ScatterShape" type="Node3D" parent="Mushrooms"] -transform = Transform3D(0.992366, 0, 0.123324, -0.00806148, 0.997861, 0.0648693, -0.12306, -0.0653683, 0.990244, -0.545904, 0.200069, -0.0382232) -script = ExtResource("4_5klvy") -shape = SubResource("Resource_272xj") - -[node name="ScatterShape2" type="Node3D" parent="Mushrooms"] -transform = Transform3D(0.702501, 0, 0.711683, 0, 1, 0, -0.711683, 0, 0.702501, -2.18823, 0.0800232, 0.866356) -script = ExtResource("4_5klvy") -shape = SubResource("Resource_p1ngd") - -[node name="ScatterShape3" type="Node3D" parent="Mushrooms"] -transform = Transform3D(0.82657, 0, 0.562834, 0, 1, 0, -0.562834, 0, 0.82657, -2.31684, 0.0552569, -1.67132) -script = ExtResource("4_5klvy") -shape = SubResource("Resource_is18q") - -[node name="DeadBranches" type="Node3D" parent="."] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.572101, 0) -script = ExtResource("1_odnwj") -scatter_parent = NodePath("../MainGround") -modifier_stack = SubResource("Resource_3cg3d") - -[node name="ScatterItem" type="Node3D" parent="DeadBranches"] -script = ExtResource("3_tn31i") -source_scale_multiplier = 0.6 -path = "res://addons/proton_scatter/demos/assets/dead_branch.tscn" - -[node name="ScatterShape" type="Node3D" parent="DeadBranches"] -script = ExtResource("4_5klvy") -shape = SubResource("Resource_ojpr0") - -[node name="Bushes" type="Node3D" parent="."] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.222831, 0.534039, -1.07373) -script = ExtResource("1_odnwj") -modifier_stack = SubResource("Resource_kuroc") - -[node name="ScatterItem" type="Node3D" parent="Bushes"] -script = ExtResource("3_tn31i") -source_scale_multiplier = 0.7 -path = "res://addons/proton_scatter/demos/assets/bush.tscn" - -[node name="ScatterShape" type="Node3D" parent="Bushes"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.300213, 4.76837e-07, -0.398241) -script = ExtResource("4_5klvy") -shape = SubResource("Resource_bpfxh") - -[node name="ScatterShape2" type="Node3D" parent="Bushes"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.9127, 4.76837e-07, -1.13497) -script = ExtResource("4_5klvy") -shape = SubResource("Resource_rspgw") - -[node name="Platform" type="Node3D" parent="."] -transform = Transform3D(0.330514, 0, 0.943801, 0, 1, 0, -0.943801, 0, 0.330514, -12.248, 0, -5.402) -script = ExtResource("1_odnwj") -dbg_disable_thread = true -modifier_stack = SubResource("Resource_nle4h") - -[node name="ScatterItem" type="Node3D" parent="Platform"] -script = ExtResource("3_tn31i") -path = "res://addons/proton_scatter/demos/assets/brick.tscn" - -[node name="ScatterShape" type="Node3D" parent="Platform"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.248102, 0, 0.914603) -script = ExtResource("4_5klvy") -shape = SubResource("Resource_3agf6") diff --git a/addons/scatter-4/icons/add.svg b/addons/scatter-4/icons/add.svg deleted file mode 100644 index a241829..0000000 --- a/addons/scatter-4/icons/add.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/addons/scatter-4/icons/arrow_down.svg b/addons/scatter-4/icons/arrow_down.svg deleted file mode 100644 index fac4a77..0000000 --- a/addons/scatter-4/icons/arrow_down.svg +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - diff --git a/addons/scatter-4/icons/arrow_exp.svg b/addons/scatter-4/icons/arrow_exp.svg deleted file mode 100644 index 41a4cf0..0000000 --- a/addons/scatter-4/icons/arrow_exp.svg +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - diff --git a/addons/scatter-4/icons/arrow_linear.svg b/addons/scatter-4/icons/arrow_linear.svg deleted file mode 100644 index caacb92..0000000 --- a/addons/scatter-4/icons/arrow_linear.svg +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - diff --git a/addons/scatter-4/icons/arrow_log.svg b/addons/scatter-4/icons/arrow_log.svg deleted file mode 100644 index 4de912c..0000000 --- a/addons/scatter-4/icons/arrow_log.svg +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - diff --git a/addons/scatter-4/icons/arrow_right.svg b/addons/scatter-4/icons/arrow_right.svg deleted file mode 100644 index 3316c55..0000000 --- a/addons/scatter-4/icons/arrow_right.svg +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - diff --git a/addons/scatter-4/icons/checker.png b/addons/scatter-4/icons/checker.png deleted file mode 100644 index 9abdc75..0000000 Binary files a/addons/scatter-4/icons/checker.png and /dev/null differ diff --git a/addons/scatter-4/icons/clear.svg b/addons/scatter-4/icons/clear.svg deleted file mode 100644 index 43c0031..0000000 --- a/addons/scatter-4/icons/clear.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/addons/scatter-4/icons/close.svg b/addons/scatter-4/icons/close.svg deleted file mode 100644 index 4147c7b..0000000 --- a/addons/scatter-4/icons/close.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/addons/scatter-4/icons/curve_close.svg b/addons/scatter-4/icons/curve_close.svg deleted file mode 100644 index 032f1c6..0000000 --- a/addons/scatter-4/icons/curve_close.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/addons/scatter-4/icons/curve_create.svg b/addons/scatter-4/icons/curve_create.svg deleted file mode 100644 index 1181111..0000000 --- a/addons/scatter-4/icons/curve_create.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/addons/scatter-4/icons/curve_delete.svg b/addons/scatter-4/icons/curve_delete.svg deleted file mode 100644 index 901a08e..0000000 --- a/addons/scatter-4/icons/curve_delete.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/addons/scatter-4/icons/curve_select.svg b/addons/scatter-4/icons/curve_select.svg deleted file mode 100644 index 8f09ca6..0000000 --- a/addons/scatter-4/icons/curve_select.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/addons/scatter-4/icons/dice.svg b/addons/scatter-4/icons/dice.svg deleted file mode 100644 index 214a745..0000000 --- a/addons/scatter-4/icons/dice.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/addons/scatter-4/icons/doc.svg b/addons/scatter-4/icons/doc.svg deleted file mode 100644 index 89c8735..0000000 --- a/addons/scatter-4/icons/doc.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/addons/scatter-4/icons/documentation.svg b/addons/scatter-4/icons/documentation.svg deleted file mode 100644 index 113612b..0000000 --- a/addons/scatter-4/icons/documentation.svg +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - diff --git a/addons/scatter-4/icons/drag_area.svg b/addons/scatter-4/icons/drag_area.svg deleted file mode 100644 index 43efb22..0000000 --- a/addons/scatter-4/icons/drag_area.svg +++ /dev/null @@ -1,110 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/addons/scatter-4/icons/duplicate.svg b/addons/scatter-4/icons/duplicate.svg deleted file mode 100644 index d258f5a..0000000 --- a/addons/scatter-4/icons/duplicate.svg +++ /dev/null @@ -1,44 +0,0 @@ - - diff --git a/addons/scatter-4/icons/exclude_path.svg b/addons/scatter-4/icons/exclude_path.svg deleted file mode 100644 index 05866e3..0000000 --- a/addons/scatter-4/icons/exclude_path.svg +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - - - image/svg+xml - - - - - - - - - - - - diff --git a/addons/scatter-4/icons/global.svg b/addons/scatter-4/icons/global.svg deleted file mode 100644 index d23299e..0000000 --- a/addons/scatter-4/icons/global.svg +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - diff --git a/addons/scatter-4/icons/group.svg b/addons/scatter-4/icons/group.svg deleted file mode 100644 index 5ec0350..0000000 --- a/addons/scatter-4/icons/group.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/addons/scatter-4/icons/individual_instances.svg b/addons/scatter-4/icons/individual_instances.svg deleted file mode 100644 index 2d9f63b..0000000 --- a/addons/scatter-4/icons/individual_instances.svg +++ /dev/null @@ -1,80 +0,0 @@ - - - - - categories - - - - categories - - - - - - - - diff --git a/addons/scatter-4/icons/item.svg b/addons/scatter-4/icons/item.svg deleted file mode 100644 index 8bc141c..0000000 --- a/addons/scatter-4/icons/item.svg +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - - - image/svg+xml - - - - - - - - - - - - - diff --git a/addons/scatter-4/icons/link.svg b/addons/scatter-4/icons/link.svg deleted file mode 100644 index 909c3af..0000000 --- a/addons/scatter-4/icons/link.svg +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - diff --git a/addons/scatter-4/icons/load.svg b/addons/scatter-4/icons/load.svg deleted file mode 100644 index 7ee6ae2..0000000 --- a/addons/scatter-4/icons/load.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/addons/scatter-4/icons/loading/m_loading.tres b/addons/scatter-4/icons/loading/m_loading.tres deleted file mode 100644 index 357aac7..0000000 --- a/addons/scatter-4/icons/loading/m_loading.tres +++ /dev/null @@ -1,20 +0,0 @@ -[gd_resource type="StandardMaterial3D" load_steps=2 format=3] - -[ext_resource type="Texture2D" uid="uid://il8i8280eew6" path="res://addons/proton_scatter/icons/loading/t_loading.tres" id="1_7rsk1"] - -[resource] -render_priority = 120 -transparency = 1 -blend_mode = 1 -depth_draw_mode = 2 -no_depth_test = true -disable_ambient_light = true -albedo_color = Color(1, 0.498039, 0, 1) -albedo_texture = ExtResource("1_7rsk1") -emission_enabled = true -emission = Color(1, 0.411765, 0, 1) -emission_energy_multiplier = 3.5 -disable_receive_shadows = true -billboard_mode = 1 -fixed_size = true -point_size = 24.8 diff --git a/addons/scatter-4/icons/loading/progress1.svg b/addons/scatter-4/icons/loading/progress1.svg deleted file mode 100644 index 07505dd..0000000 --- a/addons/scatter-4/icons/loading/progress1.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/addons/scatter-4/icons/loading/progress2.svg b/addons/scatter-4/icons/loading/progress2.svg deleted file mode 100644 index 0a48f7d..0000000 --- a/addons/scatter-4/icons/loading/progress2.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/addons/scatter-4/icons/loading/progress3.svg b/addons/scatter-4/icons/loading/progress3.svg deleted file mode 100644 index a7f0f9c..0000000 --- a/addons/scatter-4/icons/loading/progress3.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/addons/scatter-4/icons/loading/progress4.svg b/addons/scatter-4/icons/loading/progress4.svg deleted file mode 100644 index 1719209..0000000 --- a/addons/scatter-4/icons/loading/progress4.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/addons/scatter-4/icons/loading/progress5.svg b/addons/scatter-4/icons/loading/progress5.svg deleted file mode 100644 index 7289b7b..0000000 --- a/addons/scatter-4/icons/loading/progress5.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/addons/scatter-4/icons/loading/progress6.svg b/addons/scatter-4/icons/loading/progress6.svg deleted file mode 100644 index 3deba6d..0000000 --- a/addons/scatter-4/icons/loading/progress6.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/addons/scatter-4/icons/loading/progress7.svg b/addons/scatter-4/icons/loading/progress7.svg deleted file mode 100644 index 546155d..0000000 --- a/addons/scatter-4/icons/loading/progress7.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/addons/scatter-4/icons/loading/progress8.svg b/addons/scatter-4/icons/loading/progress8.svg deleted file mode 100644 index b56ffcb..0000000 --- a/addons/scatter-4/icons/loading/progress8.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/addons/scatter-4/icons/loading/t_loading.tres b/addons/scatter-4/icons/loading/t_loading.tres deleted file mode 100644 index 1907238..0000000 --- a/addons/scatter-4/icons/loading/t_loading.tres +++ /dev/null @@ -1,29 +0,0 @@ -[gd_resource type="AnimatedTexture" load_steps=9 format=3] - -[ext_resource type="Texture2D" uid="uid://bkdk5ka8f2eyn" path="res://addons/proton_scatter/icons/loading/progress1.svg" id="1_n051c"] -[ext_resource type="Texture2D" uid="uid://yinrmiasphf0" path="res://addons/proton_scatter/icons/loading/progress2.svg" id="2_huiva"] -[ext_resource type="Texture2D" uid="uid://cddfi3mmjlhfa" path="res://addons/proton_scatter/icons/loading/progress3.svg" id="3_5gmad"] -[ext_resource type="Texture2D" uid="uid://bgrh6kl71mjxp" path="res://addons/proton_scatter/icons/loading/progress4.svg" id="4_ypilv"] -[ext_resource type="Texture2D" uid="uid://cu5lshwm0g08o" path="res://addons/proton_scatter/icons/loading/progress5.svg" id="5_o3w57"] -[ext_resource type="Texture2D" uid="uid://cwfbjg2q2j1b1" path="res://addons/proton_scatter/icons/loading/progress6.svg" id="6_475ws"] -[ext_resource type="Texture2D" uid="uid://d0f2b7boq8n1j" path="res://addons/proton_scatter/icons/loading/progress7.svg" id="7_kuufk"] -[ext_resource type="Texture2D" uid="uid://c0cn8qjmctb2n" path="res://addons/proton_scatter/icons/loading/progress8.svg" id="8_spub1"] - -[resource] -frames = 8 -speed_scale = 8.0 -frame_0/texture = ExtResource("1_n051c") -frame_1/texture = ExtResource("2_huiva") -frame_1/duration = 1.0 -frame_2/texture = ExtResource("3_5gmad") -frame_2/duration = 1.0 -frame_3/texture = ExtResource("4_ypilv") -frame_3/duration = 1.0 -frame_4/texture = ExtResource("5_o3w57") -frame_4/duration = 1.0 -frame_5/texture = ExtResource("6_475ws") -frame_5/duration = 1.0 -frame_6/texture = ExtResource("7_kuufk") -frame_6/duration = 1.0 -frame_7/texture = ExtResource("8_spub1") -frame_7/duration = 1.0 diff --git a/addons/scatter-4/icons/local.svg b/addons/scatter-4/icons/local.svg deleted file mode 100644 index 2d5e554..0000000 --- a/addons/scatter-4/icons/local.svg +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - diff --git a/addons/scatter-4/icons/menu.svg b/addons/scatter-4/icons/menu.svg deleted file mode 100644 index 20c5300..0000000 --- a/addons/scatter-4/icons/menu.svg +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - diff --git a/addons/scatter-4/icons/point.svg b/addons/scatter-4/icons/point.svg deleted file mode 100644 index 1447124..0000000 --- a/addons/scatter-4/icons/point.svg +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - image/svg+xml - - - - - - - - - - diff --git a/addons/scatter-4/icons/rebuild.svg b/addons/scatter-4/icons/rebuild.svg deleted file mode 100644 index d69e6a7..0000000 --- a/addons/scatter-4/icons/rebuild.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/addons/scatter-4/icons/remove.svg b/addons/scatter-4/icons/remove.svg deleted file mode 100644 index eb8e244..0000000 --- a/addons/scatter-4/icons/remove.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/addons/scatter-4/icons/restrict_volume.svg b/addons/scatter-4/icons/restrict_volume.svg deleted file mode 100644 index af4ffbf..0000000 --- a/addons/scatter-4/icons/restrict_volume.svg +++ /dev/null @@ -1,54 +0,0 @@ - - - - - height-arrow - - - - - height-arrow - - - - diff --git a/addons/scatter-4/icons/restrict_volume_lock.svg b/addons/scatter-4/icons/restrict_volume_lock.svg deleted file mode 100644 index 88bdfb7..0000000 --- a/addons/scatter-4/icons/restrict_volume_lock.svg +++ /dev/null @@ -1,59 +0,0 @@ - - - - - height-arrow - - - - - height-arrow - - - - - diff --git a/addons/scatter-4/icons/save.svg b/addons/scatter-4/icons/save.svg deleted file mode 100644 index be5d3ef..0000000 --- a/addons/scatter-4/icons/save.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/addons/scatter-4/icons/scatter.svg b/addons/scatter-4/icons/scatter.svg deleted file mode 100644 index 9092f4a..0000000 --- a/addons/scatter-4/icons/scatter.svg +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - diff --git a/addons/scatter-4/icons/select_all.svg b/addons/scatter-4/icons/select_all.svg deleted file mode 100644 index 4440149..0000000 --- a/addons/scatter-4/icons/select_all.svg +++ /dev/null @@ -1,39 +0,0 @@ - - diff --git a/addons/scatter-4/icons/shape.svg b/addons/scatter-4/icons/shape.svg deleted file mode 100644 index 1335f5a..0000000 --- a/addons/scatter-4/icons/shape.svg +++ /dev/null @@ -1,41 +0,0 @@ - - diff --git a/addons/scatter-4/icons/square_handle.svg b/addons/scatter-4/icons/square_handle.svg deleted file mode 100644 index 4df41e2..0000000 --- a/addons/scatter-4/icons/square_handle.svg +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - - - - - - - image/svg+xml - - - - - - - - - - diff --git a/addons/scatter-4/icons/types/bool.svg b/addons/scatter-4/icons/types/bool.svg deleted file mode 100644 index 674cbc9..0000000 --- a/addons/scatter-4/icons/types/bool.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/addons/scatter-4/icons/types/curve.svg b/addons/scatter-4/icons/types/curve.svg deleted file mode 100644 index 8b330b7..0000000 --- a/addons/scatter-4/icons/types/curve.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/addons/scatter-4/icons/types/float.svg b/addons/scatter-4/icons/types/float.svg deleted file mode 100644 index b941332..0000000 --- a/addons/scatter-4/icons/types/float.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/addons/scatter-4/icons/types/int.svg b/addons/scatter-4/icons/types/int.svg deleted file mode 100644 index b943822..0000000 --- a/addons/scatter-4/icons/types/int.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/addons/scatter-4/icons/types/string.svg b/addons/scatter-4/icons/types/string.svg deleted file mode 100644 index abcb92d..0000000 --- a/addons/scatter-4/icons/types/string.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/addons/scatter-4/icons/types/texture.svg b/addons/scatter-4/icons/types/texture.svg deleted file mode 100644 index bb7831e..0000000 --- a/addons/scatter-4/icons/types/texture.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/addons/scatter-4/icons/types/vector2.svg b/addons/scatter-4/icons/types/vector2.svg deleted file mode 100644 index 2bab922..0000000 --- a/addons/scatter-4/icons/types/vector2.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/addons/scatter-4/icons/types/vector2i.svg b/addons/scatter-4/icons/types/vector2i.svg deleted file mode 100644 index f292354..0000000 --- a/addons/scatter-4/icons/types/vector2i.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/addons/scatter-4/icons/types/vector3.svg b/addons/scatter-4/icons/types/vector3.svg deleted file mode 100644 index 85cac57..0000000 --- a/addons/scatter-4/icons/types/vector3.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/addons/scatter-4/icons/types/vector3i.svg b/addons/scatter-4/icons/types/vector3i.svg deleted file mode 100644 index 26e9c1b..0000000 --- a/addons/scatter-4/icons/types/vector3i.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/addons/scatter-4/icons/warning.svg b/addons/scatter-4/icons/warning.svg deleted file mode 100644 index f40d539..0000000 --- a/addons/scatter-4/icons/warning.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/addons/scatter-4/masks/bars.png b/addons/scatter-4/masks/bars.png deleted file mode 100644 index 99ce23b..0000000 Binary files a/addons/scatter-4/masks/bars.png and /dev/null differ diff --git a/addons/scatter-4/masks/blinds.png b/addons/scatter-4/masks/blinds.png deleted file mode 100644 index a15a038..0000000 Binary files a/addons/scatter-4/masks/blinds.png and /dev/null differ diff --git a/addons/scatter-4/masks/checker.png b/addons/scatter-4/masks/checker.png deleted file mode 100644 index ca58baf..0000000 Binary files a/addons/scatter-4/masks/checker.png and /dev/null differ diff --git a/addons/scatter-4/masks/wave.png b/addons/scatter-4/masks/wave.png deleted file mode 100644 index 3e5f218..0000000 Binary files a/addons/scatter-4/masks/wave.png and /dev/null differ diff --git a/addons/scatter-4/plugin.cfg b/addons/scatter-4/plugin.cfg deleted file mode 100644 index 29069d3..0000000 --- a/addons/scatter-4/plugin.cfg +++ /dev/null @@ -1,7 +0,0 @@ -[plugin] - -name="ProtonScatter" -description="Scatter props or entire scenes across any space in a non destructive way" -author="HungryProton" -version="4.0" -script="plugin.gd" diff --git a/addons/scatter-4/plugin.gd b/addons/scatter-4/plugin.gd deleted file mode 100644 index ea85271..0000000 --- a/addons/scatter-4/plugin.gd +++ /dev/null @@ -1,97 +0,0 @@ -@tool -extends EditorPlugin - - -const ProtonScatter := preload("./src/scatter.gd") -const ProtonScatterShape := preload("./src/scatter_shape.gd") -const ModifierStackPlugin := preload("./src/stack/inspector_plugin/modifier_stack_plugin.gd") -const ScatterGizmoPlugin := preload("./src/scatter_gizmo_plugin.gd") -const ShapeGizmoPlugin := preload("./src/shapes/gizmos_plugin/shape_gizmo_plugin.gd") -const PathPanel := preload("./src/shapes/gizmos_plugin/components/path_panel.tscn") - - -var _modifier_stack_plugin: EditorInspectorPlugin = ModifierStackPlugin.new() -var _scatter_gizmo_plugin: ScatterGizmoPlugin = ScatterGizmoPlugin.new() -var _shape_gizmo_plugin: EditorNode3DGizmoPlugin = ShapeGizmoPlugin.new() -var _path_panel - - -func get_name(): - return "ProtonScatter" - - -func _enter_tree(): - add_inspector_plugin(_modifier_stack_plugin) - - _path_panel = PathPanel.instantiate() - add_control_to_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, _path_panel) - _path_panel.visible = false - - add_node_3d_gizmo_plugin(_scatter_gizmo_plugin) - - add_node_3d_gizmo_plugin(_shape_gizmo_plugin) - _shape_gizmo_plugin.set_undo_redo(get_undo_redo()) - _shape_gizmo_plugin.set_path_gizmo_panel(_path_panel) - _shape_gizmo_plugin.set_editor_plugin(self) - - add_custom_type( - "ProtonScatter", - "Node3D", - preload("./src/scatter.gd"), - preload("./icons/scatter.svg") - ) - add_custom_type( - "ScatterItem", - "Node3D", - preload("./src/scatter_item.gd"), - preload("./icons/item.svg") - ) - add_custom_type( - "ScatterShape", - "Node3D", - preload("./src/scatter_shape.gd"), - preload("./icons/shape.svg") - ) - - var editor_selection = get_editor_interface().get_selection() - editor_selection.selection_changed.connect(_on_selection_changed) - - scene_changed.connect(_on_scene_changed) - - -func _exit_tree(): - remove_custom_type("ProtonScatter") - remove_custom_type("ScatterItem") - remove_custom_type("ScatterShape") - remove_inspector_plugin(_modifier_stack_plugin) - remove_node_3d_gizmo_plugin(_shape_gizmo_plugin) - remove_node_3d_gizmo_plugin(_scatter_gizmo_plugin) - if _path_panel: - remove_control_from_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, _path_panel) - _path_panel.queue_free() - _path_panel = null - - -func _handles(node) -> bool: - return node is ProtonScatterShape - - -func _forward_3d_gui_input(viewport_camera: Camera3D, event: InputEvent) -> int: - return _shape_gizmo_plugin.forward_3d_gui_input(viewport_camera, event) - - -func _on_selection_changed() -> void: - var selected = get_editor_interface().get_selection().get_selected_nodes() - _path_panel.selection_changed(selected) - - if selected.is_empty(): - return - - var selected_node = selected[0] - if selected_node is ProtonScatter: - selected_node.undo_redo = get_undo_redo() - selected_node.editor_plugin = self - - -func _on_scene_changed(_scene_root) -> void: - pass diff --git a/addons/scatter-4/presets/default.tscn b/addons/scatter-4/presets/default.tscn deleted file mode 100644 index 240adc5..0000000 --- a/addons/scatter-4/presets/default.tscn +++ /dev/null @@ -1,69 +0,0 @@ -[gd_scene load_steps=14 format=3] - -[ext_resource type="Script" path="res://addons/proton_scatter/src/scatter.gd" id="1_e0kty"] -[ext_resource type="Script" path="res://addons/proton_scatter/src/stack/modifier_stack.gd" id="2_lt5xy"] -[ext_resource type="Script" path="res://addons/proton_scatter/src/modifiers/create_inside_grid.gd" id="3_nry4c"] -[ext_resource type="Script" path="res://addons/proton_scatter/src/modifiers/randomize_transforms.gd" id="4_5a045"] -[ext_resource type="Script" path="res://addons/proton_scatter/src/modifiers/project_on_geometry.gd" id="5_gkw57"] -[ext_resource type="Script" path="res://addons/proton_scatter/src/scatter_item.gd" id="6_3iwkw"] -[ext_resource type="Script" path="res://addons/proton_scatter/src/scatter_shape.gd" id="7_jofmq"] -[ext_resource type="Script" path="res://addons/proton_scatter/src/shapes/sphere_shape.gd" id="8_gnbkw"] - -[sub_resource type="Resource" id="Resource_741ly"] -script = ExtResource("3_nry4c") -spacing = Vector3(0.2, 1, 0.2) -enabled = true -override_global_seed = false -custom_seed = 0 -restrict_height = true -use_local_space = false - -[sub_resource type="Resource" id="Resource_n0177"] -script = ExtResource("4_5a045") -position = Vector3(0.15, 0.15, 0.15) -rotation = Vector3(20, 360, 20) -scale = Vector3(2, 2, 2) -enabled = true -override_global_seed = false -custom_seed = 0 -restrict_height = false -use_local_space = true - -[sub_resource type="Resource" id="Resource_hqvoo"] -script = ExtResource("5_gkw57") -ray_direction = Vector3(0, -1, 0) -ray_length = 5.0 -ray_offset = 5.0 -remove_points_on_miss = true -align_with_collision_normal = false -max_slope = 90.0 -collision_mask = 1 -enabled = true -override_global_seed = false -custom_seed = 0 -restrict_height = false -use_local_space = false - -[sub_resource type="Resource" id="Resource_asuhn"] -script = ExtResource("2_lt5xy") -stack = [SubResource("Resource_741ly"), SubResource("Resource_n0177"), SubResource("Resource_hqvoo")] - -[sub_resource type="Resource" id="Resource_g8bsm"] -script = ExtResource("8_gnbkw") -radius = 2.0 - -[node name="ProtonScatter3" type="Node3D"] -script = ExtResource("1_e0kty") -scatter_parent = NodePath("") -modifier_stack = SubResource("Resource_asuhn") - -[node name="Grass" type="Node3D" parent="."] -script = ExtResource("6_3iwkw") -path = "res://addons/proton_scatter/demos/assets/grass_2.tscn" - -[node name="ScatterShape2" type="Node3D" parent="."] -transform = Transform3D(1, 0, -2.98023e-08, 0, 1, 0, 2.98023e-08, 0, 1, 0, 0, 0) -script = ExtResource("7_jofmq") -shape = SubResource("Resource_g8bsm") - -[node name="ScatterOutput" type="Marker3D" parent="."] diff --git a/addons/scatter-4/src/common/bounds.gd b/addons/scatter-4/src/common/bounds.gd deleted file mode 100644 index 52d0ed4..0000000 --- a/addons/scatter-4/src/common/bounds.gd +++ /dev/null @@ -1,51 +0,0 @@ -@tool -extends Resource - -# Essentially a Rect3 -# Used by the Domain class - - -var size: Vector3 -var center: Vector3 -var min: Vector3 -var max: Vector3 - -var _points := 0 - - -func clear() -> void: - size = Vector3.ZERO - center = Vector3.ZERO - min = Vector3.ZERO - max = Vector3.ZERO - _points = 0 - - -func feed(point: Vector3) -> void: - if _points == 0: - min = point - max = point - - min = _minv(min, point) - max = _maxv(max, point) - _points += 1 - - -# Call this after you've called feed() with all the points in your data set -func compute_bounds() -> void: - if min == null or max == null: - return - - size = max - min - center = min + (size / 2.0) - - -# Returns a vector with the smallest values in each of the 2 input vectors -func _minv(v1: Vector3, v2: Vector3) -> Vector3: - return Vector3(min(v1.x, v2.x), min(v1.y, v2.y), min(v1.z, v2.z)) - - -# Returns a vector with the highest values in each of the 2 input vectors -func _maxv(v1: Vector3, v2: Vector3) -> Vector3: - return Vector3(max(v1.x, v2.x), max(v1.y, v2.y), max(v1.z, v2.z)) - diff --git a/addons/scatter-4/src/common/domain.gd b/addons/scatter-4/src/common/domain.gd deleted file mode 100644 index dcdd45d..0000000 --- a/addons/scatter-4/src/common/domain.gd +++ /dev/null @@ -1,295 +0,0 @@ -@tool -extends RefCounted - -# A domain is the complete area where transforms can (and can't) be placed. -# A Scatter node has one single domain, a domain has one or more shape nodes. -# -# It's the combination of every shape defined under a Scatter node, grouped in -# a single class that exposes utility functions (check if a point is inside, or -# along the surface etc). -# -# An instance of this class is passed to the modifiers during a rebuild. - - -const ProtonScatter := preload("../scatter.gd") -const ProtonScatterShape := preload("../scatter_shape.gd") -const BaseShape := preload("../shapes/base_shape.gd") -const Bounds := preload("../common/bounds.gd") - - -class DomainShapeInfo: - var transform: Transform3D - var shape: BaseShape - - func is_point_inside(point: Vector3) -> bool: - return shape.is_point_inside(point, transform) - - func get_corners_global() -> Array: - return shape.get_corners_global(transform) - -# A polygon made of one outer boundary and one or multiple holes (inner polygons) -class ComplexPolygon: - var inner: Array[PackedVector2Array] = [] - var outer: PackedVector2Array - - func add(polygon: PackedVector2Array) -> void: - if polygon.is_empty(): return - if Geometry2D.is_polygon_clockwise(polygon): - inner.push_back(polygon) - else: - if not outer.is_empty(): - print_debug("ProtonScatter error: Replacing polygon's existing outer boundary. This should not happen, please report.") - outer = polygon - - func add_array(array: Array, reverse := false) -> void: - for p in array: - if reverse: - p.reverse() - add(p) - - func get_all() -> Array[PackedVector2Array]: - var res = inner.duplicate() - res.push_back(outer) - return res - - func _to_string() -> String: - var res = "o: " + var_to_str(outer.size()) + ", i: [" - for i in inner: - res += var_to_str(i.size()) + ", " - res += "]" - return res - - -var root: ProtonScatter -var positive_shapes: Array[DomainShapeInfo] -var negative_shapes: Array[DomainShapeInfo] -var bounds: Bounds = Bounds.new() -var bounds_local: Bounds = Bounds.new() -var edges: Array[Curve3D] = [] - - -func is_empty() -> bool: - return positive_shapes.is_empty() - - -# If a point is in an exclusion shape, returns false -# If a point is in an inclusion shape (but not in an exclusion one), returns true -# If a point is in neither, returns false -func is_point_inside(point: Vector3) -> bool: - for s in negative_shapes: - if s.is_point_inside(point): - return false - - for s in positive_shapes: - if s.is_point_inside(point): - return true - - return false - - -# If a point is inside an exclusion shape, returns true -# Returns false in every other case -func is_point_excluded(point: Vector3) -> bool: - for s in negative_shapes: - if s.is_point_inside(point): - return true - - return false - - -# Recursively find all ScatterShape nodes under the provided root. In case of -# nested Scatter nodes, shapes under these other Scatter nodes will be ignored -func discover_shapes(root_node: Node3D) -> void: - root = root_node - positive_shapes.clear() - negative_shapes.clear() - for c in root.get_children(): - _discover_shapes_recursive(c) - compute_bounds() - compute_edges() - - -func compute_bounds() -> void: - bounds.clear() - bounds_local.clear() - - var gt: Transform3D = root.get_global_transform().affine_inverse() - - for info in positive_shapes: - for point in info.get_corners_global(): - bounds.feed(point) - bounds_local.feed(gt * point) - - bounds.compute_bounds() - bounds_local.compute_bounds() - - -func compute_edges() -> void: - edges.clear() - var source_polygons: Array[ComplexPolygon] = [] - var root_gt: Transform3D = root.get_global_transform() - - ## Retrieve all polygons - for info in positive_shapes: - # Store all closed polygons in a specific array - var polygon := ComplexPolygon.new() - polygon.add_array(info.shape.get_closed_edges(root_gt, info.transform)) - - # Polygons with holes must be merged together first - if not polygon.inner.is_empty(): - source_polygons.push_back(polygon) - else: - source_polygons.push_front(polygon) - - # Store open edges directly since they are already Curve3D and we - # don't apply boolean operations to them. - var open_edges = info.shape.get_open_edges(root_gt, info.transform) - edges.append_array(open_edges) - - if source_polygons.is_empty(): - return - - ## Merge all closed polygons together - var merged_polygons: Array[ComplexPolygon] = [] - - while not source_polygons.is_empty(): - var merged := false - var p1: ComplexPolygon = source_polygons.pop_back() - var max_steps: int = source_polygons.size() - var i = 0 - - # Test p1 against every other polygon from source_polygon until a - # successful merge. If no merge happened, put it in the final array. - while i < max_steps and not merged: - i += 1 - - # Get the next polygon in the list - var p2: ComplexPolygon = source_polygons.pop_back() - - # If the outer boundary of any of the two polygons is completely - # enclosed in one of the other polygon's hole, we don't try to - # merge them and go the next iteration. - var full_overlap = false - for ip1 in p1.inner: - var res = Geometry2D.clip_polygons(p2.outer, ip1) - if res.is_empty(): - full_overlap = true - break - - for ip2 in p2.inner: - var res = Geometry2D.clip_polygons(p1.outer, ip2) - if res.is_empty(): - full_overlap = true - break - - if full_overlap: - source_polygons.push_front(p2) - continue - - # Try to merge the two polygons p1 and p2 - var res = Geometry2D.merge_polygons(p1.outer, p2.outer) - var outer_polygons := 0 - for p in res: - if not Geometry2D.is_polygon_clockwise(p): - outer_polygons += 1 - - # If the merge generated a new polygon, process the holes data from - # the two original polygons and store in the new_polygon - # P1 and P2 are then discarded and replaced by the new polygon. - if outer_polygons == 1: - var new_polygon = ComplexPolygon.new() - new_polygon.add_array(res) - - # Process the holes data from p1 and p2 - for ip1 in p1.inner: - for ip2 in p2.inner: - new_polygon.add_array(Geometry2D.intersect_polygons(ip1, ip2), true) - new_polygon.add_array(Geometry2D.clip_polygons(ip2, p1.outer), true) - - new_polygon.add_array(Geometry2D.clip_polygons(ip1, p2.outer), true) - - source_polygons.push_back(new_polygon) - merged = true - - # If the polygons don't overlap, return it to the pool to be tested - # against other polygons - else: - source_polygons.push_front(p2) - - # If p1 is not overlapping any other polygon, add it to the final list - if not merged: - merged_polygons.push_back(p1) - - var gt_inverse := root_gt.affine_inverse() - - ## For each polygons from the previous step, create a corresponding Curve3D - for cp in merged_polygons: - for polygon in cp.get_all(): - if polygon.size() < 2: # Ignore polygons too small to form a loop - continue - - var curve := Curve3D.new() - for point in polygon: - var p = Vector3(point.x, 0.0, point.y) - curve.add_point(root_gt * p) - - curve.add_point(curve.get_point_position(0)) # Close the loop - edges.push_back(curve) - - -func get_root() -> ProtonScatter: - return root - - -func get_global_transform() -> Transform3D: - return root.get_global_transform() - - -func get_local_transform() -> Transform3D: - return root.get_transform() - - -func get_edges() -> Array[Curve3D]: - if edges.is_empty(): - compute_edges() - return edges - - -func get_copy(): - var copy = get_script().new() - - copy.root = root - copy.bounds = bounds - copy.bounds_local = bounds_local - - for s in positive_shapes: - var s_copy = DomainShapeInfo.new() - s_copy.transform = s.transform - s_copy.shape = s.shape.get_copy() - copy.positive_shapes.push_back(s_copy) - - for s in negative_shapes: - var s_copy = DomainShapeInfo.new() - s_copy.transform = s.transform - s_copy.shape = s.shape.get_copy() - copy.negative_shapes.push_back(s_copy) - - return copy - - -func _discover_shapes_recursive(node: Node) -> void: - if node is ProtonScatter: # Ignore shapes under nested Scatter nodes - return - - if node is ProtonScatterShape and node.shape != null: - var info := DomainShapeInfo.new() - info.transform = node.get_global_transform() - info.shape = node.shape - - if node.negative: - negative_shapes.push_back(info) - else: - positive_shapes.push_back(info) - - for c in node.get_children(): - _discover_shapes_recursive(c) diff --git a/addons/scatter-4/src/common/event_helper.gd b/addons/scatter-4/src/common/event_helper.gd deleted file mode 100644 index 912d18c..0000000 --- a/addons/scatter-4/src/common/event_helper.gd +++ /dev/null @@ -1,72 +0,0 @@ -extends RefCounted - -# Utility class that mimics the Input class behavior -# -# This only useful when using actions from the Input class isn't possible, -# like in _unhandled_input or forward_3d_gui_input for example, where you don't -# have a native way to detect if a key was just pressed or released. -# -# How to use: -# Call the feed() method first with the latest event you received, then call -# either of the is_key_* function -# -# If you don't call feed() on the same frame before calling any of these two, -# the behavior is undefined. - - -var _actions := {} - - -func feed(event: InputEvent) -> void: - var key - if event is InputEventMouseButton: - key = event.button_index - elif event is InputEventKey: - key = event.keycode - else: - _cleanup_states() - return - - if not key in _actions: - _actions[key] = { - pressed = event.pressed, - just_released = not event.pressed, - just_pressed = event.pressed, - } - return - - var pressed = _actions[key].pressed - - if pressed and not event.pressed: - _actions[key].just_released = true - _actions[key].just_pressed = false - - if not pressed and event.pressed: - _actions[key].just_pressed = true - _actions[key].just_released = false - - if pressed and event.pressed: - _actions[key].just_pressed = false - _actions[key].just_released = false - - _actions[key].pressed = event.pressed - - -func _cleanup_states() -> void: - for key in _actions: - _actions[key].just_released = false - _actions[key].just_pressed = false - - -func is_key_just_pressed(key) -> bool: - if key in _actions: - return _actions[key].just_pressed - - return false - - -func is_key_just_released(key) -> bool: - if key in _actions: - return _actions[key].just_released - - return false diff --git a/addons/scatter-4/src/common/physics_helper.gd b/addons/scatter-4/src/common/physics_helper.gd deleted file mode 100644 index 8ec4a0c..0000000 --- a/addons/scatter-4/src/common/physics_helper.gd +++ /dev/null @@ -1,58 +0,0 @@ -@tool -extends Node - -# Runs jobs during the physics step. -# Only supports raycast for now, but can easilly be adapted to handle -# the other types of queries. - - -signal job_canceled -signal job_completed - -const MAX_QUERIES_PER_FRAME = 400 # TODO: Expose in user settings - - -var _queries: Array -var _results: Array[Dictionary] -var _job_in_progress := false -var _cancel_current := false - - -func execute(queries: Array) -> Array[Dictionary]: - if _job_in_progress: - _cancel_current = true - await job_canceled - - _results.clear() - _queries = queries - _queries.reverse() - _job_in_progress = true - - await job_completed - - _job_in_progress = false - return _results.duplicate() - - -func _physics_process(_delta: float) -> void: - if _cancel_current: - _cancel_current = false - _job_in_progress = false - _results.clear() - job_canceled.emit() - return - - if not _job_in_progress: - return - - var space_state: PhysicsDirectSpaceState3D = get_tree().get_root().get_world_3d().get_direct_space_state() - var steps = min(MAX_QUERIES_PER_FRAME, _queries.size()) - - for i in steps: - var q = _queries.pop_back() - var hit := space_state.intersect_ray(q) # TODO: Support other operations - _results.push_back(hit) - - if _queries.is_empty(): - _job_in_progress = false - job_completed.emit() diff --git a/addons/scatter-4/src/common/scatter_util.gd b/addons/scatter-4/src/common/scatter_util.gd deleted file mode 100644 index 22d897c..0000000 --- a/addons/scatter-4/src/common/scatter_util.gd +++ /dev/null @@ -1,209 +0,0 @@ -extends Node - -# To prevent the other core scripts from becoming too large, some of their -# utility functions are written here (only the functions that don't disturb -# reading the core code, mostly data validation and other verbose checks). - - -const ProtonScatter := preload("../scatter.gd") -const ProtonScatterItem := preload("../scatter_item.gd") -const ModifierStack := preload("../stack/modifier_stack.gd") - -### SCATTER UTILITY FUNCTIONS ### - - -# Make sure the output node exists. This is the parent node to -# everything generated by the scatter mesh -static func ensure_output_root_exists(s: ProtonScatter) -> void: - # Check if the node exists in the tree - if not s.output_root: - s.output_root = s.get_node_or_null("ScatterOutput") - - # If the node is valid, end here - if is_instance_valid(s.output_root) and s.has_node(NodePath(s.output_root.name)): - enforce_output_root_owner(s) - return - - # Some conditions are not met, cleanup and recreate the root - if s.output_root: - if s.has_node(NodePath(s.output_root.name)): - s.remove_node(s.output_root.name) - s.output_root.queue_free() - s.output_root = null - - s.output_root = Marker3D.new() - s.output_root.name = "ScatterOutput" - s.add_child(s.output_root, true) - enforce_output_root_owner(s) - - -static func enforce_output_root_owner(s: ProtonScatter) -> void: - if is_instance_valid(s.output_root) and s.is_inside_tree(): - if s.show_output_in_tree: - set_owner_recursive(s.output_root, s.get_tree().get_edited_scene_root()) - else: - set_owner_recursive(s.output_root, null) - - # TMP: Workaround to force the scene tree to update and take in account - # the owner changes. Otherwise it doesn't show until much later. - s.output_root.update_configuration_warnings() - - -# Item root is a Node3D placed as a child of the ScatterOutput node. -# Each ScatterItem has a corresponding output node, serving as a parent for -# the Multimeshes or duplicates generated by the Scatter node. -static func get_or_create_item_root(item: ProtonScatterItem) -> Node3D: - var s: ProtonScatter = item.get_parent() - ensure_output_root_exists(s) - var item_root: Node3D = s.output_root.get_node_or_null(NodePath(item.name)) - - if not item_root: - item_root = Node3D.new() - s.output_root.add_child(item_root) - item_root.name = item.name - if Engine.is_editor_hint(): - item_root.owner = item_root.get_tree().get_edited_scene_root() - - return item_root - - -static func get_or_create_multimesh(item: ProtonScatterItem, count: int) -> MultiMeshInstance3D: - var item_root := get_or_create_item_root(item) - var mmi: MultiMeshInstance3D = item_root.get_node_or_null("MultiMeshInstance3D") - - if not mmi: - mmi = MultiMeshInstance3D.new() - item_root.add_child(mmi) - mmi.set_owner(item_root.owner) - mmi.set_name("MultiMeshInstance3D") - - if not mmi.multimesh: - mmi.multimesh = MultiMesh.new() - - mmi.position = Vector3.ZERO - # item.update_shadows() - - var node = item.get_item() - var mesh_instance: MeshInstance3D = get_merged_meshes_from(node) - if not mesh_instance: - return - - mmi.multimesh.instance_count = 0 # Set this to zero or you can't change the other values - mmi.multimesh.mesh = mesh_instance.mesh - mmi.multimesh.transform_format = 1 - mmi.multimesh.instance_count = count - - mesh_instance.queue_free() - - return mmi - - -# Called from child nodes who affect the rebuild process (like ScatterShape) -# Usually, it would be the Scatter node responsibility to listen to changes from -# the children nodes, but keeping track of the children is annoying (they can -# be moved around from a Scatter node to another, or put under a wrong node, or -# other edge cases). -# So instead, when a child changed, it notifies the parent Scatter node through -# this method. -static func request_parent_to_rebuild(node: Node, deferred := false) -> void: - var parent = node.get_parent() - if not parent or not parent.is_inside_tree(): - return - - if parent and parent is ProtonScatter: - if deferred: - parent.rebuild.call_deferred(true) - else: - parent.rebuild(true) - - -### MESH UTILITY ### - -# Recursively search for all MeshInstances3D in the node's children and -# returns them all in an array. If node is a MeshInstance, it will also be -# added to the array -static func get_all_mesh_instances_from(node: Node3D) -> Array[MeshInstance3D]: - var res: Array[MeshInstance3D] = [] - - if node is MeshInstance3D: - res.push_back(node) - - for c in node.get_children(): - res.append_array(get_all_mesh_instances_from(c)) - - return res - - -# Find all the meshes below node and create a new single mesh with multiple -# surfaces from all of them. -static func get_merged_meshes_from(node: Node) -> MeshInstance3D: - if not node: - return null - - # Reset node transform for this step, overwise they'll stack - var transform_backup: Transform3D - if node.is_inside_tree(): - transform_backup = node.get_global_transform() - node.global_transform = Transform3D() - else: - transform_backup = node.transform - node.transform = Transform3D() - - var instances: Array[MeshInstance3D] = get_all_mesh_instances_from(node) - if instances.is_empty(): - return null - - var total_surfaces = 0 - var array_mesh = ArrayMesh.new() - - for i in instances.size(): - var mi: MeshInstance3D = instances[i] - var mesh: Mesh = mi.mesh - var surface_count = mesh.get_surface_count() - var material_override = mi.get_material_override() - var inverse_transform: Transform3D - if mi.is_inside_tree(): - inverse_transform = mi.global_transform.affine_inverse() - else: - inverse_transform = mi.transform.affine_inverse() - - for j in surface_count: - var arrays = mesh.surface_get_arrays(j) - var length = arrays[ArrayMesh.ARRAY_VERTEX].size() - - for k in length: - var pos: Vector3 = arrays[ArrayMesh.ARRAY_VERTEX][k] - pos = pos * inverse_transform - arrays[ArrayMesh.ARRAY_VERTEX][k] = pos - - array_mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays) - - # Retrieve the material on the MeshInstance first, if none is defined, - # use the one from the mesh resource. - var material: Material - if material_override: - material = material_override - else: - material = mi.get_surface_override_material(j) - if not material: - material = mesh.surface_get_material(j) - array_mesh.surface_set_material(total_surfaces, material) - - total_surfaces += 1 - - # Restore node initial transform - if node.is_inside_tree(): - node.global_transform = transform_backup - else: - node.transform = transform_backup - - # Return merged mesh - var res := MeshInstance3D.new() - res.mesh = array_mesh - return res - - -static func set_owner_recursive(node: Node, new_owner) -> void: - node.set_owner(new_owner) - for c in node.get_children(): - set_owner_recursive(c, new_owner) diff --git a/addons/scatter-4/src/common/transform_list.gd b/addons/scatter-4/src/common/transform_list.gd deleted file mode 100644 index 1d4b23a..0000000 --- a/addons/scatter-4/src/common/transform_list.gd +++ /dev/null @@ -1,66 +0,0 @@ -@tool -extends RefCounted - - -var list: Array[Transform3D] = [] -var max_count := -1 - - -func add(count: int) -> void: - for i in count: - var t := Transform3D() - list.push_back(t) - - -func append(array: Array[Transform3D]) -> void: - list.append_array(array) - - -func remove(count: int) -> void: - count = int(max(count, 0)) # Prevent using a negative number - var new_size = max(list.size() - count, 0) - list.resize(new_size) - - -func resize(count: int) -> void: - if max_count >= 0: - count = int(min(count, max_count)) - - var size = list.size() - if count > size: - add(count - size) - else: - remove(size - count) - - -# TODO: Faster algorithm probably exists for this, research an alternatives -# if this ever becomes a performance bottleneck. -func shuffle(random_seed := 0) -> void: - var n = list.size() - if n < 2: - return - - var rng = RandomNumberGenerator.new() - rng.set_seed(random_seed) - - var i = n - 1 - var j - var tmp - while i >= 1: - j = rng.randi() % (i + 1) - tmp = list[j] - list[j] = list[i] - list[i] = tmp - i -= 1 - - -func clear() -> void: - list = [] - - -func is_empty() -> bool: - return list.is_empty() - - -func size() -> int: - return list.size() diff --git a/addons/scatter-4/src/common/util.gd b/addons/scatter-4/src/common/util.gd deleted file mode 100644 index 50242b0..0000000 --- a/addons/scatter-4/src/common/util.gd +++ /dev/null @@ -1,29 +0,0 @@ -@tool -extends RefCounted - - -static func get_position_and_normal_at(curve: Curve3D, offset: float) -> Array: - if not curve: - return [] - - var pos: Vector3 = curve.sample_baked(offset) - var normal := Vector3.ZERO - - var pos1 - if offset + curve.get_bake_interval() < curve.get_baked_length(): - pos1 = curve.sample_baked(offset + curve.get_bake_interval()) - normal = (pos1 - pos) - else: - pos1 = curve.sample_baked(offset - curve.get_bake_interval()) - normal = (pos - pos1) - - return [pos, normal] - - -static func remove_line_breaks(text: String) -> String: - # Remove tabs - text = text.replace("\t", "") - # Remove line breaks - text = text.replace("\n", " ") - # Remove occasional double space caused by the line above - return text.replace(" ", " ") diff --git a/addons/scatter-4/src/documentation/documentation.gd b/addons/scatter-4/src/documentation/documentation.gd deleted file mode 100644 index b6091f8..0000000 --- a/addons/scatter-4/src/documentation/documentation.gd +++ /dev/null @@ -1,277 +0,0 @@ -@tool -extends PopupPanel - - -# Formats and displays the DocumentationData provided by other parts of the addon -# TODO: Adjust title font size based on the editor font size / scaling - - -const DocumentationInfo = preload("./documentation_info.gd") -const SpecialPages = preload("./pages/special_pages.gd") - -var _pages := {} -var _items := {} -var _categories_roots := {} - -var _modifiers_root: TreeItem - -var _edited_text: String -var _accent_color := Color.CORNFLOWER_BLUE -var _editor_scale := 1.0 -var _header_size := 20 -var _sub_header_size := 16 - -var _populated := false - - -@onready var tree: Tree = $HSplitContainer/Tree -@onready var label: RichTextLabel = $HSplitContainer/RichTextLabel - - -func _ready() -> void: - tree.create_item() # Create tree root - tree.hide_root = true - tree.item_selected.connect(_on_item_selected) - - add_page(SpecialPages.get_scatter_documentation(), tree.create_item()) - add_page(SpecialPages.get_item_documentation(), tree.create_item()) - add_page(SpecialPages.get_shape_documentation(), tree.create_item()) - - _modifiers_root = tree.create_item() - add_page(SpecialPages.get_modifiers_documentation(), _modifiers_root) - - _populate() - - -# Fed from the StackPanel scene, before the ready function -func set_editor_plugin(editor_plugin: EditorPlugin) -> void: - if not editor_plugin: - return - - var editor_interface := editor_plugin.get_editor_interface() - var editor_settings := editor_interface.get_editor_settings() - - _accent_color = editor_settings.get("interface/theme/accent_color") - _editor_scale = editor_interface.get_editor_scale() - - -func show_page(page_name: String) -> void: - if not page_name in _items: - return - - var item: TreeItem = _items[page_name] - item.select(0) - popup_centered(Vector2i(900, 600)) - - -# Generate a formatted string from the DocumentationInfo input. -# This string will be stored and later displayed in the RichTextLabel so we -# we don't have to regenerate it everytime we look at another page. -func add_page(info: DocumentationInfo, item: TreeItem = null) -> void: - if not item: - var root: TreeItem = _get_or_create_tree_root(info.get_category()) - item = tree.create_item(root) - - item.set_text(0, info.get_title()) - - _begin_formatting() - - # Page title - _format_title(info.get_title()) - - # Paragraphs - for p in info.get_paragraphs(): - _format_paragraph(p) - - # Parameters - if not info.get_parameters().is_empty(): - _format_subtitle("Parameters") - - for p in info.get_parameters(): - _format_parameter(p) - - # Warnings - if not info.get_warnings().is_empty(): - _format_subtitle("Warnings") - - for w in info.get_warnings(): - _format_warning(w) - - _pages[item] = _get_formatted_text() - _items[info.get_title()] = item - - -func _populate(): - if _populated: # Already generated the documentation pages - return - - var path = _get_root_folder() + "/src/modifiers/" - var result := {} - _discover_modifiers_recursive(path, result) - - var names := result.keys() - names.sort() - - for n in names: - var info = result[n] - add_page(info) - - _populated = true - - -func _discover_modifiers_recursive(path, result) -> void: - var dir = DirAccess.open(path) - dir.list_dir_begin() - var path_root = dir.get_current_dir() + "/" - - while true: - var file = dir.get_next() - if file == "": - break - if file == "base_modifier.gd": - continue - if dir.current_is_dir(): - _discover_modifiers_recursive(path_root + file, result) - continue - if not file.ends_with(".gd") and not file.ends_with(".gdc"): - continue - - var full_path = path_root + file - var script = load(full_path) - if not script or not script.can_instantiate(): - print("Error: Failed to load script ", file) - continue - - var modifier = script.new() - - var info: DocumentationInfo = modifier.documentation - info.set_title(modifier.display_name) - info.set_category(modifier.category) - if modifier.use_edge_data: - info.add_warning( - "This modifier uses edge data (represented by the blue lines - on the Scatter node). These edges are usually locked to the - local XZ plane, (except for the Path shape when they are - NOT closed). If you can't see these lines, make sure to have at - least one Shape crossing the ProtonScatter local XZ plane.", - 1) - - result[modifier.display_name] = info - - dir.list_dir_end() - - -func _get_root_folder() -> String: - var script: Script = get_script() - var path: String = script.get_path().get_base_dir() - var folders = path.right(-6) # Remove the res:// - var tokens = folders.split('/') - return "res://" + tokens[0] + "/" + tokens[1] - - -func _get_or_create_tree_root(root_name: String) -> TreeItem: - if root_name in _categories_roots: - return _categories_roots[root_name] - - var root = tree.create_item(_modifiers_root) - root.set_text(0, root_name) - root.set_selectable(0, false) - _categories_roots[root_name] = root - return root - - -func _begin_formatting() -> void: - _edited_text = "" - - -func _get_formatted_text() -> String: - return _edited_text - - -func _format_title(text: String) -> void: - _edited_text += "[font_size=" + var_to_str(_header_size * _editor_scale) + "]" - _edited_text += "[color=" + _accent_color.to_html() + "]" - _edited_text += "[center][b]" - _edited_text += text - _edited_text += "[/b][/center]" - _edited_text += "[/color]" - _edited_text += "[/font_size]" - _format_line_break(2) - - -func _format_subtitle(text: String) -> void: - _edited_text += "[font_size=" + var_to_str(_header_size * _editor_scale) + "]" - _edited_text += "[color=" + _accent_color.to_html() + "]" - _edited_text += "[b]" + text + "[/b]" - _edited_text += "[/color]" - _edited_text += "[/font_size]" - _format_line_break(2) - - -func _format_line_break(count := 1) -> void: - for i in count: - _edited_text += "\n" - - -func _format_paragraph(text: String) -> void: - _edited_text += "[p]" + text + "[/p]" - _format_line_break(2) - - -func _format_parameter(p) -> void: - var root_folder = _get_root_folder() - - _edited_text += "[indent]" - - if not p.type.is_empty(): - var file_name = p.type.to_lower() + ".svg" - _edited_text += "[img]" + root_folder + "/icons/types/" + file_name + "[/img] " - - _edited_text += "[b]" + p.name + "[/b] " - - match p.cost: - 1: - _edited_text += "[img]" + root_folder + "/icons/arrow_log.svg[/img]" - 2: - _edited_text += "[img]" + root_folder + "/icons/arrow_linear.svg[/img]" - 3: - _edited_text += "[img]" + root_folder + "/icons/arrow_exp.svg[/img]" - - _format_line_break(2) - _edited_text += "[indent]" + p.description + "[/indent]" - _format_line_break(2) - - for warning in p.warnings: - if not warning.text.is_empty(): - _format_warning(warning) - - _edited_text += "[/indent]" - - -func _format_warning(w, indent := true) -> void: - if indent: - _edited_text += "[indent]" - - var color := "Darkgray" - match w.importance: - 1: - color = "yellow" - 2: - color = "red" - - _edited_text += "[color=" + color + "][i]" + w.text + "[/i][/color]\n" - - if indent: - _edited_text += "[/indent]" - - _format_line_break(1) - - -func _on_item_selected() -> void: - var selected: TreeItem = tree.get_selected() - - if _pages.has(selected): - var text: String = _pages[selected] - label.set_text(text) - else: - label.set_text("[center] Under construction [/center]") diff --git a/addons/scatter-4/src/documentation/documentation.tscn b/addons/scatter-4/src/documentation/documentation.tscn deleted file mode 100644 index 0bcaa8f..0000000 --- a/addons/scatter-4/src/documentation/documentation.tscn +++ /dev/null @@ -1,29 +0,0 @@ -[gd_scene load_steps=3 format=3 uid="uid://cfg8iqtuion8b"] - -[ext_resource type="Script" path="res://addons/proton_scatter/src/documentation/documentation.gd" id="1_5c4lw"] -[ext_resource type="PackedScene" uid="uid://cojoo2c73fpsb" path="res://addons/proton_scatter/src/documentation/panel.tscn" id="2_vpfxu"] - -[node name="Documentation" type="PopupPanel"] -title = "ProtonScatter documentation" -exclusive = true -unresizable = false -borderless = false -script = ExtResource("1_5c4lw") - -[node name="HSplitContainer" parent="." instance=ExtResource("2_vpfxu")] -offset_left = 4.0 -offset_top = 4.0 -offset_right = -1824.0 -offset_bottom = -984.0 - -[node name="Tree" parent="HSplitContainer" index="0"] -offset_right = 80.0 -offset_bottom = 92.0 -hide_root = true - -[node name="RichTextLabel" parent="HSplitContainer" index="1"] -offset_left = 92.0 -offset_right = 92.0 -offset_bottom = 92.0 - -[editable path="HSplitContainer"] diff --git a/addons/scatter-4/src/documentation/documentation_info.gd b/addons/scatter-4/src/documentation/documentation_info.gd deleted file mode 100644 index b6eac91..0000000 --- a/addons/scatter-4/src/documentation/documentation_info.gd +++ /dev/null @@ -1,113 +0,0 @@ -@tool -extends RefCounted - - -# Stores raw documentation data. - -# The data is provided by any class that needs an entry in the documentation -# panel. This was initially designed for all the modifiers, but might be expanded -# to other parts of the addon as well. - -# Formatting is handled by the main Documentation class. - -const Util := preload("../common/util.gd") - - -class Warning: - var text: String - var importance: int - -class Parameter: - var name: String - var cost: int - var type: String - var description: String - var warnings: Array[Warning] = [] - - func set_name(text: String) -> Parameter: - name = Util.remove_line_breaks(text) - return self - - func set_description(text: String) -> Parameter: - description = Util.remove_line_breaks(text) - return self - - func set_cost(val: int) -> Parameter: - cost = val - return self - - func set_type(val: String) -> Parameter: - type = Util.remove_line_breaks(val) - return self - - func add_warning(warning: String, warning_importance := -1) -> Parameter: - var w = Warning.new() - w.text = Util.remove_line_breaks(warning) - w.importance = warning_importance - warnings.push_back(w) - return self - - -var _category: String -var _page_title: String -var _paragraphs: Array[String] = [] -var _warnings: Array[Warning] = [] -var _parameters: Array[Parameter] = [] - - -func set_category(text: String) -> void: - _category = text - - -func set_title(text: String) -> void: - _page_title = text - - -func add_paragraph(text: String) -> void: - _paragraphs.push_back(Util.remove_line_breaks(text)) - - -# Warning importance: -# 0: Default (Grey) -# 1: Mid (Yellow) -# 2: Critical (Red) -func add_warning(text: String, importance: int = 0) -> void: - var w = Warning.new() - w.text = Util.remove_line_breaks(text) - w.importance = importance - - _warnings.push_back(w) - - -# Add documentation for a user exposed parameter. -# Cost: -# 0: None -# 1: Log -# 2: Linear -# 3: Exponential -func add_parameter(name := "") -> Parameter: - var p = Parameter.new() - p.name = name - p.cost = 0 - _parameters.push_back(p) - return p - - -func get_title() -> String: - return _page_title - - -func get_category() -> String: - return _category - - -func get_paragraphs() -> Array[String]: - return _paragraphs - - -func get_warnings() -> Array[Warning]: - return _warnings - - -func get_parameters() -> Array[Parameter]: - return _parameters diff --git a/addons/scatter-4/src/documentation/pages/special_pages.gd b/addons/scatter-4/src/documentation/pages/special_pages.gd deleted file mode 100644 index 72f6bd9..0000000 --- a/addons/scatter-4/src/documentation/pages/special_pages.gd +++ /dev/null @@ -1,113 +0,0 @@ -@tool -extends RefCounted - -const DocumentationInfo = preload("../documentation_info.gd") - - -static func get_scatter_documentation() -> DocumentationInfo: - var info := DocumentationInfo.new() - - info.set_title("ProtonScatter") - info.add_paragraph( - "ProtonScatter is a content positioning add-on. It is suited to place - a large amount of objects in a procedural way.") - info.add_paragraph( - "This add-on is [color=red][b]IN BETA[/b][/color] which means breaking - changes may happen. It is not recommended to use in production yet." - ) - info.add_paragraph( - "First, define [i]what[/i] you want to place using [b]ScatterItems[/b] - nodes.") - info.add_paragraph( - "Then, define [i]where[/i] to place them using [b]ScatterShapes[/b] - nodes.") - info.add_paragraph( - "Finaly, define [i]how[/i] the content should be placed using the - [b]Modifier stack[/b] that's on the [b]ProtonScatter[/b] node.") - info.add_paragraph( - "Each of these components have their dedicated documenation page, but - first, you should check out the example scenes in the demo folder.") - - var p := info.add_parameter("General / Global seed") - p.set_type("int") - p.set_description( - "The random seed to use on this node. Modifiers using random components - can access this value and use it accordingly. You can also specify - a custom seed for specific modifiers as well.") - - p = info.add_parameter("General / Show output in tree") - p.set_type("bool") - p.set_description( - "Show the generated items in the editor scene tree. By default this - option is disabled as it creates quite a bit of clutter when instancing - is disabled. It also increases the scene file size significantly.") - - p = info.add_parameter("Performance / Use instancing") - p.set_type("bool") - p.set_description( - "When enabled, ProtonScatter will use MultiMeshInstance3D nodes - instead of duplicating the source nodes. This allows the GPU to render - thousands of meshes in a single draw call.") - p.add_warning("Collisions and attached scripts are ignored when this - option is enabled.", 1) - - return info - - -static func get_item_documentation() -> DocumentationInfo: - var info := DocumentationInfo.new() - - info.set_title("ScatterItems") - - info.add_paragraph("TODO: Write this page") - - return info - - -static func get_shape_documentation() -> DocumentationInfo: - var info := DocumentationInfo.new() - - info.set_title("ScatterShapes") - info.add_paragraph("TODO: Write this page") - - return info - - -static func get_modifiers_documentation() -> DocumentationInfo: - var info := DocumentationInfo.new() - - info.set_title("Modifiers") - info.add_paragraph( - "A modifier takes in a Transform3D list, create, modify or delete - transforms, then pass it down to the next modifier. Remember that - [b] modifiers are processed from top to bottom [/b]. A modifier - down the stack will recieve a list processed by the modifiers above.") - info.add_paragraph( - "The initial transform list is empty, so it's necessary to start the - stack with a [b] Create [/b] modifier.") - info.add_paragraph( - "When clicking the [b] Expand button [/b] (the little arrow on the left) - you get access to this modifier's parameters. This is where you can - adjust its behavior according to your needs.") - info.add_paragraph( - "Three common options might be found on these modifiers. (They can - be disabled if they are irrelevant). They are defined as follow:") - - var p := info.add_parameter("Use local seed") - p.set_description( - "The dice icon on the left allows you to force a specific seed for the - modifier. If this option is not used then the Global seed from the - ProtonScatter node will be used instead.") - - p = info.add_parameter("Restrict height") - p.set_description( - "When applicable, the modifier will remain within the local XZ plane - instead of using the full volume described by the ScatterShape nodes.") - - p = info.add_parameter("Use local space") - p.set_description( - "When enabled, the modifier will operate in local space relative to - the ProtonScatter node. If disabled, the modifier operates in - global space.") - - return info diff --git a/addons/scatter-4/src/documentation/panel.tscn b/addons/scatter-4/src/documentation/panel.tscn deleted file mode 100644 index f5687e3..0000000 --- a/addons/scatter-4/src/documentation/panel.tscn +++ /dev/null @@ -1,22 +0,0 @@ -[gd_scene format=3 uid="uid://cojoo2c73fpsb"] - -[node name="HSplitContainer" type="HSplitContainer"] -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 -split_offset = 250 - -[node name="Tree" type="Tree" parent="."] -layout_mode = 2 -offset_right = 250.0 -offset_bottom = 648.0 - -[node name="RichTextLabel" type="RichTextLabel" parent="."] -layout_mode = 2 -offset_left = 262.0 -offset_right = 1152.0 -offset_bottom = 648.0 -bbcode_enabled = true -text = "[center] [b] [i] Documentation page [/i] [/b] [/center]" diff --git a/addons/scatter-4/src/modifiers/array.gd b/addons/scatter-4/src/modifiers/array.gd deleted file mode 100644 index 3d97271..0000000 --- a/addons/scatter-4/src/modifiers/array.gd +++ /dev/null @@ -1,167 +0,0 @@ -@tool -extends "base_modifier.gd" - -# Takes existing objects and duplicates them recursively with given transforms - - -@export var amount := 1 -@export var min_amount := -1 -@export var local_offset := false -@export var offset := Vector3.ZERO -@export var local_rotation := false -@export var rotation := Vector3.ZERO -@export var individual_rotation_pivots := true -@export var rotation_pivot := Vector3.ZERO -@export var local_scale := true -@export var scale := Vector3.ONE -@export var randomize_indices := true - -var _rng: RandomNumberGenerator - - -func _init() -> void: - display_name = "Array" - category = "Create" - can_override_seed = true - can_restrict_height = false - global_reference_frame_available = false - local_reference_frame_available = false - individual_instances_reference_frame_available = false - - documentation.add_paragraph( - "Recursively creates copies of the existing transforms, with each copy - being offset from the previous one in any of a number of possible ways.") - - var p := documentation.add_parameter("Amount") - p.set_type("int") - p.set_cost(2) - p.set_description( - "The iteration count. If set to 1, each existing transforms are copied - once.") - p.add_warning("If set to 0, no copies are created.") - - p = documentation.add_parameter("Minimum amount") - p.set_type("int") - p.set_description( - "Creates a random amount of copies for each transforms, between this - value and the amount value.") - p.add_warning("Ignored if set to a negative value.") - - p = documentation.add_parameter("Offset") - p.set_type("Vector3") - p.set_description( - "Adds a constant offset between each copies and the previous one.") - - p = documentation.add_parameter("Local offset") - p.set_type("bool") - p.set_description( - "If enabled, offset is relative to the previous copy orientation. - Otherwise, the offset is in global space.") - - p = documentation.add_parameter("Rotation") - p.set_type("Vector3") - p.set_description( - "The rotation offset (on each axes) to add on each copy.") - - p = documentation.add_parameter("Local rotation") - p.set_type("bool") - p.set_description( - "If enabled, the rotation is applied in local space relative to each - individual transforms. Otherwise, the rotation is applied in global - space.") - - p = documentation.add_parameter("Rotation Pivot") - p.set_type("Vector3") - p.set_description( - "The point around which each copies are rotated. By default, each - transforms are rotated around their individual centers.") - - p = documentation.add_parameter("Individual Rotation Pivots") - p.set_type("bool") - p.set_description( - "If enabled, each copies will use their own pivot relative to the - previous copy. Otherwise, a single pivot point (defined in global space) - will be used for the rotation of [b]all[/b] the copies.") - - p = documentation.add_parameter("Scale") - p.set_type("Vector3") - p.set_description( - "Scales the copies relative to the transforms they are from.") - - p = documentation.add_parameter("Local Scale") - p.set_type("bool") - p.set_description( - "If enabled, scaling is applied in local space relative to each - individual transforms. Otherwise, global axes are used, resulting - in skewed transforms in most cases.") - - p = documentation.add_parameter("Randomize Indices") - p.set_type("bool") - p.set_description( - "Randomize the transform list order. This is only useful to break up the - repetitive patterns if you're using multiple ScatterItem nodes.") - - -func _process_transforms(transforms, domain, seed: int) -> void: - _rng = RandomNumberGenerator.new() - _rng.set_seed(seed) - - var new_transforms: Array[Transform3D] = [] - var rotation_rad := Vector3.ZERO - - rotation_rad.x = deg_to_rad(rotation.x) - rotation_rad.y = deg_to_rad(rotation.y) - rotation_rad.z = deg_to_rad(rotation.z) - - for t in transforms.size(): - new_transforms.push_back(transforms.list[t]) - - var steps = amount - if min_amount >= 0: - steps = _rng.randi_range(min_amount, amount) - - for a in steps: - a += 1 - - # use original object's transform as base transform - var transform : Transform3D = transforms.list[t] - var basis := transform.basis - - # first move to rotation point defined in rotation offset - var rotation_pivot_offset = (float(individual_rotation_pivots) * (transform * rotation_pivot) + float(!individual_rotation_pivots) * (rotation_pivot)) - transform.origin -= rotation_pivot_offset - - # then rotate - transform = transform.rotated(float(local_rotation) * basis.x + float(!local_rotation) * Vector3(1, 0, 0), rotation_rad.x * a) - transform = transform.rotated(float(local_rotation) * basis.y + float(!local_rotation) * Vector3(0, 1, 0), rotation_rad.y * a) - transform = transform.rotated(float(local_rotation) * basis.z + float(!local_rotation) * Vector3(0, 0, 1), rotation_rad.z * a) - - # scale - # If the scale is different than 1, each transform gets bigger or - # smaller for each iteration. - var s = scale - s.x = pow(s.x, a) - s.y = pow(s.y, a) - s.z = pow(s.z, a) - - if local_scale: - transform.basis.x *= s.x - transform.basis.y *= s.y - transform.basis.z *= s.z - else: - transform.basis = transform.basis.scaled(s) - - # apply changes back to the transform and undo the rotation pivot offset - transform.origin += rotation_pivot_offset - - # offset - transform.origin += (float(!local_offset) * offset * a) + (float(local_offset) * (basis * offset) * a) - - # store the final result if the position is valid - if not domain.is_point_excluded(transform.origin): - new_transforms.push_back(transform) - - transforms.list = new_transforms - - if randomize_indices: - transforms.shuffle(seed) diff --git a/addons/scatter-4/src/modifiers/base_modifier.gd b/addons/scatter-4/src/modifiers/base_modifier.gd deleted file mode 100644 index 9dd008b..0000000 --- a/addons/scatter-4/src/modifiers/base_modifier.gd +++ /dev/null @@ -1,106 +0,0 @@ -@tool -extends Resource - -# Modifiers place transforms. They create, edit or remove transforms in a list, -# before the next Modifier in the stack does the same. -# All Modifiers must inherit from this class. -# Transforms in the provided transforms list must be in global space. - - -signal warning_changed - -const TransformList = preload("../common/transform_list.gd") -const Domain = preload("../common/domain.gd") -const DocumentationInfo = preload("../documentation/documentation_info.gd") - -@export var enabled := true -@export var override_global_seed := false -@export var custom_seed := 0 -@export var restrict_height := false # Tells the modifier whether to constrain transforms to the local XY plane or not -@export var reference_frame := 0 - -var display_name: String = "Base Modifier Name" -var category: String = "None" -var documentation := DocumentationInfo.new() -var warning: String = "" -var warning_ignore_no_transforms := false -var warning_ignore_no_shape := false -var expanded := false -var can_override_seed := false -var can_restrict_height := true -var global_reference_frame_available := true -var local_reference_frame_available := false -var individual_instances_reference_frame_available := false -var use_edge_data := false - - -func get_warning() -> String: - return warning - - -func process_transforms(transforms: TransformList, domain: Domain, global_seed: int) -> void: - _clear_warning() - - if not enabled: - return - - if domain.is_empty() and not warning_ignore_no_shape: - warning += """The Scatter node does not have a shape. - Add at least one ScatterShape node as a child.\n""" - - if transforms.is_empty() and not warning_ignore_no_transforms: - warning += """There's no transforms to act on. - Make sure you have a Create modifier before this one.\n - """ - - var seed = global_seed - if can_override_seed and override_global_seed: - seed = custom_seed - - await _process_transforms(transforms, domain, seed) - - warning_changed.emit() - - -func get_copy(): - var script = get_script() - var copy = script.new() - for p in get_property_list(): - var value = get(p.name) - copy.set(p.name, value) - - return copy - - -func is_using_global_space() -> bool: - return reference_frame == 0 - - -func is_using_local_space() -> bool: - return reference_frame == 1 - - -func is_using_individual_instances_space() -> bool: - return reference_frame == 2 - - -func use_global_space_by_default() -> void: - reference_frame = 0 - - -func use_local_space_by_default() -> void: - reference_frame = 1 - - -func use_individual_instances_space_by_default() -> void: - reference_frame = 2 - - -func _clear_warning() -> void: - warning = "" - warning_changed.emit() - - -# Override in inherited class -func _process_transforms(_transforms: TransformList, _domain: Domain, _seed: int) -> void: - pass diff --git a/addons/scatter-4/src/modifiers/clusterize.gd b/addons/scatter-4/src/modifiers/clusterize.gd deleted file mode 100644 index 897b46d..0000000 --- a/addons/scatter-4/src/modifiers/clusterize.gd +++ /dev/null @@ -1,114 +0,0 @@ -@tool -extends "base_modifier.gd" - - -@export_file("Texture") var mask -@export var mask_scale := Vector2.ONE -@export var mask_offset := Vector2.ZERO -@export var mask_rotation := 0.0 -@export_range(0.0, 1.0) var remove_below = 0.1 - - -func _init() -> void: - display_name = "Clusterize" - category = "Edit" - global_reference_frame_available = true - local_reference_frame_available = false # TODO, enable this and handle this case - individual_instances_reference_frame_available = false - - documentation.add_paragraph( - "Clump transforms together based on a mask. - Sampling the mask returns values between 0 and 1. The transforms are - scaled against these values which means, bright areas don't affect their - scale while dark area scales them down. Transforms are then removed - below a threshold, leaving clumps behind.") - - var p := documentation.add_parameter("Mask") - p.set_type("Texture") - p.set_description("The texture used as a mask.") - p.add_warning( - "The amount of texture fetch depends on the amount of transforms - generated in the previous modifiers (4 reads for each transform). - In theory, the texture size shouldn't affect performances in a - noticeable way.") - - p = documentation.add_parameter("Mask scale") - p.set_type("Vector2") - p.set_description( - "Depending on the mask resolution, the perceived scale will change. - Use this parameter to increase or decrease the area covered by the mask.") - - p = documentation.add_parameter("Mask offset") - p.set_type("Vector2") - p.set_description("Moves the mask XZ position in 3D space") - - p = documentation.add_parameter("Mask rotation") - p.set_type("Float") - p.set_description("Rotates the mask around the Y axis. (Angle in degrees)") - - p = documentation.add_parameter("Remove below") - p.set_type("Float") - p.set_description("Threshold below which the transforms are removed.") - - -func _process_transforms(transforms, domain, _seed) -> void: - if not ResourceLoader.exists(mask): - warning += "The specified file " + mask + " could not be loaded." - return - - var texture = load(mask) - - if not texture is Texture: - warning += "The specified file is not a valid texture." - return - - var image: Image = texture.get_data() - var _err = image.decompress() - image.lock() - - var width = image.get_width() - var height = image.get_height() - var i = 0 - var count = transforms.list.size() - var angle = deg_to_rad(mask_rotation) - - while i < count: - var t = transforms.list[i] - var origin = t.origin.rotated(Vector3.UP, angle) - - var x = origin.x * mask_scale.x + mask_offset.x - x = fposmod(x, width - 1) - var y = origin.z * mask_scale.y + mask_offset.y - y = fposmod(y, height - 1) - - var level = _get_pixel(image, x, y) - if level < remove_below: - transforms.list.remove(i) - count -= 1 - continue - - origin = t.origin - t.origin = Vector3.ZERO - t = t.scaled(Vector3(level, level, level)) - t.origin = origin - - transforms.list[i] = t - i += 1 - - image.unlock() - - -# x and y don't always match an exact pixel, so we sample the neighboring -# pixels as well and return a weighted value based on the input coords. -func _get_pixel(image: Image, x: float, y: float) -> float: - var ix = int(x) - var iy = int(y) - x -= ix - y -= iy - - var nw = image.get_pixel(ix, iy).v - var ne = image.get_pixel(ix + 1, iy).v - var sw = image.get_pixel(ix, iy + 1).v - var se = image.get_pixel(ix + 1, iy + 1).v - - return nw * (1 - x) * (1 - y) + ne * x * (1 - y) + sw * (1 - x) * y + se * x * y diff --git a/addons/scatter-4/src/modifiers/create_along_edge_continuous.gd b/addons/scatter-4/src/modifiers/create_along_edge_continuous.gd deleted file mode 100644 index 66d6202..0000000 --- a/addons/scatter-4/src/modifiers/create_along_edge_continuous.gd +++ /dev/null @@ -1,97 +0,0 @@ -@tool -extends "base_modifier.gd" - - -@export var item_length := 2.0 -@export var ignore_slopes := false - -var _current_offset = 0.0 - - -func _init() -> void: - display_name = "Create Along Edge (Continuous)" - category = "Create" - warning_ignore_no_transforms = true - warning_ignore_no_shape = false - use_edge_data = true - global_reference_frame_available = false - local_reference_frame_available = false - individual_instances_reference_frame_available = false - - var p - - documentation.add_paragraph( - "Create new transforms along the edges of the Scatter shapes. These - transforms are placed so they touch each other but don't overlap, even - if the curve has sharp turns.") - - documentation.add_paragraph( - "This is useful to place props suchs as fences, walls or anything that - needs to look organized without leaving gaps.") - - documentation.add_warning( - "The transforms are placed starting from the begining of each curves. - If the curve is closed, there will be a gap at the end if the total - curve length isn't a multiple of the item length.") - - p = documentation.add_parameter("Item length") - p.set_type("float") - p.set_description("How long is the item being placed") - p.set_cost(2) - p.add_warning( - "The smaller this value, the more transforms will be created. - Setting a slightly different length than the actual model length - allow for gaps between each transforms.") - - p = documentation.add_parameter("Ignore slopes") - p.set_type("bool") - p.set_description( - "If enabled, all the curves will be projected to the local XZ plane - before creating the new transforms.") - - -# TODO: Use dichotomic search instead of fixed step length? -func _process_transforms(transforms, domain, _seed) -> void: - var new_transforms: Array[Transform3D] = [] - var curves: Array[Curve3D] = domain.get_edges() - - for curve in curves: - if not ignore_slopes: - curve = curve.duplicate() - else: - curve = get_projected_curve(curve, domain.get_global_transform()) - - var length_squared = pow(item_length, 2) - var offset_max = curve.get_baked_length() - var offset = 0.0 - var step = item_length / 20.0 - - while offset < offset_max: - var start := curve.sample_baked(offset) - var end: Vector3 - var dist: float - offset += item_length * 0.9 # Saves a few iterations, the target - # point will never be closer than the item length, only further - - while offset < offset_max: - offset += step - end = curve.sample_baked(offset) - dist = start.distance_squared_to(end) - - if dist >= length_squared: - var t = Transform3D() - t.origin = start + ((end - start) / 2.0) - new_transforms.push_back(t.looking_at(end, Vector3.UP)) - break - - transforms.append(new_transforms) - - -func get_projected_curve(curve: Curve3D, t: Transform3D) -> Curve3D: - var points = curve.tessellate() - var new_curve = Curve3D.new() - for p in points: - p.y = t.origin.y - new_curve.add_point(p) - - return new_curve diff --git a/addons/scatter-4/src/modifiers/create_along_edge_even.gd b/addons/scatter-4/src/modifiers/create_along_edge_even.gd deleted file mode 100644 index 78cd97c..0000000 --- a/addons/scatter-4/src/modifiers/create_along_edge_even.gd +++ /dev/null @@ -1,106 +0,0 @@ -@tool -extends "base_modifier.gd" - - -const Util := preload("../common/util.gd") - - -# TODO : -# + change alignement parameters to something more usable and intuitive -# + Use the curve up vector, default to local Y+ when not available -@export var spacing := 1.0 -@export var offset := 0.0 -@export_enum("X", "Y", "Z") var up_axis := 1 -@export var align_x := false -@export var align_y := false -@export var align_z := false - -var _min_spacing := 0.05 - - -func _init() -> void: - display_name = "Create Along Edge (Even)" - category = "Create" - warning_ignore_no_transforms = true - warning_ignore_no_shape = false - can_restrict_height = false - global_reference_frame_available = false - local_reference_frame_available = false - individual_instances_reference_frame_available = false - use_edge_data = true - - var p - documentation.add_paragraph( - "Evenly create transforms along the edges of the ScatterShapes") - - p = documentation.add_parameter("Spacing") - p.set_type("float") - p.set_description("How much space between the transforms origin") - p.set_cost(3) - p.add_warning("The smaller the value, the denser the resulting transforms list.", 1) - p.add_warning( - "A value of 0 would result in infinite transforms, so it's capped - to 0.05 at least.") - - -func _process_transforms(transforms, domain, _seed) -> void: - spacing = max(_min_spacing, spacing) - - var up := get_align_up_vector(up_axis) - var inverse_basis: Basis = domain.get_global_transform().affine_inverse().basis - var up_local := up * inverse_basis - - var new_transforms: Array[Transform3D] = [] - var curves: Array[Curve3D] = domain.get_edges() - - for curve in curves: - var length: float = curve.get_baked_length() - var count := int(round(length / spacing)) - var stepped_length: float = count * spacing - - for i in count: - var curve_offset = i * spacing + abs(offset) - - while curve_offset > stepped_length: # Loop back to the curve start if offset is too large - curve_offset -= stepped_length - - var data : Array = Util.get_position_and_normal_at(curve, curve_offset) - var pos: Vector3 = data[0] - var normal: Vector3 = data[1] - - if domain.is_point_excluded(pos): - continue - - var t := Transform3D() - t.origin = pos - t = t.looking_at(normal + pos, up) - - var angles := t.basis.get_euler() - angles.x *= int(align_x) - angles.y *= int(align_y) - angles.z *= int(align_y) - - t.basis = t.basis.from_euler(angles) - - new_transforms.push_back(t) - - transforms.append(new_transforms) - - -static func get_align_up_vector(align : int) -> Vector3: - var axis : Vector3 - match align: - #x - 0: - axis = Vector3.RIGHT - #y - 1: - axis = Vector3.UP - #z - 2: - axis = Vector3.BACK - _: - #default return y axis - axis = Vector3.UP - - return axis diff --git a/addons/scatter-4/src/modifiers/create_along_edge_random.gd b/addons/scatter-4/src/modifiers/create_along_edge_random.gd deleted file mode 100644 index 5a6cc41..0000000 --- a/addons/scatter-4/src/modifiers/create_along_edge_random.gd +++ /dev/null @@ -1,69 +0,0 @@ -@tool -extends "base_modifier.gd" - - -@export var instance_count := 10 -@export var align_to_path := false -@export var align_up_axis := Vector3.UP - -var _rng: RandomNumberGenerator - - -func _init() -> void: - display_name = "Create Along Edge (Random)" - category = "Create" - warning_ignore_no_transforms = true - warning_ignore_no_shape = false - use_edge_data = true - global_reference_frame_available = true - local_reference_frame_available = true - individual_instances_reference_frame_available = false - - -func _process_transforms(transforms, domain, seed) -> void: - _rng = RandomNumberGenerator.new() - _rng.set_seed(seed) - - var st: Transform3D = domain.get_global_transform() - var new_transforms: Array[Transform3D] = [] - var curves: Array[Curve3D] = domain.get_edges() - var total_curve_length := 0.0 - - for curve in curves: - var length: float = curve.get_baked_length() - total_curve_length += length - - for curve in curves: - var length: float = curve.get_baked_length() - var local_instance_count: int = round((length / total_curve_length) * instance_count) - - for i in local_instance_count: - var data = get_pos_and_normal(curve, _rng.randf() * length) - var pos: Vector3 = data[0] - var normal: Vector3 = data[1] - var t := Transform3D() - - t.origin = pos - if align_to_path: - t = t.looking_at(normal + pos, align_up_axis) - elif is_using_local_space(): - t.basis = st.basis - - new_transforms.push_back(t) - - transforms.append(new_transforms) - - -func get_pos_and_normal(curve: Curve3D, offset : float) -> Array: - var pos: Vector3 = curve.sample_baked(offset) - var normal := Vector3.ZERO - - var pos1 - if offset + curve.get_bake_interval() < curve.get_baked_length(): - pos1 = curve.sample_baked(offset + curve.get_bake_interval()) - normal = (pos1 - pos) - else: - pos1 = curve.sample_baked(offset - curve.get_bake_interval()) - normal = (pos - pos1) - - return [pos, normal] diff --git a/addons/scatter-4/src/modifiers/create_inside_grid.gd b/addons/scatter-4/src/modifiers/create_inside_grid.gd deleted file mode 100644 index bdbeb0f..0000000 --- a/addons/scatter-4/src/modifiers/create_inside_grid.gd +++ /dev/null @@ -1,100 +0,0 @@ -@tool -extends "base_modifier.gd" - - -@export var spacing := Vector3(2.0, 2.0, 2.0) - -var _min_spacing := 0.05 - - -func _init() -> void: - display_name = "Create Inside (Grid)" - category = "Create" - warning_ignore_no_transforms = true - warning_ignore_no_shape = false - can_restrict_height = true - restrict_height = true - global_reference_frame_available = true - local_reference_frame_available = true - individual_instances_reference_frame_available = false - - documentation.add_paragraph( - "Place transforms along the edges of the ScatterShapes") - - documentation.add_paragraph( - "When [b]Local Space[/b] is enabled, the grid is aligned with the - Scatter root node. Otherwise, the grid is aligned with the global - axes." - ) - - var p = documentation.add_parameter("Spacing") - p.set_type("vector3") - p.set_description( - "Defines the grid size along the 3 axes. A spacing of 1 means 1 unit - of space between each transform on this axis.") - p.set_cost(3) - p.add_warning( - "The smaller the value, the denser the resulting transforms list. - Use with care as the performance impact will go up quickly.", 1) - p.add_warning( - "A value of 0 would result in infinite transforms, so it's capped to 0.05 - at least.") - - -func _process_transforms(transforms, domain, seed) -> void: - spacing.x = max(_min_spacing, spacing.x) - spacing.y = max(_min_spacing, spacing.y) - spacing.z = max(_min_spacing, spacing.z) - - var gt: Transform3D = domain.get_global_transform() - var center: Vector3 = domain.bounds.center - var size: Vector3 = domain.bounds_local.size - - if is_using_local_space(): - center = domain.bounds_local.center - - var half_size := size * 0.5 - var start_corner := center - half_size - var baseline: float = 0.0 - - var width := int(ceil(size.x / spacing.x)) - var height := int(ceil(size.y / spacing.y)) - var length := int(ceil(size.z / spacing.z)) - - if restrict_height: - height = 1 - baseline = domain.bounds_local.max.y - else: - height = max(1, height) # Make sure height never gets below 1 or else nothing happens - - var max_count: int = width * length * height - var new_transforms: Array[Transform3D] = [] - new_transforms.resize(max_count) - - var t: Transform3D - var pos: Vector3 - var t_index := 0 - - for i in width * length: - for j in height: - t = Transform3D() - pos = Vector3.ZERO - pos.x = (i % width) * spacing.x - pos.y = (j * spacing.y) + baseline - pos.z = (i / width) * spacing.z - pos += start_corner - - if is_using_local_space(): - pos = gt * pos - t.basis = gt.basis - - if domain.is_point_inside(pos): - t.origin = pos - new_transforms[t_index] = t - t_index += 1 - - if t_index != new_transforms.size(): - new_transforms.resize(t_index) - - transforms.append(new_transforms) - transforms.shuffle(seed) diff --git a/addons/scatter-4/src/modifiers/create_inside_poisson.gd b/addons/scatter-4/src/modifiers/create_inside_poisson.gd deleted file mode 100644 index 8b5896c..0000000 --- a/addons/scatter-4/src/modifiers/create_inside_poisson.gd +++ /dev/null @@ -1,225 +0,0 @@ -@tool -extends "base_modifier.gd" - - -# Poisson disc sampling based on Sebastian Lague implementation, modified to -# support both 2D and 3D space. -# Reference: https://www.youtube.com/watch?v=7WcmyxyFO7o - -# TODO: This doesn't work if the valid space isn't one solid space -# (fails to fill the full domain if it's made of discrete, separate shapes) - - -const Bounds := preload("../common/bounds.gd") - -@export var radius := 1.0 -@export var samples_before_rejection := 15 - - -var _rng: RandomNumberGenerator -var _squared_radius: float -var _domain -var _bounds: Bounds - -var _gt: Transform3D -var _points: Array[Transform3D] # Stores the generated points -var _grid: Array[int] = [] # Flattened array -var _grid_size := Vector3i.ZERO -var _cell_size: float -var _cell_x: int -var _cell_y: int -var _cell_z: int - - -func _init() -> void: - display_name = "Create Inside (Poisson)" - category = "Create" - warning_ignore_no_transforms = true - warning_ignore_no_shape = false - can_restrict_height = true - can_override_seed = true - restrict_height = true - global_reference_frame_available = true - local_reference_frame_available = true - individual_instances_reference_frame_available = false - use_local_space_by_default() - - documentation.add_paragraph( - "Place transforms without overlaps. Transforms are assumed to have a - spherical shape.") - - var p := documentation.add_parameter("Radius") - p.set_type("float") - p.set_description("Transform size.") - p.add_warning( - "The larger the radius, the harder it will be to place the transform, - resulting in a faster early exit. - On the other hand, smaller radius means more room for more points, - meaning more transforms to generate so it will take longer to complete.") - - p = documentation.add_parameter("Samples before rejection") - p.set_type("int") - p.set_description( - "The algorithm tries a point at random until it finds a valid one. This - parameter controls how many attempts before moving to the next - iteration. Lower values are faster but gives poor coverage. Higher - values generates better coverage but are slower.") - p.set_cost(2) - - documentation.add_warning( - "This modifier uses a poisson disk sampling algorithm which can be - quite slow.") - - -func _process_transforms(transforms, domain, seed) -> void: - _rng = RandomNumberGenerator.new() - _rng.set_seed(seed) - _domain = domain - _bounds = _domain.bounds - _gt = domain.get_global_transform() - _points = [] - _init_grid() - - # Stores the possible starting points from where we run the sampling. - # This array will progressively be emptied as the algorithm progresses. - var spawn_points: Array[Transform3D] - spawn_points.push_back(_get_starting_point()) - - # Sampler main loop - while not spawn_points.is_empty(): - - # Pick a starting point at random from the existing list - var spawn_index: int = _rng.randi_range(0, spawn_points.size() - 1) - var spawn_center := spawn_points[spawn_index] - - var tries := 0 - var candidate_accepted := false - - while tries < samples_before_rejection: - tries += 1 - - # Generate a random point in space, outside the radius of the spawn point - var dir: Vector3 = _generate_random_vector() - var candidate: Vector3 = spawn_center.origin + dir * _rng.randf_range(radius, radius * 2.0) - - if _is_valid(candidate): - candidate_accepted = true - - # Add new points to the lists - var t = Transform3D() - t.origin = candidate - - if is_using_local_space(): - t.basis = _gt.basis - - _points.push_back(t) - spawn_points.push_back(t) - if restrict_height: - _grid[_cell_x + _cell_z * _grid_size.z] = _points.size() - 1 - else: - _grid[_cell_x + (_grid_size.y * _cell_y) + (_grid_size.x * _grid_size.y * _cell_z)] = _points.size() - 1 - - break - - # Failed to find a point after too many tries. The space around this - # spawn point is probably full, discard it. - if not candidate_accepted: - spawn_points.remove_at(spawn_index) - - transforms.append(_points) - transforms.shuffle(seed) - - -func _init_grid() -> void: - _squared_radius = radius * radius - _cell_size = radius / sqrt(2) - _grid_size.x = ceil(_bounds.size.x / _cell_size) - _grid_size.y = ceil(_bounds.size.y / _cell_size) - _grid_size.z = ceil(_bounds.size.z / _cell_size) - - _grid_size = _grid_size.clamp(Vector3.ONE, _grid_size) - - _grid = [] - if restrict_height: - _grid.resize(_grid_size.x * _grid_size.z) - else: - _grid.resize(_grid_size.x * _grid_size.y * _grid_size.z) - - -# Starting point must be inside the domain, or we run the risk to never generate -# any valid point later on -# TODO: Domain may have islands, so we should use multiple starting points -func _get_starting_point() -> Transform3D: - var point: Vector3 = _bounds.center - - var tries := 0 - while not _domain.is_point_inside(point) or tries > 200: - tries += 1 - point.x = _rng.randf_range(_bounds.min.x, _bounds.max.x) - point.y = _rng.randf_range(_bounds.min.y, _bounds.max.y) - point.z = _rng.randf_range(_bounds.min.z, _bounds.max.z) - - if restrict_height: - point.y = _bounds.center.y - - var starting_point := Transform3D() - starting_point.origin = point - return starting_point - - -func _is_valid(candidate: Vector3) -> bool: - if not _domain.is_point_inside(candidate): - return false - - # compute candidate current cell - var t_candidate = candidate - _bounds.min - _cell_x = floor(t_candidate.x / _cell_size) - _cell_y = floor(t_candidate.y / _cell_size) - _cell_z = floor(t_candidate.z / _cell_size) - - # Search the surrounding cells for other points - var search_start_x: int = max(0, _cell_x - 2) - var search_end_x: int = min(_cell_x + 2, _grid_size.x - 1) - var search_start_y: int = max(0, _cell_y - 2) - var search_end_y: int = min(_cell_y + 2, _grid_size.y - 1) - var search_start_z: int = max(0, _cell_z - 2) - var search_end_z: int = min(_cell_z + 2, _grid_size.z - 1) - - if restrict_height: - for x in range(search_start_x, search_end_x + 1): - for z in range(search_start_z, search_end_z + 1): - var point_index = _grid[x + z * _grid_size.z] - if _is_point_too_close(candidate, point_index): - return false - else: - for x in range(search_start_x, search_end_x + 1): - for y in range(search_start_y, search_end_y + 1): - for z in range(search_start_z, search_end_z + 1): - var point_index = _grid[x + (_grid_size.y * y) + (_grid_size.x * _grid_size.y * z)] - if _is_point_too_close(candidate, point_index): - return false - - return true - - -func _is_point_too_close(candidate: Vector3, point_index) -> bool: - if point_index == null: - return false - - var other_point := _points[point_index] - var squared_dist: float = candidate.distance_squared_to(other_point.origin) - return squared_dist < _squared_radius - - -func _generate_random_vector(): - var angle = _rng.randf_range(0.0, TAU) - if restrict_height: - return Vector3(sin(angle), 0.0, cos(angle)) - - var costheta = _rng.randf_range(-1.0, 1.0) - var theta = acos(costheta) - var vector := Vector3.ZERO - vector.x = sin(theta) * cos(angle) - vector.y = sin(theta) * sin(angle) - vector.z = cos(theta) - return vector diff --git a/addons/scatter-4/src/modifiers/create_inside_random.gd b/addons/scatter-4/src/modifiers/create_inside_random.gd deleted file mode 100644 index 529916d..0000000 --- a/addons/scatter-4/src/modifiers/create_inside_random.gd +++ /dev/null @@ -1,85 +0,0 @@ -@tool -extends "base_modifier.gd" - - -@export var amount := 10 - -var _rng: RandomNumberGenerator - - -func _init() -> void: - display_name = "Create Inside (Random)" - category = "Create" - warning_ignore_no_transforms = true - warning_ignore_no_shape = false - can_override_seed = true - global_reference_frame_available = true - local_reference_frame_available = true - use_local_space_by_default() - - documentation.add_paragraph( - "Randomly place new transforms inside the area defined by - the ScatterShape nodes.") - - var p := documentation.add_parameter("Amount") - p.set_type("int") - p.set_description("How many transforms will be created.") - p.set_cost(2) - - documentation.add_warning( - "In some cases, the amount of transforms created by this modifier - might be lower than the requested amount (but never higher). This may - happen if the provided ScatterShape has a huge bounding box but a tiny - valid space, like a narrow path.") - - -# TODO: -# + Multithreading -# + Spatial partionning to discard areas outside the domain earlier -func _process_transforms(transforms, domain, seed) -> void: - _rng = RandomNumberGenerator.new() - _rng.set_seed(seed) - - var gt: Transform3D = domain.get_global_transform() - var gt_inverse = gt.affine_inverse() - var center: Vector3 = domain.bounds.center - var half_size: Vector3 = domain.bounds.size / 2.0 - var height: float = domain.bounds.center.y - - # Generate a random point in the bounding box. Store if it's inside the - # domain, or discard if invalid. Repeat until enough valid points are found. - var t: Transform3D - var pos: Vector3 - var new_transforms: Array[Transform3D] = [] - var max_retries = amount * 10 - var tries := 0 - - while new_transforms.size() != amount: - t = Transform3D() - pos = _random_vec3() * half_size + center - - if restrict_height: - pos.y = height - - if is_using_local_space(): - t.basis = gt.basis - - if domain.is_point_inside(pos): - t.origin = pos - new_transforms.push_back(t) - continue - - # Prevents an infinite loop - tries += 1 - if tries > max_retries: - break - - transforms.append(new_transforms) - - -func _random_vec3() -> Vector3: - var vec3 = Vector3.ZERO - vec3.x = _rng.randf_range(-1.0, 1.0) - vec3.y = _rng.randf_range(-1.0, 1.0) - vec3.z = _rng.randf_range(-1.0, 1.0) - return vec3 diff --git a/addons/scatter-4/src/modifiers/look_at.gd b/addons/scatter-4/src/modifiers/look_at.gd deleted file mode 100644 index 471d14c..0000000 --- a/addons/scatter-4/src/modifiers/look_at.gd +++ /dev/null @@ -1,42 +0,0 @@ -@tool -extends "base_modifier.gd" - - -@export var target := Vector3.ZERO -@export var up := Vector3.UP - - -func _init() -> void: - display_name = "Look At" - category = "Edit" - can_restrict_height = false - global_reference_frame_available = true - local_reference_frame_available = true - individual_instances_reference_frame_available = true - use_local_space_by_default() - - documentation.add_paragraph("Rotates every transform such that the forward axis (-Z) points towards the target position.") - - documentation.add_parameter("Target").set_type("Vector3").set_description( - "Target position (X, Y, Z)") - documentation.add_parameter("Up").set_type("Vector3").set_description( - "Up axes (X, Y, Z)") - - -func _process_transforms(transforms, domain, _seed : int) -> void: - var st: Transform3D = domain.get_global_transform() - - for t in transforms.size(): - var transform: Transform3D = transforms.list[t] - var origin := transform.origin - var original_scale := transform.basis.get_scale() - var local_target := target - origin - - if is_using_local_space(): - local_target = st * local_target - elif is_using_individual_instances_space(): - local_target = transform * local_target - - var lookat := Transform3D(Basis.looking_at(local_target, up), origin) - lookat = lookat.scaled_local(original_scale) - transforms.list[t] = lookat diff --git a/addons/scatter-4/src/modifiers/offset_position.gd b/addons/scatter-4/src/modifiers/offset_position.gd deleted file mode 100644 index 5a0ba43..0000000 --- a/addons/scatter-4/src/modifiers/offset_position.gd +++ /dev/null @@ -1,38 +0,0 @@ -@tool -extends "base_modifier.gd" - - -@export var position := Vector3.ZERO - - -func _init() -> void: - display_name = "Offset Position" - category = "Offset" - can_restrict_height = false - global_reference_frame_available = true - local_reference_frame_available = true - individual_instances_reference_frame_available = true - use_individual_instances_space_by_default() - - documentation.add_paragraph("Moves every transform the same way.") - - var p := documentation.add_parameter("Position") - p.set_type("vector3") - p.set_description("How far each transforms are moved.") - - -func _process_transforms(transforms, domain, _seed) -> void: - var st: Transform3D = domain.get_global_transform() - var t: Transform3D - - for i in transforms.list.size(): - t = transforms.list[i] - - if is_using_individual_instances_space(): - t.origin += t.basis * position - elif is_using_local_space(): - t.origin += st.basis * position - else: - t.origin += position - - transforms.list[i] = t diff --git a/addons/scatter-4/src/modifiers/offset_rotation.gd b/addons/scatter-4/src/modifiers/offset_rotation.gd deleted file mode 100644 index d69a30a..0000000 --- a/addons/scatter-4/src/modifiers/offset_rotation.gd +++ /dev/null @@ -1,54 +0,0 @@ -@tool -extends "base_modifier.gd" - - -@export var rotation := Vector3.ZERO - - -func _init() -> void: - display_name = "Offset Rotation" - category = "Offset" - can_restrict_height = false - global_reference_frame_available = true - local_reference_frame_available = true - individual_instances_reference_frame_available = true - use_individual_instances_space_by_default() - - documentation.add_paragraph("Rotates every transform.") - - documentation.add_parameter("Rotation").set_type("Vector3").set_description( - "Rotation angle (in degrees) along each axes (X, Y, Z)") - - -func _process_transforms(transforms, domain, _seed : int) -> void: - var rotation_rad := Vector3.ZERO - rotation_rad.x = deg_to_rad(rotation.x) - rotation_rad.y = deg_to_rad(rotation.y) - rotation_rad.z = deg_to_rad(rotation.z) - - var t: Transform3D - var basis: Basis - var axis_x := Vector3.RIGHT - var axis_y := Vector3.UP - var axis_z := Vector3.FORWARD - - if is_using_local_space(): - var st: Transform3D = domain.get_global_transform() - axis_x = st.basis.x - axis_y = st.basis.y - axis_z = st.basis.z - - for i in transforms.size(): - t = transforms.list[i] - basis = t.basis - - if is_using_individual_instances_space(): - axis_x = basis.x - axis_y = basis.y - axis_z = basis.z - - basis = basis.rotated(axis_x, rotation_rad.x) - basis = basis.rotated(axis_y, rotation_rad.y) - basis = basis.rotated(axis_z, rotation_rad.z) - - transforms.list[i].basis = basis diff --git a/addons/scatter-4/src/modifiers/offset_scale.gd b/addons/scatter-4/src/modifiers/offset_scale.gd deleted file mode 100644 index 959e2fb..0000000 --- a/addons/scatter-4/src/modifiers/offset_scale.gd +++ /dev/null @@ -1,45 +0,0 @@ -@tool -extends "base_modifier.gd" - - -@export var scale := Vector3(1, 1, 1) - - -func _init() -> void: - display_name = "Offset Scale" - category = "Offset" - can_restrict_height = false - global_reference_frame_available = true - local_reference_frame_available = true - individual_instances_reference_frame_available = true - use_individual_instances_space_by_default() - - documentation.add_paragraph("Scales every transform.") - - var p := documentation.add_parameter("Scale") - p.set_type("Vector3") - p.set_description("How much to scale the transform along each axes (X, Y, Z)") - - -func _process_transforms(transforms, domain, _seed) -> void: - var st: Transform3D = domain.get_global_transform() - var basis: Basis - var t: Transform3D - var local_t: Transform3D - - for i in transforms.size(): - t = transforms.list[i] - basis = t.basis - - if is_using_individual_instances_space(): - basis.x *= scale.x - basis.y *= scale.y - basis.z *= scale.z - elif is_using_local_space(): - local_t = t * st - local_t.basis = local_t.basis.scaled(scale) - basis = (st * local_t).basis - else: - basis = basis.scaled(scale) - - transforms.list[i].basis = basis diff --git a/addons/scatter-4/src/modifiers/offset_transform.gd b/addons/scatter-4/src/modifiers/offset_transform.gd deleted file mode 100644 index cd3166d..0000000 --- a/addons/scatter-4/src/modifiers/offset_transform.gd +++ /dev/null @@ -1,81 +0,0 @@ -@tool -extends "base_modifier.gd" - - -@export var position := Vector3.ZERO -@export var rotation := Vector3(0.0, 0.0, 0.0) -@export var scale := Vector3.ONE - - -func _init() -> void: - display_name = "Offset Transform" - category = "Offset" - can_restrict_height = false - global_reference_frame_available = true - local_reference_frame_available = true - individual_instances_reference_frame_available = true - use_local_space_by_default() - - documentation.add_paragraph( - "Offsets position, rotation and scale in a single modifier. Every - transforms generated before will see the same transformation applied.") - - var p := documentation.add_parameter("Position") - p.set_type("Vector3") - p.set_description("How far each transforms are moved.") - - p = documentation.add_parameter("Rotation") - p.set_type("Vector3") - p.set_description("Rotation angle (in degrees) along each axes (X, Y, Z)") - - p = documentation.add_parameter("Scale") - p.set_type("Vector3") - p.set_description("How much to scale the transform along each axes (X, Y, Z)") - - -func _process_transforms(transforms, domain, _seed) -> void: - var t: Transform3D - var local_t: Transform3D - var basis: Basis - var axis_x := Vector3.RIGHT - var axis_y := Vector3.UP - var axis_z := Vector3.DOWN - var final_scale := scale - var final_position := position - var st: Transform3D = domain.get_global_transform() - - if is_using_local_space(): - axis_x = st.basis.x - axis_y = st.basis.y - axis_z = st.basis.z - final_scale = scale.rotated(Vector3.RIGHT, st.basis.get_euler().x) - final_position = st.basis * position - - for i in transforms.size(): - t = transforms.list[i] - basis = t.basis - - if is_using_individual_instances_space(): - axis_x = basis.x - axis_y = basis.y - axis_z = basis.z - basis.x *= scale.x - basis.y *= scale.y - basis.z *= scale.z - final_position = t.basis * position - - elif is_using_local_space(): - local_t = t * st - local_t.basis = local_t.basis.scaled(final_scale) - basis = (st * local_t).basis - - else: - basis = basis.scaled(final_scale) - - basis = basis.rotated(axis_x, deg_to_rad(rotation.x)) - basis = basis.rotated(axis_y, deg_to_rad(rotation.y)) - basis = basis.rotated(axis_z, deg_to_rad(rotation.z)) - t.basis = basis - t.origin += final_position - - transforms.list[i] = t diff --git a/addons/scatter-4/src/modifiers/project_on_geometry.gd b/addons/scatter-4/src/modifiers/project_on_geometry.gd deleted file mode 100644 index 4ad6209..0000000 --- a/addons/scatter-4/src/modifiers/project_on_geometry.gd +++ /dev/null @@ -1,179 +0,0 @@ -@tool -extends "base_modifier.gd" - - -signal projection_completed - - -const ProtonScatterPhysicsHelper := preload("res://addons/proton_scatter/src/common/physics_helper.gd") - - -@export var ray_direction := Vector3.DOWN -@export var ray_length := 10.0 -@export var ray_offset := 1.0 -@export var remove_points_on_miss := true -@export var align_with_collision_normal := false -@export_range(0.0, 90.0) var max_slope = 90.0 -@export_flags_3d_physics var collision_mask = 1 - -var _last_hit: Dictionary - - -func _init() -> void: - display_name = "Project On Colliders" - category = "Edit" - can_restrict_height = false - global_reference_frame_available = true - local_reference_frame_available = true - individual_instances_reference_frame_available = true - use_global_space_by_default() - - documentation.add_paragraph( - "Moves each transforms along the ray direction until they hit a collider. - This is useful to avoid floating objects on uneven terrain for example.") - - documentation.add_warning( - "This modifier only works when physics bodies are around. It will ignore - simple MeshInstances nodes.") - - var p := documentation.add_parameter("Ray direction") - p.set_type("Vector3") - p.set_description( - "In which direction we look for a collider. This default to the DOWN - direction by default (look at the ground).") - p.add_warning( - "This is relative to the transform is local space is enabled, or aligned - with the global axis if local space is disabled.") - - p = documentation.add_parameter("Ray length") - p.set_type("float") - p.set_description("How far we look for other physics objects.") - p.set_cost(2) - - p = documentation.add_parameter("Ray offset") - p.set_type("Vector3") - p.set_description( - "Moves back the raycast origin point along the ray direction. This is - useful if the initial transform is slightly below the ground, which would - make the raycast miss the collider (since it would start inside).") - - p = documentation.add_parameter("Remove points on miss") - p.set_type("bool") - p.set_description( - "When enabled, if the raycast didn't collide with anything, or collided - with a surface above the max slope setting, the transform is removed - from the list. - This is useful to avoid floating objects that are too far from the rest - of the scene's geometry.") - - p = documentation.add_parameter("Align with collision normal") - p.set_type("bool") - p.set_description( - "Rotate the transform to align it with the collision normal in case - the ray cast hit a collider.") - - p = documentation.add_parameter("Max slope") - p.set_type("float") - p.set_description( - "Angle (in degrees) after which the hit is considered invalid. - When a ray cast hit, the normal of the ray is compared against the - normal of the hit. If you set the slope to 0°, the ray and the hit - normal would have to be perfectly aligned to be valid. On the other - hand, setting the maximum slope to 90° treats every collisions as - valid regardless of their normals.") - - p = documentation.add_parameter("Mask") - p.set_description( - "Only collide with colliders on these layers. Disabled layers will - be ignored. It's useful to ignore players or npcs that might be on the - scene when you're editing it.") - - -func _process_transforms(transforms, domain, _seed) -> void: - if transforms.is_empty(): - return - - # Create all the physics ray queries - var domain_basis: Basis = domain.get_root().get_global_transform().basis - var queries: Array[PhysicsRayQueryParameters3D] = [] - for t in transforms.list: - var start = t.origin - var end = t.origin - var dir = ray_direction.normalized() - - if is_using_individual_instances_space(): - dir = t.basis * dir - - elif is_using_local_space(): - dir = domain_basis * dir - - start -= ray_offset * dir - end += ray_length * dir - - var ray_query := PhysicsRayQueryParameters3D.new() - ray_query.from = start - ray_query.to = end - ray_query.collision_mask = collision_mask - - queries.push_back(ray_query) - - # Run the queries in the physics helper since we can't access the PhysicsServer - # from outside the _physics_process while also being in a separate thread. - var physics_helper: ProtonScatterPhysicsHelper = domain.get_root().get_physics_helper() - var ray_hits = await physics_helper.execute(queries) - - if ray_hits.is_empty(): - return - - # Apply the results - - var index := 0 - var d: float - var t: Transform3D - var remapped_max_slope = remap(max_slope, 0.0, 90.0, 0.0, 1.0) - var is_point_valid := false - - for hit in ray_hits: - is_point_valid = true - - if hit.is_empty(): - is_point_valid = false - else: - d = abs(Vector3.UP.dot(hit.normal)) - is_point_valid = d >= (1.0 - remapped_max_slope) - - if is_point_valid: - t = transforms.list[index] - - if align_with_collision_normal: - t = _align_with(t, hit.normal) - - t.origin = hit.position - transforms.list[index] = t - index += 1 - - elif remove_points_on_miss: - transforms.list.remove_at(index) - - if transforms.is_empty(): - warning += """Every points have been removed. Possible reasons include: \n - + No collider is close enough to the shapes. - + Ray length is too short. - + Ray direction is incorrect. - + Collision mask is not set properly. - + Max slope is too low. - """ - - -func _align_with(t: Transform3D, normal: Vector3) -> Transform3D: - var n1 = t.basis.y.normalized() - var n2 = normal.normalized() - - var cosa = n1.dot(n2) - var alpha = acos(cosa) - var axis = n1.cross(n2) - - if axis == Vector3.ZERO: - return t - - return t.rotated(axis.normalized(), alpha) diff --git a/addons/scatter-4/src/modifiers/proxy.gd b/addons/scatter-4/src/modifiers/proxy.gd deleted file mode 100644 index fd862ba..0000000 --- a/addons/scatter-4/src/modifiers/proxy.gd +++ /dev/null @@ -1,49 +0,0 @@ -@tool -extends "base_modifier.gd" - - -const Scatter = preload("../scatter.gd") - - -@export_node_path var scatter_node -#@export var auto_sync_changes := true # TODO: find a solution to this. - -var _reference_node - - -func _init() -> void: - display_name = "Proxy" - category = "Misc" - can_restrict_height = false - can_override_seed = false - global_reference_frame_available = false - local_reference_frame_available = false - individual_instances_reference_frame_available = false - warning_ignore_no_transforms = true - - documentation.add_paragraph("Copy a modifier stack from another ProtonScatter node in the scene.") - documentation.add_paragraph( - "Useful when you need multiple Scatter nodes sharing the same rules, without having to - replicate their modifiers and settings in each." - ) - documentation.add_paragraph( - "Unlike presets which are full independent copies, this method is more similar to a linked - copy. Changes on the original modifier stack will be accounted for in here." - ) - - var p = documentation.add_parameter("Scatter node") - p.set_type("NodePath") - p.set_description("The Scatter node to use as a reference.") - - -func _process_transforms(transforms, domain, _seed) -> void: - var reference_node = domain.get_root().get_node_or_null(scatter_node) - - if not reference_node or not reference_node is Scatter: - warning += "You need to select a valid ProtonScatter node." - return - - if reference_node.modifier_stack: - var stack = reference_node.modifier_stack.get_copy() - var result = stack.update(domain.get_root(), domain) - transforms.append(result.list) diff --git a/addons/scatter-4/src/modifiers/randomize_rotation.gd b/addons/scatter-4/src/modifiers/randomize_rotation.gd deleted file mode 100644 index aea5eae..0000000 --- a/addons/scatter-4/src/modifiers/randomize_rotation.gd +++ /dev/null @@ -1,88 +0,0 @@ -@tool -extends "base_modifier.gd" - - -@export var rotation := Vector3(360.0, 360.0, 360.0) -@export var snap_angle := Vector3.ZERO - -var _rng: RandomNumberGenerator - - -func _init() -> void: - display_name = "Randomize Rotation" - category = "Edit" - can_override_seed = true - can_restrict_height = false - global_reference_frame_available = true - local_reference_frame_available = true - individual_instances_reference_frame_available = true - use_individual_instances_space_by_default() - - documentation.add_paragraph("Randomly rotate every transforms individually.") - - var p := documentation.add_parameter("Rotation") - p.set_type("Vector3") - p.set_description("Rotation angle (in degrees) along each axes (X, Y, Z)") - - p = documentation.add_parameter("Snap angle") - p.set_type("Vector3") - p.set_description( - "When set to any value above 0, the rotation will be done by increments - of the snap angle.") - p.add_warning( - "Example: When Snap Angle is set to 90, the possible random rotation - offsets around an axis will be among [0, 90, 180, 360].") - - -func _process_transforms(transforms, domain, seed) -> void: - _rng = RandomNumberGenerator.new() - _rng.set_seed(seed) - - var t: Transform3D - var b: Basis - - var gt: Transform3D = domain.get_global_transform() - var gb: Basis = gt.basis - var axis_x: Vector3 = Vector3.RIGHT - var axis_y: Vector3 = Vector3.UP - var axis_z: Vector3 = Vector3.FORWARD - - if is_using_local_space(): - axis_x = (Vector3.RIGHT * gb).normalized() - axis_y = (Vector3.UP * gb).normalized() - axis_z = (Vector3.FORWARD * gb).normalized() - - for i in transforms.list.size(): - t = transforms.list[i] - b = t.basis - - if is_using_individual_instances_space(): - axis_x = t.basis.x.normalized() - axis_y = t.basis.y.normalized() - axis_z = t.basis.z.normalized() - - b = b.rotated(axis_x, _random_angle(rotation.x, snap_angle.x)) - b = b.rotated(axis_y, _random_angle(rotation.y, snap_angle.y)) - b = b.rotated(axis_z, _random_angle(rotation.z, snap_angle.z)) - - t.basis = b - transforms.list[i] = t - - -func _random_vec3() -> Vector3: - var vec3 = Vector3.ZERO - vec3.x = _rng.randf_range(-1.0, 1.0) - vec3.y = _rng.randf_range(-1.0, 1.0) - vec3.z = _rng.randf_range(-1.0, 1.0) - return vec3 - - -func _random_angle(rot: float, snap: float) -> float: - return deg_to_rad(snapped(_rng.randf_range(-1.0, 1.0) * rot, snap)) - - -func _clamp_vector(vec3, vmin, vmax) -> Vector3: - vec3.x = clamp(vec3.x, vmin.x, vmax.x) - vec3.y = clamp(vec3.y, vmin.y, vmax.y) - vec3.z = clamp(vec3.z, vmin.z, vmax.z) - return vec3 diff --git a/addons/scatter-4/src/modifiers/randomize_transforms.gd b/addons/scatter-4/src/modifiers/randomize_transforms.gd deleted file mode 100644 index eb675ad..0000000 --- a/addons/scatter-4/src/modifiers/randomize_transforms.gd +++ /dev/null @@ -1,94 +0,0 @@ -@tool -extends "base_modifier.gd" - - -@export var position := Vector3.ONE -@export var rotation := Vector3(360.0, 360.0, 360.0) -@export var scale := Vector3.ONE - -var _rng: RandomNumberGenerator - - -func _init() -> void: - display_name = "Randomize Transforms" - category = "Edit" - can_override_seed = true - can_restrict_height = false - global_reference_frame_available = true - local_reference_frame_available = true - individual_instances_reference_frame_available = true - use_individual_instances_space_by_default() - - -func _process_transforms(transforms, domain, seed) -> void: - _rng = RandomNumberGenerator.new() - _rng.set_seed(seed) - - var t: Transform3D - var local_t: Transform3D - var basis: Basis - var random_scale: Vector3 - var random_position: Vector3 - var st: Transform3D = domain.get_global_transform() - - # Global rotation axis - var axis_x := Vector3.RIGHT - var axis_y := Vector3.UP - var axis_z := Vector3.DOWN - - if is_using_local_space(): - axis_x = st.basis.x - axis_y = st.basis.y - axis_z = st.basis.z - - for i in transforms.size(): - t = transforms.list[i] - basis = t.basis - - random_scale = Vector3.ONE + (_rng.randf() * scale) - random_position = _random_vec3() * position - - if is_using_individual_instances_space(): - axis_x = basis.x - axis_y = basis.y - axis_z = basis.z - basis.x *= random_scale.x - basis.y *= random_scale.y - basis.z *= random_scale.z - random_position = t.basis * random_position - - elif is_using_local_space(): - local_t = t * st - local_t.basis = local_t.basis.scaled(random_scale) - basis = (st * local_t).basis - - else: - basis = basis.scaled(random_scale) - - basis = basis.rotated(axis_x, deg_to_rad(_random_float() * rotation.x)) - basis = basis.rotated(axis_y, deg_to_rad(_random_float() * rotation.y)) - basis = basis.rotated(axis_z, deg_to_rad(_random_float() * rotation.z)) - - t.origin += random_position - t.basis = basis - - transforms.list[i] = t - - -func _random_vec3() -> Vector3: - var vec3 = Vector3.ZERO - vec3.x = _rng.randf_range(-1.0, 1.0) - vec3.y = _rng.randf_range(-1.0, 1.0) - vec3.z = _rng.randf_range(-1.0, 1.0) - return vec3 - - -func _random_float() -> float: - return _rng.randf_range(-1.0, 1.0) - - -func _clamp_vector(vec3, vmin, vmax) -> Vector3: - vec3.x = clamp(vec3.x, vmin.x, vmax.x) - vec3.y = clamp(vec3.y, vmin.y, vmax.y) - vec3.z = clamp(vec3.z, vmin.z, vmax.z) - return vec3 diff --git a/addons/scatter-4/src/modifiers/relax.gd b/addons/scatter-4/src/modifiers/relax.gd deleted file mode 100644 index 24b686d..0000000 --- a/addons/scatter-4/src/modifiers/relax.gd +++ /dev/null @@ -1,44 +0,0 @@ -@tool -extends "base_modifier.gd" - - -@export var iterations : int = 3 -@export var offset_step : float = 0.01 -@export var consecutive_step_multiplier : float = 0.5 - - -func _init() -> void: - display_name = "Relax Position" - category = "Edit" - global_reference_frame_available = false - local_reference_frame_available = false - individual_instances_reference_frame_available = false - can_restrict_height = true - restrict_height = true - - -func _process_transforms(transforms, domain, _seed) -> void: - # TODO this can benefit greatly from multithreading - if transforms.size() < 2: - return - - var offset = offset_step - - for iteration in iterations: - for i in transforms.size(): - var min_vector = Vector3.ONE * 99999 - # Find the closest point - for j in transforms.size(): - if i == j: - continue - var d = transforms.list[i].origin - transforms.list[j].origin - if d.length() < min_vector.length(): - min_vector = d - - if restrict_height: - min_vector.y = 0.0 - - # move away from closest point - transforms.list[i].origin += min_vector.normalized() * offset - - offset *= consecutive_step_multiplier diff --git a/addons/scatter-4/src/modifiers/remove_outside_shapes.gd b/addons/scatter-4/src/modifiers/remove_outside_shapes.gd deleted file mode 100644 index 50f20b9..0000000 --- a/addons/scatter-4/src/modifiers/remove_outside_shapes.gd +++ /dev/null @@ -1,44 +0,0 @@ -@tool -extends "base_modifier.gd" - - -@export var negative_shapes_only := false - - -func _init() -> void: - display_name = "Remove Outside" - category = "Remove" - can_restrict_height = false - global_reference_frame_available = false - local_reference_frame_available = false - individual_instances_reference_frame_available = false - - documentation.add_paragraph( - "Remove all transforms falling outside a ScatterShape node, or inside - a shape set to 'Negative' mode.") - - var p := documentation.add_parameter("Negative Shapes Only") - p.set_type("bool") - p.set_description( - "Only remove transforms falling inside the negative shapes (shown - in red). Transforms outside any shapes will still remain.") - - -func _process_transforms(transforms, domain, seed) -> void: - var i := 0 - var point: Vector3 - var to_remove := false - - while i < transforms.size(): - point = transforms.list[i].origin - - if negative_shapes_only: - to_remove = domain.is_point_excluded(point) - else: - to_remove = not domain.is_point_inside(point) - - if to_remove: - transforms.list.remove_at(i) - continue - - i += 1 diff --git a/addons/scatter-4/src/modifiers/single_item.gd b/addons/scatter-4/src/modifiers/single_item.gd deleted file mode 100644 index fe1e120..0000000 --- a/addons/scatter-4/src/modifiers/single_item.gd +++ /dev/null @@ -1,36 +0,0 @@ -@tool -extends "base_modifier.gd" - -# Adds a single object with the given transform - -@export var offset := Vector3.ZERO -@export var rotation := Vector3.ZERO -@export var scale := Vector3.ONE - - -func _init() -> void: - display_name = "Add Single Item" - category = "Create" - warning_ignore_no_shape = true - warning_ignore_no_transforms = true - can_restrict_height = false - global_reference_frame_available = true - local_reference_frame_available = true - individual_instances_reference_frame_available = false - use_local_space_by_default() - - -func _process_transforms(transforms, domain, _seed) -> void: - var basis := Basis() - basis = basis.rotated(Vector3.RIGHT, deg_to_rad(rotation.x)) - basis = basis.rotated(Vector3.UP, deg_to_rad(rotation.y)) - basis = basis.rotated(Vector3.FORWARD, deg_to_rad(rotation.z)) - var transform := Transform3D(basis, offset) - - if is_using_local_space(): - var gt: Transform3D = domain.get_global_transform() - transform = gt * transform.scaled_local(scale) - else: - transform = transform.scaled(scale) - - transforms.list.push_back(transform) diff --git a/addons/scatter-4/src/presets/preset_entry.gd b/addons/scatter-4/src/presets/preset_entry.gd deleted file mode 100644 index 8a9d11c..0000000 --- a/addons/scatter-4/src/presets/preset_entry.gd +++ /dev/null @@ -1,27 +0,0 @@ -@tool -extends MarginContainer - -signal load_full -signal load_stack_only -signal delete - - -func _ready() -> void: - $%LoadStackOnly.pressed.connect(func (): load_stack_only.emit()) - $%LoadFullPreset.pressed.connect(func (): load_full.emit()) - $%DeleteButton.pressed.connect(func (): delete.emit()) - - -func set_preset_name(preset_name: String) -> void: - $%Label.set_text(preset_name.capitalize()) - - -func show_save_controls() -> void: - $%SaveButtons.visible = true - $%LoadButtons.visible = false - - -func show_load_controls() -> void: - $%SaveButtons.visible = false - $%LoadButtons.visible = true - diff --git a/addons/scatter-4/src/presets/preset_entry.tscn b/addons/scatter-4/src/presets/preset_entry.tscn deleted file mode 100644 index 7482d15..0000000 --- a/addons/scatter-4/src/presets/preset_entry.tscn +++ /dev/null @@ -1,130 +0,0 @@ -[gd_scene load_steps=6 format=3 uid="uid://bosqtuvhckh3g"] - -[ext_resource type="Texture2D" uid="uid://ddjrq1h4mkn6a" path="res://addons/proton_scatter/icons/load.svg" id="1_0auay"] -[ext_resource type="Script" path="res://addons/proton_scatter/src/presets/preset_entry.gd" id="1_bqha3"] -[ext_resource type="Texture2D" uid="uid://bl1rkjjxvxu8f" path="res://addons/proton_scatter/icons/remove.svg" id="2_p04k2"] - -[sub_resource type="SystemFont" id="SystemFont_kgkwq"] -font_style = 1 - -[sub_resource type="LabelSettings" id="LabelSettings_poli7"] -font = SubResource("SystemFont_kgkwq") - -[node name="PresetEntry" type="MarginContainer"] -custom_minimum_size = Vector2(450, 0) -anchors_preset = 14 -anchor_top = 0.5 -anchor_right = 1.0 -anchor_bottom = 0.5 -offset_top = -45.0 -offset_bottom = 45.0 -grow_horizontal = 2 -grow_vertical = 2 -size_flags_horizontal = 3 -script = ExtResource("1_bqha3") - -[node name="Panel" type="Panel" parent="."] -layout_mode = 2 -offset_right = 1920.0 -offset_bottom = 90.0 - -[node name="MarginContainer" type="MarginContainer" parent="."] -layout_mode = 2 -offset_right = 1920.0 -offset_bottom = 90.0 -theme_override_constants/margin_left = 12 -theme_override_constants/margin_top = 12 -theme_override_constants/margin_right = 12 -theme_override_constants/margin_bottom = 12 - -[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer"] -layout_mode = 2 -offset_left = 12.0 -offset_top = 12.0 -offset_right = 1908.0 -offset_bottom = 78.0 - -[node name="Label" type="Label" parent="MarginContainer/HBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 -offset_top = 20.0 -offset_right = 1669.0 -offset_bottom = 46.0 -size_flags_horizontal = 3 -text = "Preset name" -label_settings = SubResource("LabelSettings_poli7") - -[node name="VSeparator" type="VSeparator" parent="MarginContainer/HBoxContainer"] -layout_mode = 2 -offset_left = 1673.0 -offset_right = 1677.0 -offset_bottom = 66.0 - -[node name="LoadButtons" type="VBoxContainer" parent="MarginContainer/HBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 -offset_left = 1681.0 -offset_right = 1860.0 -offset_bottom = 66.0 -alignment = 1 - -[node name="LoadStackOnly" type="Button" parent="MarginContainer/HBoxContainer/LoadButtons"] -unique_name_in_owner = true -layout_mode = 2 -offset_right = 179.0 -offset_bottom = 31.0 -text = "Load modifier stack" -icon = ExtResource("1_0auay") -alignment = 0 - -[node name="LoadFullPreset" type="Button" parent="MarginContainer/HBoxContainer/LoadButtons"] -unique_name_in_owner = true -layout_mode = 2 -offset_top = 35.0 -offset_right = 179.0 -offset_bottom = 66.0 -text = "Load full preset" -icon = ExtResource("1_0auay") -alignment = 0 - -[node name="SaveButtons" type="VBoxContainer" parent="MarginContainer/HBoxContainer"] -unique_name_in_owner = true -visible = false -layout_mode = 2 -offset_left = 1712.0 -offset_right = 1860.0 -offset_bottom = 96.0 -size_flags_stretch_ratio = 2.0 -alignment = 1 - -[node name="OverrideButton" type="Button" parent="MarginContainer/HBoxContainer/SaveButtons"] -unique_name_in_owner = true -layout_mode = 2 -offset_top = 32.0 -offset_right = 148.0 -offset_bottom = 63.0 -text = "Override preset" -icon = ExtResource("1_0auay") -alignment = 0 - -[node name="VSeparator2" type="VSeparator" parent="MarginContainer/HBoxContainer"] -layout_mode = 2 -offset_left = 1864.0 -offset_right = 1868.0 -offset_bottom = 66.0 - -[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/HBoxContainer"] -layout_mode = 2 -offset_left = 1872.0 -offset_right = 1896.0 -offset_bottom = 66.0 -alignment = 1 - -[node name="DeleteButton" type="Button" parent="MarginContainer/HBoxContainer/VBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 -offset_top = 21.0 -offset_right = 24.0 -offset_bottom = 45.0 -theme_override_colors/icon_normal_color = Color(0.917647, 0.0784314, 0, 1) -icon = ExtResource("2_p04k2") diff --git a/addons/scatter-4/src/presets/presets.gd b/addons/scatter-4/src/presets/presets.gd deleted file mode 100644 index c406ce8..0000000 --- a/addons/scatter-4/src/presets/presets.gd +++ /dev/null @@ -1,169 +0,0 @@ -@tool -extends Popup - - -const PRESETS_PATH = "res://addons/proton_scatter/presets" -const PresetEntry := preload("./preset_entry.tscn") -const ScatterUtil := preload('../common/scatter_util.gd') -const ScatterItem := preload('../scatter_item.gd') -const ScatterShape := preload('../scatter_shape.gd') - -var _scatter_node -var _ideal_popup_size: Vector2i -var _editor_file_system: EditorFileSystem - - -func _ready(): - $%NewPresetButton.pressed.connect(_show_preset_dialog) - $%NewPresetDialog.confirmed.connect(_on_new_preset_name_confirmed) - - -func save_preset(scatter_node: Node3D) -> void: - if not scatter_node: - return - - _populate() - _scatter_node = scatter_node - $%NewPresetButton.visible = true - - for c in $%PresetsRoot.get_children(): - c.show_save_controls() - - popup_centered(_ideal_popup_size) - - -func load_preset(scatter_node: Node3D) -> void: - if not scatter_node: - return - - _populate() - _scatter_node = scatter_node - $%NewPresetButton.visible = false - - for c in $%PresetsRoot.get_children(): - c.show_load_controls() - - popup_centered(_ideal_popup_size) - - -func load_default(scatter_node: Node3D) -> void: - pass # TODO - - -func set_editor_plugin(editor_plugin: EditorPlugin) -> void: - if not editor_plugin: - return - - _editor_file_system = editor_plugin.get_editor_interface().get_resource_filesystem() - - -func _clear(): - for c in $%PresetsRoot.get_children(): - c.queue_free() - - -func _populate() -> void: - _clear() - var dir = DirAccess.open(PRESETS_PATH) - if not dir: - print_debug("ProtonScatter error: Could not open folder ", PRESETS_PATH) - return - - dir.include_hidden = false - dir.include_navigational = false - dir.list_dir_begin() - - while true: - var file := dir.get_next() - if file == "": - break - - if dir.current_is_dir(): - continue - - if not file.ends_with(".tscn") and not file.ends_with(".scn"): - continue - - # Preset found, create an entry - var full_path = PRESETS_PATH.path_join(file) - var entry := PresetEntry.instantiate() - entry.set_preset_name(file.get_basename()) - entry.load_full.connect(_on_load_full_preset.bind(full_path)) - entry.load_stack_only.connect(_on_load_stack_only.bind(full_path)) - entry.delete.connect(_on_delete_preset.bind(full_path, entry)) - - $%PresetsRoot.add_child(entry) - - dir.list_dir_end() - var full_height = $%PresetsRoot.get_child_count() * 120 - _ideal_popup_size = Vector2i(450, clamp(full_height, 120, 500)) - - -func _show_preset_dialog() -> void: - $%NewPresetName.set_text("") - $%NewPresetDialog.popup_centered() - - -func _on_new_preset_name_confirmed() -> void: - var file_name: String = $%NewPresetName.text.to_lower().strip_edges() + ".tscn" - var full_path := PRESETS_PATH.path_join(file_name) - _on_save_preset(full_path) - hide() - - -func _on_save_preset(path) -> void: - var preset = _scatter_node.duplicate(7) - preset.clear_output() - ScatterUtil.set_owner_recursive(preset, preset) - preset.global_transform.origin = Vector3.ZERO - - var packed_scene = PackedScene.new() - if packed_scene.pack(preset) != OK: - print_debug("ProtonScatter error: Failed to save preset") - return - - var err = ResourceSaver.save(packed_scene, path) - if err: - print_debug("ProtonScatter error: Failed to save preset. Code: ", err) - - -func _on_load_full_preset(path: String) -> void: - var preset = load(path).instantiate() - if preset: - _scatter_node.modifier_stack = preset.modifier_stack.get_copy() - preset.global_transform = _scatter_node.get_global_transform() - - for c in _scatter_node.get_children(): - if c is ScatterItem or c is ScatterShape: - _scatter_node.remove_child(c) - c.queue_free() - - for c in preset.get_children(): - if c is Marker3D or c.name == "ScatterOutput": - continue - preset.remove_child(c) - _scatter_node.add_child(c, true) - - ScatterUtil.set_owner_recursive(_scatter_node, get_tree().get_edited_scene_root()) - - _scatter_node.rebuild.call_deferred() - preset.queue_free() - - hide() - - -func _on_load_stack_only(path: String) -> void: - var preset = load(path).instantiate() - if preset: - _scatter_node.modifier_stack = preset.modifier_stack.get_copy() - _scatter_node.rebuild.call_deferred() - preset.queue_free() - - hide() - - -func _on_delete_preset(path: String, entry: Control) -> void: - DirAccess.remove_absolute(path) - $%PresetsRoot.remove_child(entry) - entry.queue_free() - _editor_file_system.scan() # Refresh the filesystem view diff --git a/addons/scatter-4/src/presets/presets.tscn b/addons/scatter-4/src/presets/presets.tscn deleted file mode 100644 index 86d9f92..0000000 --- a/addons/scatter-4/src/presets/presets.tscn +++ /dev/null @@ -1,93 +0,0 @@ -[gd_scene load_steps=4 format=3 uid="uid://bcsosdvstytoq"] - -[ext_resource type="Script" path="res://addons/proton_scatter/src/presets/presets.gd" id="1_ualle"] -[ext_resource type="Texture2D" uid="uid://cun73k8jdmr4e" path="res://addons/proton_scatter/icons/add.svg" id="2_j26xt"] -[ext_resource type="PackedScene" uid="uid://bosqtuvhckh3g" path="res://addons/proton_scatter/src/presets/preset_entry.tscn" id="2_orram"] - -[node name="Presets" type="PopupPanel"] -title = "Manage presets" -size = Vector2i(490, 200) -unresizable = false -borderless = false -always_on_top = true -extend_to_title = true -min_size = Vector2i(400, 150) -script = ExtResource("1_ualle") - -[node name="MarginContainer" type="MarginContainer" parent="."] -offset_left = 4.0 -offset_top = 4.0 -offset_right = 486.0 -offset_bottom = 196.0 -theme_override_constants/margin_left = 12 -theme_override_constants/margin_top = 12 -theme_override_constants/margin_right = 12 -theme_override_constants/margin_bottom = 12 - -[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer"] -layout_mode = 2 -offset_left = 12.0 -offset_top = 12.0 -offset_right = 470.0 -offset_bottom = 180.0 - -[node name="ScrollContainer" type="ScrollContainer" parent="MarginContainer/VBoxContainer"] -layout_mode = 2 -offset_right = 458.0 -offset_bottom = 133.0 -size_flags_vertical = 3 -horizontal_scroll_mode = 0 - -[node name="PresetsRoot" type="VBoxContainer" parent="MarginContainer/VBoxContainer/ScrollContainer"] -unique_name_in_owner = true -layout_mode = 2 -offset_right = 458.0 -offset_bottom = 133.0 -size_flags_horizontal = 3 -size_flags_vertical = 3 -alignment = 1 - -[node name="PresetEntry" parent="MarginContainer/VBoxContainer/ScrollContainer/PresetsRoot" instance=ExtResource("2_orram")] -layout_mode = 2 -anchors_preset = 0 -anchor_top = 0.0 -anchor_right = 0.0 -anchor_bottom = 0.0 -offset_top = 6.0 -offset_right = 458.0 -offset_bottom = 126.0 -grow_horizontal = 1 -grow_vertical = 1 - -[node name="NewPresetButton" type="Button" parent="MarginContainer/VBoxContainer"] -unique_name_in_owner = true -custom_minimum_size = Vector2(200, 0) -layout_mode = 2 -offset_left = 129.0 -offset_top = 137.0 -offset_right = 329.0 -offset_bottom = 168.0 -size_flags_horizontal = 4 -text = "Create new preset" -icon = ExtResource("2_j26xt") - -[node name="NewPresetDialog" type="ConfirmationDialog" parent="."] -unique_name_in_owner = true -title = "Create new preset" - -[node name="MarginContainer" type="MarginContainer" parent="NewPresetDialog"] -offset_left = 8.0 -offset_top = 8.0 -offset_right = 192.0 -offset_bottom = 51.0 - -[node name="NewPresetName" type="LineEdit" parent="NewPresetDialog/MarginContainer"] -unique_name_in_owner = true -layout_mode = 2 -offset_top = 6.0 -offset_right = 184.0 -offset_bottom = 37.0 -grow_horizontal = 2 -grow_vertical = 2 -size_flags_vertical = 4 -placeholder_text = "New preset name" diff --git a/addons/scatter-4/src/scatter.gd b/addons/scatter-4/src/scatter.gd deleted file mode 100644 index 12474a7..0000000 --- a/addons/scatter-4/src/scatter.gd +++ /dev/null @@ -1,397 +0,0 @@ -@tool -extends Node3D - - -signal shape_changed -signal thread_completed -signal build_completed - - -# Includes -const ProtonScatter := preload("./scatter.gd") -const ProtonScatterDomain := preload("./common/domain.gd") -const ProtonScatterItem := preload("./scatter_item.gd") -const ProtonScatterModifierStack := preload("./stack/modifier_stack.gd") -const ProtonScatterPhysicsHelper := preload("./common/physics_helper.gd") -const ProtonScatterShape := preload("./scatter_shape.gd") -const ProtonScatterTransformList := preload("./common/transform_list.gd") -const ProtonScatterUtil := preload('./common/scatter_util.gd') - - -@export_category("ProtonScatter") - -@export_group("General") -@export var global_seed := 0: - set(val): - global_seed = val - rebuild() -@export var show_output_in_tree := false: - set(val): - show_output_in_tree = val - if output_root: - ProtonScatterUtil.enforce_output_root_owner(self) - -@export_group("Performance") -@export var use_instancing := true: - set(val): - use_instancing = val - full_rebuild(true) - -@export_group("Dependency") -@export var scatter_parent: NodePath: - set(val): - if not is_inside_tree(): - scatter_parent = val - return - - scatter_parent = NodePath() - if is_instance_valid(_dependency_parent): - _dependency_parent.build_completed.disconnect(rebuild) - _dependency_parent = null - - var node = get_node_or_null(val) - if not node: - return - - var type = node.get_script() - var scatter_type = get_script() - if type != scatter_type: - push_warning("ProtonScatter warning: Please select a ProtonScatter node as a parent dependency.") - return - - # TODO: Check for cyclic dependency - - scatter_parent = val - _dependency_parent = node - _dependency_parent.build_completed.connect(rebuild, CONNECT_DEFERRED) - - -@export_group("Debug", "dbg_") -@export var dbg_disable_thread := false - -var undo_redo # EditorUndoRedoManager - Can't type this, class not available outside the editor -var modifier_stack: ProtonScatterModifierStack: - set(val): - if modifier_stack: - if modifier_stack.value_changed.is_connected(rebuild): - modifier_stack.value_changed.disconnect(rebuild) - if modifier_stack.stack_changed.is_connected(rebuild): - modifier_stack.stack_changed.disconnect(rebuild) - if modifier_stack.transforms_ready.is_connected(_on_transforms_ready): - modifier_stack.transforms_ready.disconnect(_on_transforms_ready) - - modifier_stack = val.get_copy() # Enfore uniqueness - modifier_stack.value_changed.connect(rebuild, CONNECT_DEFERRED) - modifier_stack.stack_changed.connect(rebuild, CONNECT_DEFERRED) - modifier_stack.transforms_ready.connect(_on_transforms_ready, CONNECT_DEFERRED) - -var domain: ProtonScatterDomain: - set(val): - domain = ProtonScatterDomain.new() # Enforce uniqueness - -var items: Array = [] -var total_item_proportion: int -var output_root: Marker3D - -var editor_plugin # Holds a reference to the EditorPlugin. Used by other parts. - -var _thread: Thread -var _rebuild_queued := false -var _dependency_parent -var _physics_helper: ProtonScatterPhysicsHelper -var _thread_just_started := false - - -func _exit_tree(): - if is_thread_running(): - _thread.wait_to_finish() - _thread = null - - -func _ready() -> void: - _perform_sanity_check() - set_notify_transform(true) - child_exiting_tree.connect(_on_child_exiting_tree) - - # Check if the required nodes exists, if not, create them. - _discover_items() - domain.discover_shapes(self) - - if items.is_empty(): - var item = ProtonScatterItem.new() - add_child(item, true) - item.set_name("ScatterItem") - item.set_owner(get_tree().get_edited_scene_root()) - - if domain.is_empty() and not modifier_stack.does_not_require_shapes(): - var shape = ProtonScatterShape.new() - add_child(shape, true) - shape.set_owner(get_tree().get_edited_scene_root()) - shape.set_name("ScatterShape") - - if not is_instance_valid(_dependency_parent): - print("in ", name, " calling full rebuild ") - full_rebuild.call_deferred() - - -func _get_property_list() -> Array: - var list := [] - list.push_back({ - name = "modifier_stack", - type = TYPE_OBJECT, - hint_string = "ScatterModifierStack", - }) - return list - - -func _get_configuration_warnings() -> PackedStringArray: - var warnings := PackedStringArray() - if items.is_empty(): - warnings.push_back("At least one ScatterItem node is required.") - if domain.is_empty(): - warnings.push_back("At least one ScatterShape node is required.") - return warnings - - -func _notification(what): - match what: - NOTIFICATION_TRANSFORM_CHANGED: - domain.compute_bounds() - rebuild() - - -func _set(property, _value): - if not Engine.is_editor_hint(): - return false - - # Workaround to detect when the node was duplicated from the editor. - if property == "transform": - _on_node_duplicated.call_deferred() - - return false - - -func is_thread_running() -> bool: - return _thread != null and _thread.is_started() - - -# Used by some modifiers to retrieve a physics helper node -func get_physics_helper() -> ProtonScatterPhysicsHelper: - if not is_instance_valid(_physics_helper): - _physics_helper = ProtonScatterPhysicsHelper.new() - add_child(_physics_helper) - - return _physics_helper - - -# Deletes what the Scatter node generated. -func clear_output() -> void: - if not output_root: - output_root = get_node_or_null("ScatterOutput") - - if output_root: - remove_child(output_root) - output_root.queue_free() - output_root = null - - ProtonScatterUtil.ensure_output_root_exists(self) - - -func full_rebuild(delayed := false): - if not is_inside_tree(): - return - - update_gizmos() - - if delayed: - await get_tree().process_frame - - if is_thread_running(): - _thread.wait_to_finish() - _thread = null - - clear_output() - _rebuild(true) - - -# A wrapper around the _rebuild function. Ensure it's not called more than once -# per frame. (Happens when the Scatter node is moved, which triggers the -# TRANSFORM_CHANGED notification in every children, which in turn notify the -# parent Scatter node back about the changes. -func rebuild(force_discover := false) -> void: - update_gizmos() - - if not is_inside_tree(): - return - - if is_thread_running(): - _rebuild_queued = true - return - - force_discover = true # TMP while we fix the other issues - _rebuild(force_discover) - - -# Re compute the desired output. -# This is the main function, scattering the objects in the scene. -# Scattered objects are stored under a Marker3D node called "ScatterOutput" -# DON'T call this function directly outside of the 'rebuild()' function above. -func _rebuild(force_discover) -> void: - if force_discover: - _discover_items() - domain.discover_shapes(self) - - if items.is_empty() or domain.is_empty(): - clear_output() - push_warning("ProtonScatter warning: No items or shapes, abort") - return - - if not use_instancing: - clear_output() # TMP, prevents raycasts in modifier to self intersect with previous output - - if dbg_disable_thread: - modifier_stack.start_update(self, domain) - return - - if _thread: - await _thread.wait_to_finish() - - _thread = Thread.new() - var update_function := modifier_stack.start_update.bind(self, domain.get_copy()) - _thread.start(update_function, Thread.PRIORITY_NORMAL) - - -func _discover_items() -> void: - items.clear() - total_item_proportion = 0 - - for c in get_children(): - if c is ProtonScatterItem: - items.push_back(c) - total_item_proportion += c.proportion - - if is_inside_tree(): - get_tree().node_configuration_warning_changed.emit(self) - - -# Creates one MultimeshInstance3D for each ScatterItem node. -func _update_multimeshes(transforms: ProtonScatterTransformList) -> void: - var offset := 0 - var transforms_count: int = transforms.size() - var inverse_transform := global_transform.affine_inverse() - - for item in items: - var item_root = ProtonScatterUtil.get_or_create_item_root(item) - var count = int(round(float(item.proportion) / total_item_proportion * transforms_count)) - var mmi = ProtonScatterUtil.get_or_create_multimesh(item, count) - if not mmi: - return - - var t: Transform3D - for i in count: - # Extra check because of how 'count' is calculated - if (offset + i) >= transforms_count: - mmi.multimesh.instance_count = i - 1 - return - - t = item.process_transform(transforms.list[offset + i]) - mmi.multimesh.set_instance_transform(i, inverse_transform * t) - - offset += count - - -func _update_duplicates(transforms: ProtonScatterTransformList) -> void: - var offset := 0 - var transforms_count: int = transforms.size() - var inverse_transform := global_transform.affine_inverse() - - for item in items: - var count = int(round(float(item.proportion) / total_item_proportion * transforms_count)) - var root = ProtonScatterUtil.get_or_create_item_root(item) - var child_count = root.get_child_count() - - for i in count: - if (offset + i) >= transforms_count: - return - - var instance - if i < child_count: # Grab an instance from the pool if there's one available - instance = root.get_child(i) - else: - instance = _create_instance(item, root) - - if not instance: - break - - var t: Transform3D = item.process_transform(transforms.list[offset + i]) - instance.transform = inverse_transform * t - - # Delete the unused instances left in the pool if any - if count < child_count: - for i in (child_count - count): - root.get_child(-1).queue_free() - - offset += count - - -func _create_instance(item: ProtonScatterItem, root: Node3D): - if not item or not item.get_item(): - return null - - var instance = item.get_item().duplicate() - instance.visible = true - root.add_child.bind(instance, true).call_deferred() - - if show_output_in_tree: - var defer_ownership := func(i, o): - ProtonScatterUtil.set_owner_recursive(i, o) - defer_ownership.bind(instance, get_tree().get_edited_scene_root()).call_deferred() - - return instance - - -# Enforce the Scatter node has its required variables set. -func _perform_sanity_check() -> void: - if not modifier_stack: - modifier_stack = ProtonScatterModifierStack.new() - - if not domain: - domain = ProtonScatterDomain.new() - - scatter_parent = scatter_parent - - -func _on_node_duplicated() -> void: - clear_output() # Otherwise we get linked multimeshes or other unwanted side effects - _perform_sanity_check() - - -func _on_child_exiting_tree(node: Node) -> void: - if node is ProtonScatterShape or node is ProtonScatterItem: - rebuild.bind(true).call_deferred() - - -# Called when the modifier stack is done generating the full transform list -func _on_transforms_ready(transforms: ProtonScatterTransformList) -> void: - if is_thread_running(): - _thread.wait_to_finish() - _thread = null - - if _rebuild_queued: - _rebuild_queued = false - rebuild.call_deferred() - return - - if not transforms or transforms.is_empty(): - clear_output() - update_gizmos() - return - - if use_instancing: - _update_multimeshes(transforms) - else: - _update_duplicates(transforms) - - update_gizmos() - await get_tree().process_frame - build_completed.emit() diff --git a/addons/scatter-4/src/scatter_gizmo_plugin.gd b/addons/scatter-4/src/scatter_gizmo_plugin.gd deleted file mode 100644 index 55dbd53..0000000 --- a/addons/scatter-4/src/scatter_gizmo_plugin.gd +++ /dev/null @@ -1,76 +0,0 @@ -@tool -extends EditorNode3DGizmoPlugin - - -# Gizmo plugin for the ProtonScatter nodes. -# -# Displays a loading animation when the node is rebuilding its output -# Also displays the domain edges if one of its modifiers is using this data. - - -const ProtonScatter := preload("./scatter.gd") -const LoadingAnimation := preload("../icons/loading/m_loading.tres") - -var _panel: Control -var _loading_mesh: Mesh - - -func _init(): - # TODO: Replace hardcoded colors by a setting fetch - create_custom_material("line", Color(0.2, 0.4, 0.8)) - add_material("loading", LoadingAnimation) - - _loading_mesh = QuadMesh.new() - _loading_mesh.set_size(Vector2.ONE * 0.15) - - -func _get_gizmo_name() -> String: - return "ProtonScatter" - - -func _has_gizmo(node) -> bool: - return node is ProtonScatter - - -func _redraw(gizmo: EditorNode3DGizmo): - gizmo.clear() - var node = gizmo.get_node_3d() - - if not node.modifier_stack: - return - - if node.is_thread_running(): - gizmo.add_mesh(_loading_mesh, get_material("loading")) - - if node.modifier_stack.is_using_edge_data(): - var curves: Array[Curve3D] = node.domain.get_edges() - var inverse_transform := node.get_global_transform().affine_inverse() - - for curve in curves: - var lines := PackedVector3Array() - var points: PackedVector3Array = curve.tessellate(4, 8) - var lines_count := points.size() - 1 - - for i in lines_count: - lines.append(inverse_transform * points[i]) - lines.append(inverse_transform * points[i + 1]) - - gizmo.add_lines(lines, get_material("line")) - - -func set_path_gizmo_panel(panel: Control) -> void: - _panel = panel - - -# WORKAROUND -# Creates a standard material displayed on top of everything. -# Only exists because 'create_material() on_top' parameter doesn't seem to work. -func create_custom_material(name, color := Color.WHITE): - var material := StandardMaterial3D.new() - material.set_blend_mode(StandardMaterial3D.BLEND_MODE_ADD) - material.set_shading_mode(StandardMaterial3D.SHADING_MODE_UNSHADED) - material.set_flag(StandardMaterial3D.FLAG_DISABLE_DEPTH_TEST, true) - material.set_albedo(color) - material.render_priority = 100 - - add_material(name, material) diff --git a/addons/scatter-4/src/scatter_item.gd b/addons/scatter-4/src/scatter_item.gd deleted file mode 100644 index d166f38..0000000 --- a/addons/scatter-4/src/scatter_item.gd +++ /dev/null @@ -1,121 +0,0 @@ -@tool -extends Node3D - - -const ScatterUtil := preload('./common/scatter_util.gd') - - -@export_category("ScatterItem") -@export var proportion := 100: - set(val): - proportion = val - ScatterUtil.request_parent_to_rebuild(self) - -@export_enum("From current scene", "From disk") var source = 1: - set(val): - source = val - property_list_changed.emit() - -@export_group("Source options", "source_") -@export var source_scale_multiplier := 1.0: - set(val): - source_scale_multiplier = val - ScatterUtil.request_parent_to_rebuild(self) - -@export var source_ignore_position := true: - set(val): - source_ignore_position = val - ScatterUtil.request_parent_to_rebuild(self) - -@export var source_ignore_rotation := true: - set(val): - source_ignore_rotation = val - ScatterUtil.request_parent_to_rebuild(self) - -@export var source_ignore_scale := true: - set(val): - source_ignore_scale = val - ScatterUtil.request_parent_to_rebuild(self) - -var path: String: - set(val): - path = val - _target_scene = load(path) if source != 0 else null - ScatterUtil.request_parent_to_rebuild(self) - -var source_position: Vector3 -var source_rotation: Vector3 -var source_scale: Vector3 - -var _target_scene: PackedScene - - -func _get_property_list() -> Array: - var list := [] - - if source == 0: - list.push_back({ - name = "path", - type = TYPE_NODE_PATH, - }) - else: - list.push_back({ - name = "path", - type = TYPE_STRING, - hint = PROPERTY_HINT_FILE, - }) - - return list - - -func get_item() -> Node3D: - if path.is_empty(): - print("in get item, path empty") - return null - - var node: Node3D - - if source == 0: - node = get_node_or_null(path) - else: - node = _target_scene.instantiate() - - if node: - _save_source_data(node) - return node - - return null - - -# Takes a transform in input, scale it based on the local scale multiplier -# If the source transform is not ignored, also copy the source position, rotation and scale. -# Returns the processed transform -func process_transform(t: Transform3D) -> Transform3D: - var origin = t.origin - t.origin = Vector3.ZERO - - t = t.scaled(Vector3.ONE * source_scale_multiplier) - - if not source_ignore_scale: - t = t.scaled(source_scale) - - if not source_ignore_rotation: - t = t.rotated(t.basis.x.normalized(), source_rotation.x) - t = t.rotated(t.basis.y.normalized(), source_rotation.y) - t = t.rotated(t.basis.z.normalized(), source_rotation.z) - - t.origin = origin - - if not source_ignore_position: - t.origin += source_position - - return t - - -func _save_source_data(node: Node3D) -> void: - if not node: - return - - source_position = node.position - source_rotation = node.rotation - source_scale = node.scale diff --git a/addons/scatter-4/src/scatter_shape.gd b/addons/scatter-4/src/scatter_shape.gd deleted file mode 100644 index 2f622e3..0000000 --- a/addons/scatter-4/src/scatter_shape.gd +++ /dev/null @@ -1,56 +0,0 @@ -@tool -extends Node3D - - -const ScatterUtil := preload('./common/scatter_util.gd') - - -@export_category("ScatterShape") -@export var negative = false: - set(val): - negative = val - update_gizmos() - ScatterUtil.request_parent_to_rebuild(self) - -@export var shape: ProtonScatterBaseShape: - set(val): - # Disconnect the previous shape if any - if shape and shape.changed.is_connected(_on_shape_changed): - shape.changed.disconnect(_on_shape_changed) - - shape = val - if shape: - shape.changed.connect(_on_shape_changed) - - update_gizmos() - ScatterUtil.request_parent_to_rebuild(self) - - -func _ready() -> void: - set_notify_transform(true) - - -func _notification(what): - match what: - NOTIFICATION_TRANSFORM_CHANGED: - ScatterUtil.request_parent_to_rebuild(self) - - -func _set(property, _value): - if not Engine.is_editor_hint(): - return false - - # Workaround to detect when the node was duplicated from the editor. - if property == "transform": - call_deferred("_on_node_duplicated") - - return false - - -func _on_shape_changed() -> void: - update_gizmos() - ScatterUtil.request_parent_to_rebuild(self) - - -func _on_node_duplicated() -> void: - shape = shape.get_copy() # Enfore uniqueness on duplicate, could be an option diff --git a/addons/scatter-4/src/shapes/base_shape.gd b/addons/scatter-4/src/shapes/base_shape.gd deleted file mode 100644 index 775812c..0000000 --- a/addons/scatter-4/src/shapes/base_shape.gd +++ /dev/null @@ -1,33 +0,0 @@ -@tool -class_name ProtonScatterBaseShape -extends Resource - - -func is_point_inside(point_global: Vector3, global_transform: Transform3D) -> bool: - return false - - -# Returns an array of Vector3. This should contain enough points to compute -# a bounding box for the given shape. -func get_corners_global(shape_global_transform: Transform3D) -> Array[Vector3]: - return [] - - -# Returns the closed contour of the shape (closed, inner and outer if -# applicable) as a 2D polygon. -# Results in local space relative to the scatter node. -func get_closed_edges(scatter_gt: Transform3D, shape_gt: Transform3D) -> Array[PackedVector2Array]: - return [] - - -# Returns the open edges (in the case of a regular path, not closed) -# in local space relative to the scatter node. -func get_open_edges(scatter_gt: Transform3D, shape_gt: Transform3D) -> Array[Curve3D]: - return [] - - -# Returns a copy of this shape. -# TODO: check later when Godot4 enters beta if we can get rid of this and use -# the built-in duplicate() method properly. -func get_copy() -> Resource: - return null diff --git a/addons/scatter-4/src/shapes/box_shape.gd b/addons/scatter-4/src/shapes/box_shape.gd deleted file mode 100644 index 1cc2ead..0000000 --- a/addons/scatter-4/src/shapes/box_shape.gd +++ /dev/null @@ -1,101 +0,0 @@ -@tool -class_name ProtonScatterBoxShape -extends ProtonScatterBaseShape - - -@export var size := Vector3.ONE: - set(val): - size = val - _half_size = size * 0.5 - emit_changed() - -var _half_size := Vector3.ONE - - -func get_copy(): - var copy = get_script().new() - copy.size = size - return copy - - -func is_point_inside(point: Vector3, global_transform: Transform3D) -> bool: - var position = global_transform * -_half_size - var local_point = global_transform.affine_inverse() * point - return AABB(-_half_size, size).has_point(local_point) - - -func get_corners_global(gt: Transform3D) -> Array: - var res := [] - var corners := [ - Vector3(-1, -1, -1), - Vector3(-1, -1, 1), - Vector3(1, -1, 1), - Vector3(1, -1, -1), - Vector3(-1, 1, -1), - Vector3(-1, 1, 1), - Vector3(1, 1, 1), - Vector3(1, 1, -1), - ] - - for c in corners: - c *= size * 0.5 - res.push_back(gt * c) - - return res - - -# Intersection between and box and a plane results in a polygon between 3 and 6 -# vertices. -# Compute the intersection of each of the 12 edges to the plane, then recompute -# the polygon from the positions found. -func get_closed_edges(scatter_gt: Transform3D, shape_gt: Transform3D) -> Array[PackedVector2Array]: - var polygon := PackedVector2Array() - - var a = scatter_gt.basis.x - var b = scatter_gt.basis.z - var c = a + b - var o = scatter_gt.origin - var plane = Plane(a + o, b + o, c + o) - - var box_edges := [ - # Bottom square - [Vector3(-1, -1, -1), Vector3(-1, -1, 1)], - [Vector3(-1, -1, 1), Vector3(1, -1, 1)], - [Vector3(1, -1, 1), Vector3(1, -1, -1)], - [Vector3(1, -1, -1), Vector3(-1, -1, -1)], - - # Top square - [Vector3(-1, 1, -1), Vector3(-1, 1, 1)], - [Vector3(-1, 1, 1), Vector3(1, 1, 1)], - [Vector3(1, 1, 1), Vector3(1, 1, -1)], - [Vector3(1, 1, -1), Vector3(-1, 1, -1)], - - # Vertical lines - [Vector3(-1, -1, -1), Vector3(-1, 1, -1)], - [Vector3(-1, -1, 1), Vector3(-1, 1, 1)], - [Vector3(1, -1, 1), Vector3(1, 1, 1)], - [Vector3(1, -1, -1), Vector3(1, 1, -1)], - ] - - var intersection_points := PackedVector3Array() - var point - var gt_inverse := scatter_gt.affine_inverse() - var shape_gt_inverse := shape_gt.affine_inverse() - - for edge in box_edges: - var p1 = (edge[0] * _half_size) * shape_gt_inverse - var p2 = (edge[1] * _half_size) * shape_gt_inverse - point = plane.intersects_segment(p1, p2) - if point: - intersection_points.push_back(gt_inverse * point) - - if intersection_points.size() < 3: - return [] - - var points_unordered := PackedVector2Array() - for p in intersection_points: - points_unordered.push_back(Vector2(p.x, p.z)) - - polygon = Geometry2D.convex_hull(points_unordered) - - return [polygon] diff --git a/addons/scatter-4/src/shapes/gizmos_plugin/box_gizmo.gd b/addons/scatter-4/src/shapes/gizmos_plugin/box_gizmo.gd deleted file mode 100644 index 504894f..0000000 --- a/addons/scatter-4/src/shapes/gizmos_plugin/box_gizmo.gd +++ /dev/null @@ -1,135 +0,0 @@ -@tool -extends "gizmo_handler.gd" - -# 3D Gizmo for the Box shape. - - -func get_handle_name(_gizmo: EditorNode3DGizmo, _handle_id: int, _secondary: bool) -> String: - return "Box Size" - - -func get_handle_value(gizmo: EditorNode3DGizmo, handle_id: int, _secondary: bool) -> Variant: - return gizmo.get_node_3d().shape.size - - -func set_handle(gizmo: EditorNode3DGizmo, handle_id: int, _secondary: bool, camera: Camera3D, screen_pos: Vector2) -> void: - if handle_id < 0 or handle_id > 2: - return - - var axis := Vector3.ZERO - axis[handle_id] = 1.0 # handle 0:x, 1:y, 2:z - - var shape_node = gizmo.get_node_3d() - var gt := shape_node.get_global_transform() - var gt_inverse := gt.affine_inverse() - - var origin := gt.origin - var drag_axis := (axis * 4096) * gt_inverse - var ray_from = camera.project_ray_origin(screen_pos) - var ray_to = ray_from + camera.project_ray_normal(screen_pos) * 4096 - - var points = Geometry3D.get_closest_points_between_segments(origin, drag_axis, ray_from, ray_to) - - var size = shape_node.shape.size - size -= axis * size - var dist = origin.distance_to(points[0]) * 2.0 - size += axis * dist - - shape_node.shape.size = size - - -func commit_handle(gizmo: EditorNode3DGizmo, handle_id: int, _secondary: bool, restore: Variant, cancel: bool) -> void: - var shape: ProtonScatterBoxShape = gizmo.get_node_3d().shape - if cancel: - shape.size = restore - return - - _undo_redo.create_action("Set ScatterShape size") - _undo_redo.add_undo_method(self, "_set_size", shape, restore) - _undo_redo.add_do_method(self, "_set_size", shape, shape.size) - _undo_redo.commit_action() - - -func redraw(plugin: EditorNode3DGizmoPlugin, gizmo: EditorNode3DGizmo): - gizmo.clear() - var scatter_shape = gizmo.get_node_3d() - var shape: ProtonScatterBoxShape = scatter_shape.shape - - ### Draw the Box lines - var lines = PackedVector3Array() - var lines_material := plugin.get_material("primary_top", gizmo) - var half_size = shape.size * 0.5 - - var corners := [ - [ # Bottom square - Vector3(-1, -1, -1), - Vector3(-1, -1, 1), - Vector3(1, -1, 1), - Vector3(1, -1, -1), - Vector3(-1, -1, -1), - ], - [ # Top square - Vector3(-1, 1, -1), - Vector3(-1, 1, 1), - Vector3(1, 1, 1), - Vector3(1, 1, -1), - Vector3(-1, 1, -1), - ], - [ # Vertical lines - Vector3(-1, -1, -1), - Vector3(-1, 1, -1), - ], - [ - Vector3(-1, -1, 1), - Vector3(-1, 1, 1), - ], - [ - Vector3(1, -1, 1), - Vector3(1, 1, 1), - ], - [ - Vector3(1, -1, -1), - Vector3(1, 1, -1), - ] - ] - - var block_count = corners.size() - if not is_selected(gizmo): - block_count = 1 - - for i in block_count: - var block = corners[i] - for j in block.size() - 1: - lines.push_back(block[j] * half_size) - lines.push_back(block[j + 1] * half_size) - - gizmo.add_lines(lines, lines_material) - gizmo.add_collision_segments(lines) - - ### Fills the box inside - var mesh = BoxMesh.new() - mesh.size = shape.size - - var mesh_material: StandardMaterial3D - if scatter_shape.negative: - mesh_material = plugin.get_material("exclusive", gizmo) - else: - mesh_material = plugin.get_material("inclusive", gizmo) - - gizmo.add_mesh(mesh, mesh_material) - - ### Draw the handles, one for each axis - var handles := PackedVector3Array() - var handles_ids := PackedInt32Array() - var handles_material := plugin.get_material("default_handle", gizmo) - - handles.push_back(Vector3.RIGHT * shape.size.x * 0.5) - handles.push_back(Vector3.UP * shape.size.y * 0.5) - handles.push_back(Vector3.BACK * shape.size.z * 0.5) - - gizmo.add_handles(handles, handles_material, handles_ids) - - -func _set_size(box: ProtonScatterBoxShape, size: Vector3) -> void: - if box: - box.size = size diff --git a/addons/scatter-4/src/shapes/gizmos_plugin/components/curve_mode_button_group.tres b/addons/scatter-4/src/shapes/gizmos_plugin/components/curve_mode_button_group.tres deleted file mode 100644 index f8a67d2..0000000 --- a/addons/scatter-4/src/shapes/gizmos_plugin/components/curve_mode_button_group.tres +++ /dev/null @@ -1,3 +0,0 @@ -[gd_resource type="ButtonGroup" format=3 uid="uid://1xy55037k3k5"] - -[resource] diff --git a/addons/scatter-4/src/shapes/gizmos_plugin/components/path_advanced_options_panel.tscn b/addons/scatter-4/src/shapes/gizmos_plugin/components/path_advanced_options_panel.tscn deleted file mode 100644 index c5a44f0..0000000 --- a/addons/scatter-4/src/shapes/gizmos_plugin/components/path_advanced_options_panel.tscn +++ /dev/null @@ -1,55 +0,0 @@ -[gd_scene format=3 uid="uid://qb8j7oasuqbc"] - -[node name="AdvancedOptionsPanel" type="MarginContainer"] -offset_right = 221.0 -offset_bottom = 136.0 -grow_horizontal = 2 -size_flags_horizontal = 4 -size_flags_vertical = 4 -metadata/_edit_use_custom_anchors = true - -[node name="HBoxContainer" type="HBoxContainer" parent="."] -offset_right = 221.0 -offset_bottom = 136.0 - -[node name="VBoxContainer" type="VBoxContainer" parent="HBoxContainer"] -offset_right = 217.0 -offset_bottom = 136.0 - -[node name="MirrorLength" type="CheckButton" parent="HBoxContainer/VBoxContainer"] -offset_right = 217.0 -offset_bottom = 31.0 -focus_mode = 0 -text = "Mirror handles length" - -[node name="MirrorAngle" type="CheckButton" parent="HBoxContainer/VBoxContainer"] -offset_top = 35.0 -offset_right = 217.0 -offset_bottom = 66.0 -focus_mode = 0 -text = "Mirror handles angle" - -[node name="LockToPlane" type="CheckButton" parent="HBoxContainer/VBoxContainer"] -offset_top = 70.0 -offset_right = 217.0 -offset_bottom = 101.0 -focus_mode = 0 -text = "Lock to plane" - -[node name="MirrorAngle3" type="CheckButton" parent="HBoxContainer/VBoxContainer"] -offset_top = 105.0 -offset_right = 217.0 -offset_bottom = 136.0 -focus_mode = 0 -text = "Snap to colliders" - -[node name="VSeparator" type="VSeparator" parent="HBoxContainer"] -visible = false -offset_left = 221.0 -offset_right = 225.0 -offset_bottom = 136.0 - -[node name="VBoxContainer2" type="VBoxContainer" parent="HBoxContainer"] -offset_left = 221.0 -offset_right = 221.0 -offset_bottom = 136.0 diff --git a/addons/scatter-4/src/shapes/gizmos_plugin/components/path_panel.gd b/addons/scatter-4/src/shapes/gizmos_plugin/components/path_panel.gd deleted file mode 100644 index 9d0b735..0000000 --- a/addons/scatter-4/src/shapes/gizmos_plugin/components/path_panel.gd +++ /dev/null @@ -1,96 +0,0 @@ -@tool -extends Control - - -const ScatterShape = preload("../../../scatter_shape.gd") -const PathShape = preload("../../path_shape.gd") - -var shape_node: ScatterShape - -@onready var _options_button: Button = $%Options -@onready var _options_panel: Popup = $%OptionsPanel - - -func _ready() -> void: - _options_button.toggled.connect(_on_options_button_toggled) - _options_panel.popup_hide.connect(_on_options_panel_hide) - $%SnapToColliders.toggled.connect(_on_snap_to_colliders_toggled) - $%ClosedPath.toggled.connect(_on_closed_path_toggled) - $%MirrorAngle.toggled.connect(_on_mirror_angle_toggled) - - for button in [$%LockToPlane, $%SnapToColliders, $%ClosedPath]: - button.pressed.connect(_on_button_pressed) - - -# Called by the editor plugin when the node selection changes. -# Hides the panel when the selected node is not a path shape. -func selection_changed(selected: Array) -> void: - if selected.is_empty(): - visible = false - shape_node = null - return - - var node = selected[0] - visible = node is ScatterShape and node.shape is PathShape - if visible: - shape_node = node - $%ClosedPath.button_pressed = node.shape.closed - - -func is_select_mode_enabled() -> bool: - return $%Select.button_pressed - - -func is_create_mode_enabled() -> bool: - return $%Create.button_pressed - - -func is_delete_mode_enabled() -> bool: - return $%Delete.button_pressed - - -func is_lock_to_plane_enabled() -> bool: - return $%LockToPlane.button_pressed and not is_snap_to_colliders_enabled() - - -func is_snap_to_colliders_enabled() -> bool: - return $%SnapToColliders.button_pressed - - -func is_mirror_length_enabled() -> bool: - return $%MirrorLength.button_pressed - - -func is_mirror_angle_enabled() -> bool: - return $%MirrorAngle.button_pressed - - -func _on_options_button_toggled(enabled: bool) -> void: - if enabled: - var popup_position := Vector2i(get_global_transform().origin) - popup_position.y += size.y + 12 - _options_panel.popup(Rect2i(popup_position, Vector2i.ZERO)) - else: - _options_panel.hide() - - -func _on_options_panel_hide() -> void: - _options_button.button_pressed = false - - -func _on_mirror_angle_toggled(enabled: bool) -> void: - $%MirrorLength.disabled = not enabled - - -func _on_snap_to_colliders_toggled(enabled: bool) -> void: - $%LockToPlane.disabled = enabled - - -func _on_closed_path_toggled(enabled: bool) -> void: - if shape_node and shape_node.shape is PathShape: - shape_node.shape.closed = enabled - - -func _on_button_pressed() -> void: - if shape_node: - shape_node.update_gizmos() diff --git a/addons/scatter-4/src/shapes/gizmos_plugin/components/path_panel.tscn b/addons/scatter-4/src/shapes/gizmos_plugin/components/path_panel.tscn deleted file mode 100644 index 01898cc..0000000 --- a/addons/scatter-4/src/shapes/gizmos_plugin/components/path_panel.tscn +++ /dev/null @@ -1,163 +0,0 @@ -[gd_scene load_steps=7 format=3 uid="uid://vijpujrvtyin"] - -[ext_resource type="Script" path="res://addons/proton_scatter/src/shapes/gizmos_plugin/components/path_panel.gd" id="1_o7kkg"] -[ext_resource type="Texture2D" uid="uid://b2b62ko7v686h" path="res://addons/proton_scatter/icons/curve_select.svg" id="2_d7o1n"] -[ext_resource type="ButtonGroup" uid="uid://1xy55037k3k5" path="res://addons/proton_scatter/src/shapes/gizmos_plugin/components/curve_mode_button_group.tres" id="2_sl6yo"] -[ext_resource type="Texture2D" uid="uid://c31odatai1367" path="res://addons/proton_scatter/icons/curve_create.svg" id="3_l70sn"] -[ext_resource type="Texture2D" uid="uid://pog84tx0x6ka" path="res://addons/proton_scatter/icons/curve_delete.svg" id="4_b5yum"] -[ext_resource type="Texture2D" uid="uid://n66mufjib4ds" path="res://addons/proton_scatter/icons/menu.svg" id="6_xiaj2"] - -[node name="PathPanel" type="MarginContainer"] -offset_right = 108.0 -offset_bottom = 24.0 -size_flags_horizontal = 0 -size_flags_vertical = 4 -script = ExtResource("1_o7kkg") - -[node name="HBoxContainer" type="HBoxContainer" parent="."] -layout_mode = 2 -offset_right = 108.0 -offset_bottom = 24.0 -size_flags_horizontal = 4 -size_flags_vertical = 4 - -[node name="HBoxContainer" type="HBoxContainer" parent="HBoxContainer"] -layout_mode = 2 -offset_right = 80.0 -offset_bottom = 24.0 - -[node name="Select" type="Button" parent="HBoxContainer/HBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 -offset_right = 24.0 -offset_bottom = 24.0 -focus_mode = 0 -toggle_mode = true -button_pressed = true -button_group = ExtResource("2_sl6yo") -icon = ExtResource("2_d7o1n") -flat = true -icon_alignment = 1 - -[node name="Create" type="Button" parent="HBoxContainer/HBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 -offset_left = 28.0 -offset_right = 52.0 -offset_bottom = 24.0 -focus_mode = 0 -toggle_mode = true -button_group = ExtResource("2_sl6yo") -icon = ExtResource("3_l70sn") -flat = true -icon_alignment = 1 - -[node name="Delete" type="Button" parent="HBoxContainer/HBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 -offset_left = 56.0 -offset_right = 80.0 -offset_bottom = 24.0 -focus_mode = 0 -toggle_mode = true -button_group = ExtResource("2_sl6yo") -icon = ExtResource("4_b5yum") -flat = true -icon_alignment = 1 - -[node name="Options" type="Button" parent="HBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 -offset_left = 84.0 -offset_right = 108.0 -offset_bottom = 24.0 -focus_mode = 0 -toggle_mode = true -action_mode = 0 -icon = ExtResource("6_xiaj2") -flat = true -icon_alignment = 1 - -[node name="OptionsPanel" type="PopupPanel" parent="."] -unique_name_in_owner = true -size = Vector2i(229, 179) - -[node name="AdvancedOptionsPanel" type="MarginContainer" parent="OptionsPanel"] -offset_left = 4.0 -offset_top = 4.0 -offset_right = 225.0 -offset_bottom = 175.0 -grow_horizontal = 2 -size_flags_horizontal = 4 -size_flags_vertical = 4 -metadata/_edit_use_custom_anchors = true - -[node name="HBoxContainer" type="HBoxContainer" parent="OptionsPanel/AdvancedOptionsPanel"] -layout_mode = 2 -offset_right = 221.0 -offset_bottom = 171.0 - -[node name="VBoxContainer" type="VBoxContainer" parent="OptionsPanel/AdvancedOptionsPanel/HBoxContainer"] -layout_mode = 2 -offset_right = 217.0 -offset_bottom = 171.0 - -[node name="MirrorAngle" type="CheckButton" parent="OptionsPanel/AdvancedOptionsPanel/HBoxContainer/VBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 -offset_right = 217.0 -offset_bottom = 31.0 -focus_mode = 0 -button_pressed = true -text = "Mirror handles angle" - -[node name="MirrorLength" type="CheckButton" parent="OptionsPanel/AdvancedOptionsPanel/HBoxContainer/VBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 -offset_top = 35.0 -offset_right = 217.0 -offset_bottom = 66.0 -focus_mode = 0 -button_pressed = true -text = "Mirror handles length" - -[node name="ClosedPath" type="CheckButton" parent="OptionsPanel/AdvancedOptionsPanel/HBoxContainer/VBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 -offset_top = 70.0 -offset_right = 217.0 -offset_bottom = 101.0 -focus_mode = 0 -text = "Closed path" - -[node name="LockToPlane" type="CheckButton" parent="OptionsPanel/AdvancedOptionsPanel/HBoxContainer/VBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 -offset_top = 105.0 -offset_right = 217.0 -offset_bottom = 136.0 -focus_mode = 0 -button_pressed = true -text = "Lock to plane" - -[node name="SnapToColliders" type="CheckButton" parent="OptionsPanel/AdvancedOptionsPanel/HBoxContainer/VBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 -offset_top = 140.0 -offset_right = 217.0 -offset_bottom = 171.0 -focus_mode = 0 -text = "Snap to colliders" - -[node name="VSeparator" type="VSeparator" parent="OptionsPanel/AdvancedOptionsPanel/HBoxContainer"] -visible = false -layout_mode = 2 -offset_left = 221.0 -offset_right = 225.0 -offset_bottom = 136.0 - -[node name="VBoxContainer2" type="VBoxContainer" parent="OptionsPanel/AdvancedOptionsPanel/HBoxContainer"] -layout_mode = 2 -offset_left = 221.0 -offset_right = 221.0 -offset_bottom = 171.0 diff --git a/addons/scatter-4/src/shapes/gizmos_plugin/gizmo_handler.gd b/addons/scatter-4/src/shapes/gizmos_plugin/gizmo_handler.gd deleted file mode 100644 index cfc8bfd..0000000 --- a/addons/scatter-4/src/shapes/gizmos_plugin/gizmo_handler.gd +++ /dev/null @@ -1,50 +0,0 @@ -@tool -extends RefCounted - -# Abstract class. - - -var _undo_redo: EditorUndoRedoManager -var _plugin: EditorPlugin - - -func set_undo_redo(ur: EditorUndoRedoManager) -> void: - _undo_redo = ur - - -func set_editor_plugin(plugin: EditorPlugin) -> void: - _plugin = plugin - - -func get_handle_name(gizmo: EditorNode3DGizmo, handle_id: int, secondary: bool) -> String: - return "" - - -func get_handle_value(gizmo: EditorNode3DGizmo, handle_id: int, secondary: bool) -> Variant: - return null - - -func set_handle(gizmo: EditorNode3DGizmo, handle_id: int, secondary: bool, camera: Camera3D, screen_pos: Vector2) -> void: - pass - - -func commit_handle(gizmo: EditorNode3DGizmo, handle_id: int, secondary: bool, restore: Variant, cancel: bool) -> void: - pass - - -func redraw(plugin: EditorNode3DGizmoPlugin, gizmo: EditorNode3DGizmo): - pass - - -func forward_3d_gui_input(viewport_camera: Camera3D, event: InputEvent) -> bool: - return false - - -func is_selected(gizmo: EditorNode3DGizmo) -> bool: - if not _plugin: - return true - - var current_node = gizmo.get_node_3d() - var selected_nodes := _plugin.get_editor_interface().get_selection().get_selected_nodes() - - return current_node in selected_nodes diff --git a/addons/scatter-4/src/shapes/gizmos_plugin/icons/main_handle.svg b/addons/scatter-4/src/shapes/gizmos_plugin/icons/main_handle.svg deleted file mode 100644 index d4bd434..0000000 --- a/addons/scatter-4/src/shapes/gizmos_plugin/icons/main_handle.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/addons/scatter-4/src/shapes/gizmos_plugin/icons/secondary_handle.svg b/addons/scatter-4/src/shapes/gizmos_plugin/icons/secondary_handle.svg deleted file mode 100644 index 1bdf32d..0000000 --- a/addons/scatter-4/src/shapes/gizmos_plugin/icons/secondary_handle.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/addons/scatter-4/src/shapes/gizmos_plugin/path_gizmo.gd b/addons/scatter-4/src/shapes/gizmos_plugin/path_gizmo.gd deleted file mode 100644 index 823311a..0000000 --- a/addons/scatter-4/src/shapes/gizmos_plugin/path_gizmo.gd +++ /dev/null @@ -1,356 +0,0 @@ -@tool -extends "gizmo_handler.gd" - - -const ProtonScatter := preload("res://addons/proton_scatter/src/scatter.gd") -const ProtonScatterShape := preload("res://addons/proton_scatter/src/scatter_shape.gd") -const ProtonScatterEventHelper := preload("res://addons/proton_scatter/src/common/event_helper.gd") -const PathPanel := preload("./components/path_panel.gd") - -var _gizmo_panel: PathPanel -var _event_helper: ProtonScatterEventHelper - - -func get_handle_name(_gizmo: EditorNode3DGizmo, _handle_id: int, _secondary: bool) -> String: - return "Path point" - - -func get_handle_value(gizmo: EditorNode3DGizmo, _handle_id: int, _secondary: bool) -> Variant: - var shape: ProtonScatterPathShape = gizmo.get_node_3d().shape - return shape.get_copy() - - -func set_handle(gizmo: EditorNode3DGizmo, handle_id: int, secondary: bool, camera: Camera3D, screen_pos: Vector2) -> void: - if not _gizmo_panel.is_select_mode_enabled(): - return - - var shape_node: ProtonScatterShape = gizmo.get_node_3d() - var curve: Curve3D = shape_node.shape.curve - var point_count: int = curve.get_point_count() - var curve_index := handle_id - var previous_handle_position: Vector3 - - if not secondary: - previous_handle_position = curve.get_point_position(curve_index) - else: - curve_index = int(handle_id / 2) - previous_handle_position = curve.get_point_position(curve_index) - if handle_id % 2 == 0: - previous_handle_position += curve.get_point_in(curve_index) - else: - previous_handle_position += curve.get_point_out(curve_index) - - var click_world_position := _intersect_with(shape_node, camera, screen_pos, previous_handle_position) - var point_local_position: Vector3 = shape_node.get_global_transform().affine_inverse() * click_world_position - - if not secondary: - # Main curve point moved - curve.set_point_position(handle_id, point_local_position) - else: - # In out handle moved - var mirror_angle := _gizmo_panel.is_mirror_angle_enabled() - var mirror_length := _gizmo_panel.is_mirror_length_enabled() - - var point_origin = curve.get_point_position(curve_index) - var in_out_position = point_local_position - point_origin - var mirror_position = -in_out_position - - if handle_id % 2 == 0: - curve.set_point_in(curve_index, in_out_position) - if mirror_angle: - if not mirror_length: - mirror_position = curve.get_point_out(curve_index).length() * -in_out_position.normalized() - curve.set_point_out(curve_index, mirror_position) - else: - curve.set_point_out(curve_index, in_out_position) - if mirror_angle: - if not mirror_length: - mirror_position = curve.get_point_in(curve_index).length() * -in_out_position.normalized() - curve.set_point_in(curve_index, mirror_position) - - shape_node.update_gizmos() - - -func commit_handle(gizmo: EditorNode3DGizmo, _handle_id: int, _secondary: bool, restore: Variant, cancel: bool) -> void: - var shape_node: ProtonScatterShape = gizmo.get_node_3d() - - if cancel: - _edit_path(shape_node, restore) - else: - _undo_redo.create_action("Edit ScatterShape Path") - _undo_redo.add_undo_method(self, "_edit_path", shape_node, restore) - _undo_redo.add_do_method(self, "_edit_path", shape_node, shape_node.shape.get_copy()) - _undo_redo.commit_action() - - shape_node.update_gizmos() - - -func redraw(plugin: EditorNode3DGizmoPlugin, gizmo: EditorNode3DGizmo): - gizmo.clear() - - # Force the path panel to appear when the scatter shape type is changed - # from the inspector. - if is_selected(gizmo): - _gizmo_panel.selection_changed([gizmo.get_node_3d()]) - - var shape_node: ProtonScatterShape = gizmo.get_node_3d() - var shape: ProtonScatterPathShape = shape_node.shape - - if not shape: - return - - var curve: Curve3D = shape.curve - if not curve or curve.get_point_count() == 0: - return - - # ------ Common stuff ------ - var points := curve.tessellate(4, 8) - var points_2d := PackedVector2Array() - for p in points: - points_2d.push_back(Vector2(p.x, p.z)) - - var line_material: StandardMaterial3D = plugin.get_material("primary_top", gizmo) - var mesh_material: StandardMaterial3D = plugin.get_material("inclusive", gizmo) - if shape_node.negative: - mesh_material = plugin.get_material("exclusive", gizmo) - - # ------ Main line along the path curve ------ - var lines := PackedVector3Array() - var lines_count := points.size() - 1 - - for i in lines_count: - lines.append(points[i]) - lines.append(points[i + 1]) - - gizmo.add_lines(lines, line_material) - gizmo.add_collision_segments(lines) - - # ------ Draw handles ------ - var main_handles := PackedVector3Array() - var in_out_handles := PackedVector3Array() - var handle_lines := PackedVector3Array() - var ids := PackedInt32Array() # Stays empty on purpose - - for i in curve.get_point_count(): - var point_pos = curve.get_point_position(i) - var point_in = curve.get_point_in(i) + point_pos - var point_out = curve.get_point_out(i) + point_pos - - handle_lines.push_back(point_pos) - handle_lines.push_back(point_in) - handle_lines.push_back(point_pos) - handle_lines.push_back(point_out) - - in_out_handles.push_back(point_in) - in_out_handles.push_back(point_out) - main_handles.push_back(point_pos) - - gizmo.add_handles(main_handles, plugin.get_material("primary_handle", gizmo), ids) - gizmo.add_handles(in_out_handles, plugin.get_material("secondary_handle", gizmo), ids, false, true) - - if is_selected(gizmo): - gizmo.add_lines(handle_lines, plugin.get_material("secondary_top", gizmo)) - - # -------- Visual when lock to plane is enabled -------- - if _gizmo_panel.is_lock_to_plane_enabled() and is_selected(gizmo): - var bounds = shape.get_bounds() - var aabb = AABB(bounds.min, bounds.size).grow(shape.thickness / 2.0) - - var width: float = aabb.size.x - var length: float = aabb.size.z - var plane_center: Vector3 = bounds.center - plane_center.y = 0.0 - - var plane_mesh := PlaneMesh.new() - plane_mesh.set_size(Vector2(width, length)) - plane_mesh.set_center_offset(plane_center) - - gizmo.add_mesh(plane_mesh, plugin.get_material("tertiary", gizmo)) - - var plane_lines := PackedVector3Array() - var corners = [ - Vector3(-width, 0, -length), - Vector3(-width, 0, length), - Vector3(width, 0, length), - Vector3(width, 0, -length), - Vector3(-width, 0, -length), - ] - for i in corners.size() - 1: - plane_lines.push_back(corners[i] * 0.5 + plane_center) - plane_lines.push_back(corners[i + 1] * 0.5 + plane_center) - - gizmo.add_lines(plane_lines, plugin.get_material("secondary_top", gizmo)) - - # ----- Mesh representing the inside part of the path ----- - if shape.closed: - var indices = Geometry2D.triangulate_polygon(points_2d) - if indices.is_empty(): - indices = Geometry2D.triangulate_delaunay(points_2d) - - var st = SurfaceTool.new() - st.begin(Mesh.PRIMITIVE_TRIANGLES) - for index in indices: - var p = points_2d[index] - st.add_vertex(Vector3(p.x, 0.0, p.y)) - - var mesh = st.commit() - gizmo.add_mesh(mesh, mesh_material) - - # ------ Mesh representing path thickness ------ - if shape.thickness > 0 and points.size() > 1: - - # ____ TODO ____ : check if this whole section could be replaced by - # Geometry2D.expand_polyline, or an extruded capsule along the path - - ## Main path mesh - var st = SurfaceTool.new() - st.begin(Mesh.PRIMITIVE_TRIANGLE_STRIP) - - for i in points.size() - 1: - var p1: Vector3 = points[i] - var p2: Vector3 = points[i + 1] - - var normal = (p2 - p1).cross(Vector3.UP).normalized() - var offset = normal * shape.thickness * 0.5 - - st.add_vertex(p1 - offset) - st.add_vertex(p1 + offset) - - ## Add the last missing two triangles from the loop above - var p1: Vector3 = points[-1] - var p2: Vector3 = points[-2] - var normal = (p1 - p2).cross(Vector3.UP).normalized() - var offset = normal * shape.thickness * 0.5 - - st.add_vertex(p1 - offset) - st.add_vertex(p1 + offset) - - var mesh := st.commit() - gizmo.add_mesh(mesh, mesh_material) - - ## Rounded cap (start) - st.begin(Mesh.PRIMITIVE_TRIANGLES) - var center = points[0] - var next = points[1] - normal = (center - next).cross(Vector3.UP).normalized() - - for i in 12: - st.add_vertex(center) - st.add_vertex(center + normal * shape.thickness * 0.5) - normal = normal.rotated(Vector3.UP, PI / 12) - st.add_vertex(center + normal * shape.thickness * 0.5) - - mesh = st.commit() - gizmo.add_mesh(mesh, mesh_material) - - ## Rounded cap (end) - st.begin(Mesh.PRIMITIVE_TRIANGLES) - center = points[-1] - next = points[-2] - normal = (next - center).cross(Vector3.UP).normalized() - - for i in 12: - st.add_vertex(center) - st.add_vertex(center + normal * shape.thickness * 0.5) - normal = normal.rotated(Vector3.UP, -PI / 12) - st.add_vertex(center + normal * shape.thickness * 0.5) - - mesh = st.commit() - gizmo.add_mesh(mesh, mesh_material) - - -func forward_3d_gui_input(viewport_camera: Camera3D, event: InputEvent) -> bool: - if not _event_helper: - _event_helper = ProtonScatterEventHelper.new() - - _event_helper.feed(event) - - if not event is InputEventMouseButton: - return false - - if not _event_helper.is_key_just_pressed(MOUSE_BUTTON_LEFT): # Can't use just_released here - return false - - var shape_node: ProtonScatterShape = _gizmo_panel.shape_node - if not shape_node: - return false - - if not shape_node.shape or not shape_node.shape is ProtonScatterPathShape: - return false - - var shape: ProtonScatterPathShape = shape_node.shape - - # In select mode, the set_handle and commit_handle functions take over. - if _gizmo_panel.is_select_mode_enabled(): - return false - - var click_world_position := _intersect_with(shape_node, viewport_camera, event.position) - var point_local_position: Vector3 = shape_node.get_global_transform().affine_inverse() * click_world_position - - if _gizmo_panel.is_create_mode_enabled(): - shape.create_point(point_local_position) # TODO: add undo redo - shape_node.update_gizmos() - return true - - elif _gizmo_panel.is_delete_mode_enabled(): - var index = shape.get_closest_to(point_local_position) - if index != -1: - shape.remove_point(index) # TODO: add undo redo - shape_node.update_gizmos() - return true - - return false - - -func set_gizmo_panel(panel: PathPanel) -> void: - _gizmo_panel = panel - - -func _edit_path(shape_node: ProtonScatterShape, restore: ProtonScatterPathShape) -> void: - shape_node.shape.curve = restore.curve.duplicate() - shape_node.shape.thickness = restore.thickness - shape_node.update_gizmos() - - -func _intersect_with(path: ProtonScatterShape, camera: Camera3D, screen_point: Vector2, handle_position_local = null) -> Vector3: - # Get the ray data - var from = camera.project_ray_origin(screen_point) - var dir = camera.project_ray_normal(screen_point) - var gt = path.get_global_transform() - - # Snap to collider enabled - if _gizmo_panel.is_snap_to_colliders_enabled(): - var space_state: PhysicsDirectSpaceState3D = path.get_world_3d().get_direct_space_state() - var parameters := PhysicsRayQueryParameters3D.new() - parameters.from = from - parameters.to = from + (dir * 2048) - var hit := space_state.intersect_ray(parameters) - if not hit.is_empty(): - return hit.position - - # Lock to plane enabled - if _gizmo_panel.is_lock_to_plane_enabled(): - var t = Transform3D(gt) - var a = t.basis.x - var b = t.basis.z - var c = a + b - var o = t.origin - var plane = Plane(a + o, b + o, c + o) - var result = plane.intersects_ray(from, dir) - if result != null: - return result - - # Default case (similar to the built in Path3D node) - var origin: Vector3 - if handle_position_local: - origin = gt * handle_position_local - else: - origin = path.get_global_transform().origin - - var plane = Plane(dir, origin) - var res = plane.intersects_ray(from, dir) - if res != null: - return res - - return origin - diff --git a/addons/scatter-4/src/shapes/gizmos_plugin/shape_gizmo_plugin.gd b/addons/scatter-4/src/shapes/gizmos_plugin/shape_gizmo_plugin.gd deleted file mode 100644 index d2a704b..0000000 --- a/addons/scatter-4/src/shapes/gizmos_plugin/shape_gizmo_plugin.gd +++ /dev/null @@ -1,122 +0,0 @@ -@tool -extends EditorNode3DGizmoPlugin - - -# Actual logic split in the handler class to avoid cluttering this script as -# we add extra shapes. -# -# Although we could make an actual gizmo per shape type and add the extra type -# check in the 'has_gizmo' function, it causes more issues to the editor -# than it's worth (2 fewer files), so it's done like this instead. - - -const ScatterShape = preload("../../scatter_shape.gd") -const GizmoHandler = preload("./gizmo_handler.gd") - -var _handlers: Dictionary - - -func _init(): - var handle_icon = preload("./icons/main_handle.svg") - var secondary_handle_icon = preload("./icons/secondary_handle.svg") - - # TODO: Replace hardcoded colors by a setting fetch - create_material("primary", Color(1, 0.4, 0)) - create_material("secondary", Color(0.4, 0.7, 1.0)) - create_material("tertiary", Color(Color.STEEL_BLUE, 0.2)) - create_custom_material("primary_top", Color(1, 0.4, 0)) - create_custom_material("secondary_top", Color(0.4, 0.7, 1.0)) - create_custom_material("tertiary_top", Color(Color.STEEL_BLUE, 0.1)) - - create_material("inclusive", Color(0.9, 0.7, 0.2, 0.15)) - create_material("exclusive", Color(0.9, 0.1, 0.2, 0.15)) - - create_handle_material("default_handle") - create_handle_material("primary_handle", false, handle_icon) - create_handle_material("secondary_handle", false, secondary_handle_icon) - - _handlers[ProtonScatterSphereShape] = preload("./sphere_gizmo.gd").new() - _handlers[ProtonScatterPathShape] = preload("./path_gizmo.gd").new() - _handlers[ProtonScatterBoxShape] = preload("./box_gizmo.gd").new() - - -func _get_gizmo_name() -> String: - return "ScatterShape" - - -func _has_gizmo(node) -> bool: - return node is ScatterShape - - -func _get_handle_name(gizmo: EditorNode3DGizmo, handle_id: int, secondary: bool) -> String: - return _get_handler(gizmo).get_handle_name(gizmo, handle_id, secondary) - - -func _get_handle_value(gizmo: EditorNode3DGizmo, handle_id: int, secondary: bool) -> Variant: - return _get_handler(gizmo).get_handle_value(gizmo, handle_id, secondary) - - -func _set_handle(gizmo: EditorNode3DGizmo, handle_id: int, secondary: bool, camera: Camera3D, screen_pos: Vector2) -> void: - _get_handler(gizmo).set_handle(gizmo, handle_id, secondary, camera, screen_pos) - - -func _commit_handle(gizmo: EditorNode3DGizmo, handle_id: int, secondary: bool, restore: Variant, cancel: bool) -> void: - _get_handler(gizmo).commit_handle(gizmo, handle_id, secondary, restore, cancel) - - -func _redraw(gizmo: EditorNode3DGizmo): - _get_handler(gizmo).redraw(self, gizmo) - - -func forward_3d_gui_input(viewport_camera: Camera3D, event: InputEvent) -> int: - for handler in _handlers.values(): - if handler.forward_3d_gui_input(viewport_camera, event): - return EditorPlugin.AFTER_GUI_INPUT_STOP - - return EditorPlugin.AFTER_GUI_INPUT_PASS - - -func set_undo_redo(ur: EditorUndoRedoManager) -> void: - for handler_type in _handlers: - _handlers[handler_type].set_undo_redo(ur) - - -func set_path_gizmo_panel(panel: Control) -> void: - if ProtonScatterPathShape in _handlers: - _handlers[ProtonScatterPathShape].set_gizmo_panel(panel) - - -func set_editor_plugin(plugin: EditorPlugin) -> void: - for handler_type in _handlers: - _handlers[handler_type].set_editor_plugin(plugin) - - -# Creates a standard material displayed on top of everything. -# Only exists because 'create_material() on_top' parameter doesn't seem to work. -func create_custom_material(name, color := Color.WHITE): - var material := StandardMaterial3D.new() - material.set_blend_mode(StandardMaterial3D.BLEND_MODE_ADD) - material.set_shading_mode(StandardMaterial3D.SHADING_MODE_UNSHADED) - material.set_flag(StandardMaterial3D.FLAG_DISABLE_DEPTH_TEST, true) - material.set_albedo(color) - material.render_priority = 100 - - add_material(name, material) - - -func _get_handler(gizmo) -> GizmoHandler: - var null_handler = GizmoHandler.new() # Only so we don't have to check existence later - - var shape_node = gizmo.get_node_3d() - if not shape_node or not shape_node is ScatterShape: - return null_handler - - var shape_resource = shape_node.shape - if not shape_resource: - return null_handler - - var shape_type = shape_resource.get_script() - if not shape_type in _handlers: - return null_handler - - return _handlers[shape_type] diff --git a/addons/scatter-4/src/shapes/gizmos_plugin/sphere_gizmo.gd b/addons/scatter-4/src/shapes/gizmos_plugin/sphere_gizmo.gd deleted file mode 100644 index 1f7638d..0000000 --- a/addons/scatter-4/src/shapes/gizmos_plugin/sphere_gizmo.gd +++ /dev/null @@ -1,96 +0,0 @@ -@tool -extends "gizmo_handler.gd" - -# 3D Gizmo for the Sphere shape. Draws three circle on each axis to represent -# a sphere, displays one handle on the size to control the radius. -# -# (handle_id is ignored in every function since there's a single handle) - -const SphereShape = preload("../sphere_shape.gd") - - -func get_handle_name(_gizmo: EditorNode3DGizmo, _handle_id: int, _secondary: bool) -> String: - return "Radius" - - -func get_handle_value(gizmo: EditorNode3DGizmo, _handle_id: int, _secondary: bool) -> Variant: - return gizmo.get_node_3d().shape.radius - - -func set_handle(gizmo: EditorNode3DGizmo, _handle_id: int, _secondary: bool, camera: Camera3D, screen_pos: Vector2) -> void: - var shape_node = gizmo.get_node_3d() - var gt := shape_node.get_global_transform() - var gt_inverse := gt.affine_inverse() - var origin := gt.origin - - var ray_from = camera.project_ray_origin(screen_pos) - var ray_to = ray_from + camera.project_ray_normal(screen_pos) * 4096 - var points = Geometry3D.get_closest_points_between_segments(origin, (Vector3.LEFT * 4096) * gt_inverse, ray_from, ray_to) - shape_node.shape.radius = origin.distance_to(points[0]) - - -func commit_handle(gizmo: EditorNode3DGizmo, _handle_id: int, _secondary: bool, restore: Variant, cancel: bool) -> void: - var shape: SphereShape = gizmo.get_node_3d().shape - if cancel: - shape.radius = restore - return - - _undo_redo.create_action("Set ScatterShape Radius") - _undo_redo.add_undo_method(self, "_set_radius", shape, restore) - _undo_redo.add_do_method(self, "_set_radius", shape, shape.radius) - _undo_redo.commit_action() - - -func redraw(plugin: EditorNode3DGizmoPlugin, gizmo: EditorNode3DGizmo): - gizmo.clear() - var scatter_shape = gizmo.get_node_3d() - var shape: SphereShape = scatter_shape.shape - - ### Draw the 3 circles on each axis to represent the sphere - var lines = PackedVector3Array() - var lines_material := plugin.get_material("primary_top", gizmo) - var steps = 32 # TODO: Update based on sphere radius maybe ? - var step_angle = 2 * PI / steps - var radius = shape.radius - - for i in steps: - lines.append(Vector3(cos(i * step_angle), 0.0, sin(i * step_angle)) * radius) - lines.append(Vector3(cos((i + 1) * step_angle), 0.0, sin((i + 1) * step_angle)) * radius) - - if is_selected(gizmo): - for i in steps: - lines.append(Vector3(cos(i * step_angle), sin(i * step_angle), 0.0) * radius) - lines.append(Vector3(cos((i + 1) * step_angle), sin((i + 1) * step_angle), 0.0) * radius) - - for i in steps: - lines.append(Vector3(0.0, cos(i * step_angle), sin(i * step_angle)) * radius) - lines.append(Vector3(0.0, cos((i + 1) * step_angle), sin((i + 1) * step_angle)) * radius) - - gizmo.add_lines(lines, lines_material) - gizmo.add_collision_segments(lines) - - ### Draw the handle - var handles := PackedVector3Array() - var handles_ids := PackedInt32Array() - var handles_material := plugin.get_material("default_handle", gizmo) - - var handle_position: Vector3 = Vector3.LEFT * radius - handles.push_back(handle_position) - - gizmo.add_handles(handles, handles_material, handles_ids) - - ### Fills the sphere inside - var mesh = SphereMesh.new() - mesh.height = shape.radius * 2.0 - mesh.radius = shape.radius - var mesh_material: StandardMaterial3D - if scatter_shape.negative: - mesh_material = plugin.get_material("exclusive", gizmo) - else: - mesh_material = plugin.get_material("inclusive", gizmo) - gizmo.add_mesh(mesh, mesh_material) - - -func _set_radius(sphere: SphereShape, radius: float) -> void: - if sphere: - sphere.radius = radius diff --git a/addons/scatter-4/src/shapes/path_shape.gd b/addons/scatter-4/src/shapes/path_shape.gd deleted file mode 100644 index bb4a5d5..0000000 --- a/addons/scatter-4/src/shapes/path_shape.gd +++ /dev/null @@ -1,242 +0,0 @@ -@tool -class_name ProtonScatterPathShape -extends ProtonScatterBaseShape - - -const Bounds := preload("../common/bounds.gd") - - -@export var closed := true: - set(val): - closed = val - emit_changed() - -@export var thickness := 0.0: - set(val): - thickness = max(0, val) # Width cannot be negative - _half_thickness_squared = pow(thickness * 0.5, 2) - emit_changed() - -@export var curve: Curve3D: - set(val): - # Disconnect previous signal - if curve and curve.changed.is_connected(_on_curve_changed): - curve.changed.disconnect(_on_curve_changed) - - curve = val - curve.changed.connect(_on_curve_changed) - emit_changed() - - -var _polygon: PolygonPathFinder -var _half_thickness_squared: float -var _bounds: Bounds - - -func is_point_inside(point: Vector3, global_transform: Transform3D) -> bool: - if not _polygon: - _update_polygon_from_curve() - - if not _polygon: - return false - - point = global_transform.affine_inverse() * point - - if thickness > 0: - var closest_point_on_curve: Vector3 = curve.get_closest_point(point) - var dist2 = closest_point_on_curve.distance_squared_to(point) - if dist2 < _half_thickness_squared: - return true - - if closed: - return _polygon.is_point_inside(Vector2(point.x, point.z)) - - return false - - -func get_corners_global(gt: Transform3D) -> Array: - var res := [] - - if not curve: - return res - - var half_thickness = thickness * 0.5 - var corners = [ - Vector3(-1, -1, -1), - Vector3(1, -1, -1), - Vector3(1, -1, 1), - Vector3(-1, -1, 1), - Vector3(-1, 1, -1), - Vector3(1, 1, -1), - Vector3(1, 1, 1), - Vector3(-1, 1, 1), - ] - - var points = curve.tessellate(3, 10) - for p in points: - res.push_back(gt * p) - - if thickness > 0: - for offset in corners: - res.push_back(gt * (p + offset * half_thickness)) - - return res - - -func get_bounds() -> Bounds: - if not _bounds: - _update_polygon_from_curve() - return _bounds - - -func get_copy(): - var copy = get_script().new() - - copy.thickness = thickness - copy.closed = closed - if curve: - copy.curve = curve.duplicate() - - return copy - - -func copy_from(source) -> void: - thickness = source.thickness - if source.curve: - curve = source.curve.duplicate() # TODO, update signals - - -# TODO: create points in the middle of the path -func create_point(position: Vector3) -> void: - if not curve: - curve = Curve3D.new() - - curve.add_point(position) - - -func remove_point(index): - if index > curve.get_point_count() - 1: - return - curve.remove_point(index) - - -func get_closest_to(position): - if curve.get_point_count() == 0: - return -1 - - var closest = -1 - var dist_squared = -1 - - for i in curve.get_point_count(): - var point_pos: Vector3 = curve.get_point_position(i) - var point_dist: float = point_pos.distance_squared_to(position) - - if (closest == -1) or (dist_squared > point_dist): - closest = i - dist_squared = point_dist - - var threshold = 16 # Ignore if the closest point is farther than this - if dist_squared >= threshold: - return -1 - - return closest - - -func get_closed_edges(scatter_gt: Transform3D, shape_gt: Transform3D) -> Array[PackedVector2Array]: - if not closed and thickness <= 0: - return [] - - if not curve: - return [] - - var edges: Array[PackedVector2Array] = [] - var polyline := PackedVector2Array() - var shape_gt_inverse := shape_gt.affine_inverse() - var scatter_gt_inverse := scatter_gt.affine_inverse() - var points := curve.tessellate(5, 5) # TODO: find optimal values - - for p in points: - p = p * shape_gt_inverse # Convert to global coords - p = scatter_gt_inverse * p # convert to scatter local coords - polyline.push_back(Vector2(p.x, p.z)) - - # Prevents the polyline to be considered as a hole later. - if Geometry2D.is_polygon_clockwise(polyline): - polyline.reverse() - - # Expand the polyline to get the outer edge of the path. - if thickness > 0: - # WORKAROUND. We cant specify the round end caps resolution, but it's tied to the polyline - # size. So we scale everything up before calling offset_polyline(), then scale the result - # down so we get rounder caps. - var scale = 5.0 * thickness - var delta = (thickness / 2.0) * scale - - var t2 = Transform2D().scaled(Vector2.ONE * scale) - var result := Geometry2D.offset_polyline(polyline * t2, delta, Geometry2D.JOIN_ROUND, Geometry2D.END_ROUND) - - t2 = Transform2D().scaled(Vector2.ONE * (1.0 / scale)) - for polygon in result: - edges.push_back(polygon * t2) - - if closed: - edges.push_back(polyline) - - return edges - - -func get_open_edges(scatter_gt: Transform3D, shape_gt: Transform3D) -> Array[Curve3D]: - if not curve or closed or thickness > 0: - return [] - - var res := Curve3D.new() - var shape_gt_inverse := shape_gt.affine_inverse() - - for i in curve.get_point_count(): - var pos = curve.get_point_position(i) - var pos_t = pos * shape_gt_inverse - var p_in = (curve.get_point_in(i) + pos) * shape_gt_inverse - pos_t - var p_out = (curve.get_point_out(i) + pos) * shape_gt_inverse - pos_t - res.add_point(pos_t, p_in, p_out) - - return [res] - - -func _update_polygon_from_curve() -> void: - var connections = PackedInt32Array() - var polygon_points = PackedVector2Array() - - if not _bounds: - _bounds = Bounds.new() - - _bounds.clear() - _polygon = PolygonPathFinder.new() - - if not curve: - curve = Curve3D.new() - - if curve.get_point_count() == 0: - return - - var baked_points = curve.tessellate(4, 6) - var steps := baked_points.size() - - for i in baked_points.size(): - var point = baked_points[i] - var projected_point = Vector2(point.x, point.z) - _bounds.feed(point) - - polygon_points.push_back(projected_point) - connections.append(i) - if i == steps - 1: - connections.append(0) - else: - connections.append(i + 1) - - _bounds.compute_bounds() - _polygon.setup(polygon_points, connections) - - -func _on_curve_changed() -> void: - _update_polygon_from_curve() - emit_changed() diff --git a/addons/scatter-4/src/shapes/sphere_shape.gd b/addons/scatter-4/src/shapes/sphere_shape.gd deleted file mode 100644 index dda0110..0000000 --- a/addons/scatter-4/src/shapes/sphere_shape.gd +++ /dev/null @@ -1,78 +0,0 @@ -@tool -class_name ProtonScatterSphereShape -extends ProtonScatterBaseShape - - -@export var radius := 1.0: - set(val): - radius = val - _radius_squared = val * val - emit_changed() - -var _radius_squared := 0.0 - - -func get_copy(): - var copy = ProtonScatterSphereShape.new() - copy.radius = radius - return copy - - -func is_point_inside(point: Vector3, global_transform: Transform3D) -> bool: - var shape_center = global_transform * Vector3.ZERO - return shape_center.distance_squared_to(point) < _radius_squared - - -func get_corners_global(gt: Transform3D) -> Array: - var res := [] - - var corners := [ - Vector3(-1, -1, -1), - Vector3(-1, -1, 1), - Vector3(1, -1, 1), - Vector3(1, -1, -1), - Vector3(-1, 1, -1), - Vector3(-1, 1, 1), - Vector3(1, 1, 1), - Vector3(1, 1, -1), - ] - - for c in corners: - c *= radius - res.push_back(gt * c) - - return res - - - -# Returns the circle matching the intersection between the transform's XZ plane -# and the sphere. Returns an empty array if there's no intersection -func get_closed_edges(scatter_gt: Transform3D, shape_gt: Transform3D) -> Array[PackedVector2Array]: - var edge := PackedVector2Array() - - var a = scatter_gt.basis.x - var b = scatter_gt.basis.z - var c = a + b - var o = scatter_gt.origin - var plane = Plane(a + o, b + o, c + o) - - var sphere_center := shape_gt.origin - var dist2plane = plane.distance_to(sphere_center) - var radius_at_ground_level := sqrt(pow(radius, 2) - pow(dist2plane, 2)) - - # No intersection with plane - if radius_at_ground_level <= 0 or radius_at_ground_level > radius: - return [] - - var sphere_center_local = scatter_gt.affine_inverse() * sphere_center - - var origin := Vector2(sphere_center_local.x, sphere_center_local.z) - var steps: int = max(16, radius_at_ground_level * 12.0) - var angle: float = TAU / steps - - for i in steps + 1: - var theta = angle * i - var point := origin + Vector2(cos(theta), sin(theta)) * radius_at_ground_level - edge.push_back(point) - - return [edge] diff --git a/addons/scatter-4/src/stack/inspector_plugin/editor_property.gd b/addons/scatter-4/src/stack/inspector_plugin/editor_property.gd deleted file mode 100644 index 76c8cc3..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/editor_property.gd +++ /dev/null @@ -1,15 +0,0 @@ -@tool -extends EditorProperty - - -var _ui: Control - - -func _init(): - _ui = preload("./ui/stack_panel.tscn").instantiate() - add_child(_ui) - set_bottom_editor(_ui) - - -func set_node(object) -> void: - _ui.set_node(object) diff --git a/addons/scatter-4/src/stack/inspector_plugin/modifier_stack_plugin.gd b/addons/scatter-4/src/stack/inspector_plugin/modifier_stack_plugin.gd deleted file mode 100644 index 1694bc5..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/modifier_stack_plugin.gd +++ /dev/null @@ -1,19 +0,0 @@ -@tool -extends EditorInspectorPlugin - - -const Editor = preload("./editor_property.gd") -const Scatter = preload("../../scatter.gd") - - -func _can_handle(object): - return object is Scatter - - -func _parse_property(object, type, name, hint_type, hint_string, usage_flags, wide): - if name == "modifier_stack": - var editor_property = Editor.new() - editor_property.set_node(object) - add_property_editor("modifier_stack", editor_property) - return true - return false diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/add_modifier_button.gd b/addons/scatter-4/src/stack/inspector_plugin/ui/add_modifier_button.gd deleted file mode 100644 index 2d2ecb0..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/add_modifier_button.gd +++ /dev/null @@ -1,19 +0,0 @@ -@tool -extends Button - - -@onready var _popup: PopupPanel = $ModifiersPopup - - -func _ready() -> void: - _popup.popup_hide.connect(_on_popup_closed) - - -func _toggled(button_pressed): - if button_pressed: - _popup.position = global_position + Vector2(0.0, size.y) - _popup.popup() - - -func _on_popup_closed() -> void: - button_pressed = false diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/base_parameter.gd b/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/base_parameter.gd deleted file mode 100644 index cdf44ed..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/base_parameter.gd +++ /dev/null @@ -1,39 +0,0 @@ -@tool -extends Control - - -signal value_changed - -var _previous -var _locked := false - - -func set_parameter_name(_text: String) -> void: - pass - - -func set_hint_string(_hint: String) -> void: - pass - - -func set_value(val) -> void: - _locked = true - _set_value(val) - _previous = get_value() - _locked = false - - -func get_value(): - pass - - -func _set_value(_val): - pass - - -func _on_value_changed(_val) -> void: - if not _locked: - var value = get_value() - if value != _previous: - value_changed.emit(value, _previous) - _previous = value diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/bitmask_button.tscn b/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/bitmask_button.tscn deleted file mode 100644 index 978b123..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/bitmask_button.tscn +++ /dev/null @@ -1,51 +0,0 @@ -[gd_scene load_steps=4 format=3 uid="uid://cf4lrr5tnlwnw"] - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_lylt6"] -content_margin_left = 0.0 -content_margin_top = 0.0 -content_margin_right = 0.0 -content_margin_bottom = 0.0 -bg_color = Color(1, 1, 1, 0.54902) -corner_radius_top_left = 2 -corner_radius_top_right = 2 -corner_radius_bottom_right = 2 -corner_radius_bottom_left = 2 -corner_detail = 6 - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_8hejw"] -content_margin_left = 0.0 -content_margin_top = 0.0 -content_margin_right = 0.0 -content_margin_bottom = 0.0 -bg_color = Color(1, 1, 1, 0.784314) -corner_radius_top_left = 2 -corner_radius_top_right = 2 -corner_radius_bottom_right = 2 -corner_radius_bottom_left = 2 -corner_detail = 6 - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_dmtgy"] -content_margin_left = 0.0 -content_margin_top = 0.0 -content_margin_right = 0.0 -content_margin_bottom = 0.0 -bg_color = Color(1, 1, 1, 1) -corner_radius_top_left = 2 -corner_radius_top_right = 2 -corner_radius_bottom_right = 2 -corner_radius_bottom_left = 2 -corner_detail = 6 - -[node name="Button" type="Button"] -custom_minimum_size = Vector2(20, 20) -size_flags_horizontal = 3 -focus_mode = 0 -theme_override_colors/font_color = Color(0, 0, 0, 1) -theme_override_colors/font_pressed_color = Color(0, 0, 0, 1) -theme_override_colors/font_hover_color = Color(0, 0, 0, 1) -theme_override_font_sizes/font_size = 12 -theme_override_styles/normal = SubResource("StyleBoxFlat_lylt6") -theme_override_styles/hover = SubResource("StyleBoxFlat_8hejw") -theme_override_styles/pressed = SubResource("StyleBoxFlat_dmtgy") -toggle_mode = true -text = "00" diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/curve_panel.gd b/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/curve_panel.gd deleted file mode 100644 index 9479118..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/curve_panel.gd +++ /dev/null @@ -1,332 +0,0 @@ -# warning-ignore-all:return_value_discarded - -@tool -extends Control - - -signal curve_updated - - -@export var grid_color := Color(1, 1, 1, 0.2) -@export var grid_color_sub := Color(1, 1, 1, 0.1) -@export var curve_color := Color(1, 1, 1, 0.9) -@export var point_color := Color.WHITE -@export var selected_point_color := Color.ORANGE -@export var point_radius := 4.0 -@export var text_color := Color(0.9, 0.9, 0.9) -@export var columns := 4 -@export var rows := 2 -@export var dynamic_row_count := true - -var curve: Curve -var gt: Transform2D - -var _hover_point := -1: - set(val): set_hover(val) -var _selected_point := -1: - set(val): set_selected_point(val) -var _selected_tangent := -1: - set(val): set_selected_tangent(val) -var _dragging := false -var _hover_radius := 50.0 # Squared -var _tangents_length := 30.0 -var _font: Font - - -func _ready() -> void: - #rect_min_size.y *= EditorUtil.get_editor_scale() - var plugin := EditorPlugin.new() - var theme := plugin.get_editor_interface().get_base_control().get_theme() - _font = theme.get_font("Main", "EditorFonts") - plugin.queue_free() - - queue_redraw() - connect("resized", _on_resized) - - -func set_curve(c: Curve) -> void: - curve = c - queue_redraw() - - -func get_curve() -> Curve: - return curve - - -func _gui_input(event) -> void: - if event is InputEventKey: - if _selected_point != -1 and event.scancode == KEY_DELETE: - remove_point(_selected_point) - - elif event is InputEventMouseButton: - if event.doubleclick: - add_point(_to_curve_space(event.position)) - - elif event.pressed and event.button_index == MOUSE_BUTTON_MIDDLE: - var i = get_point_at(event.position) - if i != -1: - remove_point(i) - - elif event.pressed and event.button_index == MOUSE_BUTTON_LEFT: - set_selected_tangent(get_tangent_at(event.position)) - - if _selected_tangent == -1: - set_selected_point(get_point_at(event.position)) - if _selected_point != -1: - _dragging = true - - elif _dragging and not event.pressed: - _dragging = false - emit_signal("curve_updated") - - elif event is InputEventMouseMotion: - if _dragging: - var curve_amplitude: float = curve.get_max_value() - curve.get_min_value() - - # Snap to "round" coordinates when holding Ctrl. - # Be more precise when holding Shift as well. - var snap_threshold: float - if event.control: - snap_threshold = 0.025 if event.shift else 0.1 - else: - snap_threshold = 0.0 - - if _selected_tangent == -1: # Drag point - var point_pos: Vector2 = _to_curve_space(event.position).snapped(Vector2(snap_threshold, snap_threshold * curve_amplitude)) - - # The index may change if the point is dragged across another one - var i: int = curve.set_point_offset(_selected_point, point_pos.x) - set_hover(i) - set_selected_point(i) - - # This is to prevent the user from losing a point out of view. - if point_pos.y < curve.get_min_value(): - point_pos.y = curve.get_min_value() - elif point_pos.y > curve.get_max_value(): - point_pos.y = curve.get_max_value() - - curve.set_point_value(_selected_point, point_pos.y) - - else: # Drag tangent - var point_pos: Vector2 = curve.get_point_position(_selected_point) - var control_pos: Vector2 = _to_curve_space(event.position).snapped(Vector2(snap_threshold, snap_threshold * curve_amplitude)) - - var dir: Vector2 = (control_pos - point_pos).normalized() - - var tangent: float - if not is_zero_approx(dir.x): - tangent = dir.y / dir.x - else: - tangent = 1 if dir.y >= 0 else -1 - tangent *= 9999 - - var link: bool = not Input.is_key_pressed(KEY_SHIFT) - - if _selected_tangent == 0: - curve.set_point_left_tangent(_selected_point, tangent) - - # Note: if a tangent is set to linear, it shouldn't be linked to the other - if link and _selected_point != (curve.get_point_count() - 1) and curve.get_point_right_mode(_selected_point) != Curve.TANGENT_LINEAR: - curve.set_point_right_tangent(_selected_point, tangent) - - else: - curve.set_point_right_tangent(_selected_point, tangent) - - if link and _selected_point != 0 and curve.get_point_left_mode(_selected_point) != Curve.TANGENT_LINEAR: - curve.set_point_left_tangent(_selected_point, tangent) - queue_redraw() - else: - set_hover(get_point_at(event.position)) - - -func add_point(pos: Vector2) -> void: - if not curve: - return - - pos.y = clamp(pos.y, 0.0, 1.0) - curve.add_point(pos) - queue_redraw() - emit_signal("curve_updated") - - -func remove_point(idx: int) -> void: - if not curve: - return - - if idx == _selected_point: - set_selected_point(-1) - - if idx == _hover_point: - set_hover(-1) - - curve.remove_point(idx) - queue_redraw() - emit_signal("curve_updated") - - -func get_point_at(pos: Vector2) -> int: - if not curve: - return -1 - - for i in curve.get_point_count(): - var p := _to_view_space(curve.get_point_position(i)) - if p.distance_squared_to(pos) <= _hover_radius: - return i - - return -1 - - -func get_tangent_at(pos: Vector2) -> int: - if not curve or _selected_point < 0: - return -1 - - if _selected_point != 0: - var control_pos: Vector2 = _get_tangent_view_pos(_selected_point, 0) - if control_pos.distance_squared_to(pos) < _hover_radius: - return 0 - - if _selected_point != curve.get_point_count() - 1: - var control_pos = _get_tangent_view_pos(_selected_point, 1) - if control_pos.distance_squared_to(pos) < _hover_radius: - return 1 - - return -1 - - -func _draw() -> void: - if not curve: - return - - var text_height = _font.get_height() - var min_outer := Vector2(0, size.y) - var max_outer := Vector2(size.x, 0) - var min_inner := Vector2(text_height, size.y - text_height) - var max_inner := Vector2(size.x - text_height, text_height) - - var width: float = max_inner.x - min_inner.x - var height: float = max_inner.y - min_inner.y - - var curve_min: float = curve.get_min_value() - var curve_max: float = curve.get_max_value() - - - # Main area - draw_line(Vector2(0, max_inner.y), Vector2(max_outer.x, max_inner.y), grid_color) - draw_line(Vector2(0, min_inner.y), Vector2(max_outer.x, min_inner.y), grid_color) - draw_line(Vector2(min_inner.x, max_outer.y), Vector2(min_inner.x, min_outer.y), grid_color) - draw_line(Vector2(max_inner.x, max_outer.y), Vector2(max_inner.x, min_outer.y), grid_color) - - # Grid and scale - ## Vertical lines - var x_offset = 1.0 / columns - var margin = 4 - - for i in columns + 1: - var x = width * (i * x_offset) + min_inner.x - draw_line(Vector2(x, max_outer.y), Vector2(x, min_outer.y), grid_color_sub) - draw_string(_font, Vector2(x + margin, min_outer.y - margin), str(snapped(i * x_offset, 0.01)), 0, -1, -1, text_color) - - ## Horizontal lines - var y_offset = 1.0 / rows - - for i in rows + 1: - var y = height * (i * y_offset) + min_inner.y - draw_line(Vector2(min_outer.x, y), Vector2(max_outer.x, y), grid_color_sub) - var y_value = i * ((curve_max - curve_min) / rows) + curve_min - draw_string(_font, Vector2(min_inner.x + margin, y - margin), str(snapped(y_value, 0.01)), 0, -1, -1, text_color) - - # Plot curve - var steps = 100 - var offset = 1.0 / steps - x_offset = width / steps - - var a: float - var a_y: float - var b: float - var b_y: float - - a = curve.sample_baked(0.0) - a_y = remap(a, curve_min, curve_max, min_inner.y, max_inner.y) - - for i in steps - 1: - b = curve.sample_baked((i + 1) * offset) - b_y = remap(b, curve_min, curve_max, min_inner.y, max_inner.y) - draw_line(Vector2(min_inner.x + x_offset * i, a_y), Vector2(min_inner.x + x_offset * (i + 1), b_y), curve_color) - a_y = b_y - - # Draw points - for i in curve.get_point_count(): - var pos: Vector2 = _to_view_space(curve.get_point_position(i)) - if _selected_point == i: - draw_circle(pos, point_radius, selected_point_color) - else: - draw_circle(pos, point_radius, point_color); - - if _hover_point == i: - draw_arc(pos, point_radius + 4.0, 0.0, 2 * PI, 12, point_color, 1.0, true) - - # Draw tangents - if _selected_point >= 0: - var i: int = _selected_point - var pos: Vector2 = _to_view_space(curve.get_point_position(i)) - - if i != 0: - var control_pos: Vector2 = _get_tangent_view_pos(i, 0) - draw_line(pos, control_pos, selected_point_color) - draw_rect(Rect2(control_pos, Vector2(1, 1)).grow(2), selected_point_color) - - if i != curve.get_point_count() - 1: - var control_pos: Vector2 = _get_tangent_view_pos(i, 1) - draw_line(pos, control_pos, selected_point_color) - draw_rect(Rect2(control_pos, Vector2(1, 1)).grow(2), selected_point_color) - - -func _to_view_space(pos: Vector2) -> Vector2: - var h = _font.get_height() - pos.x = remap(pos.x, 0.0, 1.0, h, size.x - h) - pos.y = remap(pos.y, curve.get_min_value(), curve.get_max_value(), size.y - h, h) - return pos - - -func _to_curve_space(pos: Vector2) -> Vector2: - var h = _font.get_height() - pos.x = remap(pos.x, h, size.x - h, 0.0, 1.0) - pos.y = remap(pos.y, size.y - h, h, curve.get_min_value(), curve.get_max_value()) - return pos - - -func _get_tangent_view_pos(i: int, tangent: int) -> Vector2: - var dir: Vector2 - - if tangent == 0: - dir = -Vector2(1.0, curve.get_point_left_tangent(i)) - else: - dir = Vector2(1.0, curve.get_point_right_tangent(i)) - - var point_pos = _to_view_space(curve.get_point_position(i)) - var control_pos = _to_view_space(curve.get_point_position(i) + dir) - - return point_pos + _tangents_length * (control_pos - point_pos).normalized() - - -func set_hover(val: int) -> void: - if val != _hover_point: - _hover_point = val - queue_redraw() - - -func set_selected_point(val: int) -> void: - if val != _selected_point: - _selected_point = val - queue_redraw() - - -func set_selected_tangent(val: int) -> void: - if val != _selected_tangent: - _selected_tangent = val - queue_redraw() - - -func _on_resized() -> void: - if dynamic_row_count: - rows = (int(size.y / custom_minimum_size.y) + 1) * 2 diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/header/parameter_button.gd b/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/header/parameter_button.gd deleted file mode 100644 index fda5f0c..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/header/parameter_button.gd +++ /dev/null @@ -1,23 +0,0 @@ -@tool -extends "../base_parameter.gd" - - -var _button - - -func _ready() -> void: - _button = get_node("Button") - _button.toggled.connect(_on_value_changed) - - -func enable(enabled: bool) -> void: - _button.disabled = not enabled - _button.flat = not enabled - - -func get_value() -> bool: - return _button.button_pressed - - -func _set_value(val: bool) -> void: - _button.button_pressed = val diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/header/parameter_button.tscn b/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/header/parameter_button.tscn deleted file mode 100644 index 12dab18..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/header/parameter_button.tscn +++ /dev/null @@ -1,19 +0,0 @@ -[gd_scene load_steps=3 format=3 uid="uid://w6ycb4oveqhd"] - -[ext_resource type="Script" path="res://addons/proton_scatter/src/stack/inspector_plugin/ui/modifier/components/header/parameter_button.gd" id="1_f6puy"] -[ext_resource type="Script" path="res://addons/proton_scatter/src/stack/inspector_plugin/ui/modifier/toggle_button.gd" id="2_167vc"] - -[node name="MarginContainer" type="MarginContainer"] -offset_right = 40.0 -offset_bottom = 40.0 -size_flags_horizontal = 4 -size_flags_vertical = 4 -script = ExtResource( "1_f6puy" ) - -[node name="Button" type="Button" parent="."] -offset_right = 40.0 -offset_bottom = 40.0 -focus_mode = 0 -toggle_mode = true -icon_alignment = 1 -script = ExtResource( "2_167vc" ) diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/header/parameter_spinbox.gd b/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/header/parameter_spinbox.gd deleted file mode 100644 index 688f19a..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/header/parameter_spinbox.gd +++ /dev/null @@ -1,17 +0,0 @@ -@tool -extends "../base_parameter.gd" - - -@onready var _spinbox = $SpinBox - - -func _ready() -> void: - _spinbox.value_changed.connect(_on_value_changed) - - -func get_value() -> int: - return int(_spinbox.get_value()) - - -func _set_value(val: int) -> void: - _spinbox.set_value(val) diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/header/parameter_spinbox.tscn b/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/header/parameter_spinbox.tscn deleted file mode 100644 index 76175e5..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/header/parameter_spinbox.tscn +++ /dev/null @@ -1,17 +0,0 @@ -[gd_scene load_steps=2 format=3 uid="uid://c36gqn03pvlnr"] - -[ext_resource type="Script" path="res://addons/proton_scatter/src/stack/inspector_plugin/ui/modifier/components/header/parameter_spinbox.gd" id="1_f0oq6"] - -[node name="ParameterSpinbox" type="MarginContainer"] -offset_right = 83.0625 -offset_bottom = 31.0 -size_flags_horizontal = 4 -size_flags_vertical = 4 -script = ExtResource( "1_f0oq6" ) - -[node name="SpinBox" type="SpinBox" parent="."] -offset_right = 83.0 -offset_bottom = 31.0 -min_value = -100.0 -allow_greater = true -allow_lesser = true diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_bitmask.gd b/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_bitmask.gd deleted file mode 100644 index c32279a..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_bitmask.gd +++ /dev/null @@ -1,131 +0,0 @@ -@tool -extends "base_parameter.gd" - - -@onready var _label: Label = $Label -@onready var _grid_1: Control = $%GridContainer1 -@onready var _grid_2: Control = $%GridContainer2 -@onready var _grid_3: Control = $%GridContainer3 -@onready var _grid_4: Control = $%GridContainer4 -@onready var _menu_button: MenuButton = $%MenuButton - -var _buttons: Array[Button] -var _popup: PopupMenu -var _layer_count := 32 - - -func _ready() -> void: - _buttons = [] - var grids = [_grid_1, _grid_2, _grid_3, _grid_4] - - for g in grids: - for c in g.get_children(): - if c is Button: - var layer_number = c.text.to_int() - if layer_number > _layer_count: - c.visible = false - continue - _buttons.push_front(c) - c.focus_mode = Control.FOCUS_NONE - c.pressed.connect(_on_button_pressed) - - _popup = _menu_button.get_popup() - _popup.clear() - - var layer_name := "" - for i in _layer_count: - if i != 0 and i % 4 == 0: - _popup.add_separator("", 100 + i) - - layer_name = ProjectSettings.get_setting("layer_names/3d_physics/layer_" + str(i + 1)) - if layer_name.is_empty(): - layer_name = "Layer " + str(i + 1) - _popup.add_check_item(layer_name, _layer_count - 1 - i) - - _sync_popup_state() - _popup.id_pressed.connect(_on_id_pressed) - - -func set_parameter_name(text: String) -> void: - _label.text = text - - -func _set_value(val: int) -> void: - var binary_string: String = _dec2bin(val) - var length = binary_string.length() - - if length < _layer_count: - binary_string = binary_string.pad_zeros(_layer_count) - elif length > _layer_count: - binary_string = binary_string.substr(length - _layer_count, length) - - for i in _layer_count: - _buttons[i].button_pressed = binary_string[i] == "1" - - _sync_popup_state() - - -func get_value() -> int: - var binary_string = "" - for b in _buttons: - binary_string += "1" if b.button_pressed else "0" - - var val = _bin2dec(binary_string) - return val - - -func _dec2bin(value: int) -> String: - if value == 0: - return "0" - - var binary_string = "" - while value != 0: - var m = value % 2 - binary_string = str(m) + binary_string - # warning-ignore:integer_division - value = value / 2 - - return binary_string - - -func _bin2dec(binary_string: String) -> int: - var decimal_value = 0 - var count = binary_string.length() - 1 - - for i in binary_string.length(): - decimal_value += pow(2, count) * binary_string[i].to_int() - count -= 1 - - return decimal_value - - -func _sync_popup_state() -> void: - if not _popup: - return - - for i in _layer_count: - var idx = _popup.get_item_index(i) - _popup.set_item_checked(idx, _buttons[i].button_pressed) - - -func _on_button_pressed() -> void: - _on_value_changed(null) - _sync_popup_state() - - -func _on_id_pressed(id: int) -> void: - var idx = _popup.get_item_index(id) - var checked = not _popup.is_item_checked(idx) - _buttons[id].button_pressed = checked - _popup.set_item_checked(idx, checked) - _on_button_pressed() - - -func _on_enable_all_pressed() -> void: - _set_value(4294967295) - _on_value_changed(null) - - -func _on_clear_pressed() -> void: - _set_value(0) - _on_value_changed(null) diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_bitmask.tscn b/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_bitmask.tscn deleted file mode 100644 index 73e0361..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_bitmask.tscn +++ /dev/null @@ -1,436 +0,0 @@ -[gd_scene load_steps=6 format=3 uid="uid://chondv2lhs4pl"] - -[ext_resource type="Script" path="res://addons/proton_scatter/src/stack/inspector_plugin/ui/modifier/components/parameter_bitmask.gd" id="1"] -[ext_resource type="PackedScene" uid="uid://cf4lrr5tnlwnw" path="res://addons/proton_scatter/src/stack/inspector_plugin/ui/modifier/components/bitmask_button.tscn" id="2"] -[ext_resource type="Texture2D" uid="uid://n66mufjib4ds" path="res://addons/proton_scatter/icons/menu.svg" id="3"] -[ext_resource type="Texture2D" uid="uid://bosx22dy64f11" path="res://addons/proton_scatter/icons/clear.svg" id="4"] -[ext_resource type="Texture2D" uid="uid://bb6107shgmiaw" path="res://addons/proton_scatter/icons/select_all.svg" id="4_h30jm"] - -[node name="parameter_bitmask" type="VBoxContainer"] -anchor_right = 1.0 -offset_bottom = 178.0 -script = ExtResource("1") - -[node name="Label" type="Label" parent="."] -offset_right = 1024.0 -offset_bottom = 26.0 -text = "Parameter name" - -[node name="MarginContainer" type="MarginContainer" parent="."] -offset_top = 30.0 -offset_right = 1024.0 -offset_bottom = 130.0 - -[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer"] -offset_right = 1024.0 -offset_bottom = 100.0 -alignment = 2 - -[node name="MenuButton" type="MenuButton" parent="MarginContainer/HBoxContainer"] -unique_name_in_owner = true -offset_left = 772.0 -offset_right = 796.0 -offset_bottom = 100.0 -icon = ExtResource("3") -item_count = 39 -popup/item_0/text = "Layer 1" -popup/item_0/checkable = 1 -popup/item_0/id = 31 -popup/item_1/text = "Layer 2" -popup/item_1/checkable = 1 -popup/item_1/id = 30 -popup/item_2/text = "Layer 3" -popup/item_2/checkable = 1 -popup/item_2/id = 29 -popup/item_3/text = "Layer 4" -popup/item_3/checkable = 1 -popup/item_3/id = 28 -popup/item_4/text = "" -popup/item_4/id = 104 -popup/item_4/separator = true -popup/item_5/text = "Layer 5" -popup/item_5/checkable = 1 -popup/item_5/id = 27 -popup/item_6/text = "Layer 6" -popup/item_6/checkable = 1 -popup/item_6/id = 26 -popup/item_7/text = "Layer 7" -popup/item_7/checkable = 1 -popup/item_7/id = 25 -popup/item_8/text = "Layer 8" -popup/item_8/checkable = 1 -popup/item_8/id = 24 -popup/item_9/text = "" -popup/item_9/id = 108 -popup/item_9/separator = true -popup/item_10/text = "Layer 9" -popup/item_10/checkable = 1 -popup/item_10/id = 23 -popup/item_11/text = "Layer 10" -popup/item_11/checkable = 1 -popup/item_11/id = 22 -popup/item_12/text = "Layer 11" -popup/item_12/checkable = 1 -popup/item_12/id = 21 -popup/item_13/text = "Layer 12" -popup/item_13/checkable = 1 -popup/item_13/id = 20 -popup/item_14/text = "" -popup/item_14/id = 112 -popup/item_14/separator = true -popup/item_15/text = "Layer 13" -popup/item_15/checkable = 1 -popup/item_15/id = 19 -popup/item_16/text = "Layer 14" -popup/item_16/checkable = 1 -popup/item_16/id = 18 -popup/item_17/text = "Layer 15" -popup/item_17/checkable = 1 -popup/item_17/id = 17 -popup/item_18/text = "Layer 16" -popup/item_18/checkable = 1 -popup/item_18/id = 16 -popup/item_19/text = "" -popup/item_19/id = 116 -popup/item_19/separator = true -popup/item_20/text = "Layer 17" -popup/item_20/checkable = 1 -popup/item_20/id = 15 -popup/item_21/text = "Layer 18" -popup/item_21/checkable = 1 -popup/item_21/id = 14 -popup/item_22/text = "Layer 19" -popup/item_22/checkable = 1 -popup/item_22/id = 13 -popup/item_23/text = "Layer 20" -popup/item_23/checkable = 1 -popup/item_23/id = 12 -popup/item_24/text = "" -popup/item_24/id = 120 -popup/item_24/separator = true -popup/item_25/text = "Layer 21" -popup/item_25/checkable = 1 -popup/item_25/id = 11 -popup/item_26/text = "Layer 22" -popup/item_26/checkable = 1 -popup/item_26/id = 10 -popup/item_27/text = "Layer 23" -popup/item_27/checkable = 1 -popup/item_27/id = 9 -popup/item_28/text = "Layer 24" -popup/item_28/checkable = 1 -popup/item_28/id = 8 -popup/item_29/text = "" -popup/item_29/id = 124 -popup/item_29/separator = true -popup/item_30/text = "Layer 25" -popup/item_30/checkable = 1 -popup/item_30/id = 7 -popup/item_31/text = "Layer 26" -popup/item_31/checkable = 1 -popup/item_31/id = 6 -popup/item_32/text = "Layer 27" -popup/item_32/checkable = 1 -popup/item_32/id = 5 -popup/item_33/text = "Layer 28" -popup/item_33/checkable = 1 -popup/item_33/id = 4 -popup/item_34/text = "" -popup/item_34/id = 128 -popup/item_34/separator = true -popup/item_35/text = "Layer 29" -popup/item_35/checkable = 1 -popup/item_35/id = 3 -popup/item_36/text = "Layer 30" -popup/item_36/checkable = 1 -popup/item_36/id = 2 -popup/item_37/text = "Layer 31" -popup/item_37/checkable = 1 -popup/item_37/id = 1 -popup/item_38/text = "Layer 32" -popup/item_38/checkable = 1 -popup/item_38/id = 0 - -[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/HBoxContainer"] -offset_left = 800.0 -offset_right = 996.0 -offset_bottom = 100.0 - -[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/HBoxContainer/VBoxContainer"] -offset_right = 196.0 -offset_bottom = 44.0 - -[node name="GridContainer1" type="GridContainer" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer"] -unique_name_in_owner = true -offset_right = 92.0 -offset_bottom = 44.0 -columns = 4 - -[node name="Button1" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer/GridContainer1" instance=ExtResource("2")] -offset_right = 20.0 -offset_bottom = 20.0 -text = "1" - -[node name="Button2" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer/GridContainer1" instance=ExtResource("2")] -offset_left = 24.0 -offset_right = 44.0 -offset_bottom = 20.0 -text = "2" - -[node name="Button3" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer/GridContainer1" instance=ExtResource("2")] -offset_left = 48.0 -offset_right = 68.0 -offset_bottom = 20.0 -text = "3" - -[node name="Button4" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer/GridContainer1" instance=ExtResource("2")] -offset_left = 72.0 -offset_right = 92.0 -offset_bottom = 20.0 -text = "4" - -[node name="Button5" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer/GridContainer1" instance=ExtResource("2")] -offset_top = 24.0 -offset_right = 20.0 -offset_bottom = 44.0 -text = "5" - -[node name="Button6" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer/GridContainer1" instance=ExtResource("2")] -offset_left = 24.0 -offset_top = 24.0 -offset_right = 44.0 -offset_bottom = 44.0 -text = "6" - -[node name="Button7" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer/GridContainer1" instance=ExtResource("2")] -offset_left = 48.0 -offset_top = 24.0 -offset_right = 68.0 -offset_bottom = 44.0 -text = "7" - -[node name="Button8" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer/GridContainer1" instance=ExtResource("2")] -offset_left = 72.0 -offset_top = 24.0 -offset_right = 92.0 -offset_bottom = 44.0 -text = "8" - -[node name="VSeparator" type="VSeparator" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer"] -offset_left = 96.0 -offset_right = 100.0 -offset_bottom = 44.0 - -[node name="GridContainer2" type="GridContainer" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer"] -unique_name_in_owner = true -offset_left = 104.0 -offset_right = 196.0 -offset_bottom = 44.0 -columns = 4 - -[node name="Button9" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer/GridContainer2" instance=ExtResource("2")] -offset_right = 20.0 -offset_bottom = 20.0 -text = "9" - -[node name="Button10" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer/GridContainer2" instance=ExtResource("2")] -offset_left = 24.0 -offset_right = 44.0 -offset_bottom = 20.0 -text = "10" - -[node name="Button11" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer/GridContainer2" instance=ExtResource("2")] -offset_left = 48.0 -offset_right = 68.0 -offset_bottom = 20.0 -text = "11" - -[node name="Button12" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer/GridContainer2" instance=ExtResource("2")] -offset_left = 72.0 -offset_right = 92.0 -offset_bottom = 20.0 -text = "12" - -[node name="Button13" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer/GridContainer2" instance=ExtResource("2")] -offset_top = 24.0 -offset_right = 20.0 -offset_bottom = 44.0 -text = "13" - -[node name="Button14" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer/GridContainer2" instance=ExtResource("2")] -offset_left = 24.0 -offset_top = 24.0 -offset_right = 44.0 -offset_bottom = 44.0 -text = "14" - -[node name="Button15" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer/GridContainer2" instance=ExtResource("2")] -offset_left = 48.0 -offset_top = 24.0 -offset_right = 68.0 -offset_bottom = 44.0 -text = "15" - -[node name="Button16" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer/GridContainer2" instance=ExtResource("2")] -offset_left = 72.0 -offset_top = 24.0 -offset_right = 92.0 -offset_bottom = 44.0 -text = "16" - -[node name="HSeparator" type="HSeparator" parent="MarginContainer/HBoxContainer/VBoxContainer"] -offset_top = 48.0 -offset_right = 196.0 -offset_bottom = 52.0 - -[node name="HBoxContainer2" type="HBoxContainer" parent="MarginContainer/HBoxContainer/VBoxContainer"] -offset_top = 56.0 -offset_right = 196.0 -offset_bottom = 100.0 - -[node name="GridContainer3" type="GridContainer" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer2"] -unique_name_in_owner = true -offset_right = 92.0 -offset_bottom = 44.0 -columns = 4 - -[node name="Button17" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer2/GridContainer3" instance=ExtResource("2")] -offset_right = 20.0 -offset_bottom = 20.0 -text = "17" - -[node name="Button18" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer2/GridContainer3" instance=ExtResource("2")] -offset_left = 24.0 -offset_right = 44.0 -offset_bottom = 20.0 -text = "18" - -[node name="Button19" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer2/GridContainer3" instance=ExtResource("2")] -offset_left = 48.0 -offset_right = 68.0 -offset_bottom = 20.0 -text = "19" - -[node name="Button20" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer2/GridContainer3" instance=ExtResource("2")] -offset_left = 72.0 -offset_right = 92.0 -offset_bottom = 20.0 -text = "20" - -[node name="Button21" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer2/GridContainer3" instance=ExtResource("2")] -offset_top = 24.0 -offset_right = 20.0 -offset_bottom = 44.0 -text = "21" - -[node name="Button22" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer2/GridContainer3" instance=ExtResource("2")] -offset_left = 24.0 -offset_top = 24.0 -offset_right = 44.0 -offset_bottom = 44.0 -text = "22" - -[node name="Button23" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer2/GridContainer3" instance=ExtResource("2")] -offset_left = 48.0 -offset_top = 24.0 -offset_right = 68.0 -offset_bottom = 44.0 -text = "23" - -[node name="Button24" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer2/GridContainer3" instance=ExtResource("2")] -offset_left = 72.0 -offset_top = 24.0 -offset_right = 92.0 -offset_bottom = 44.0 -text = "24" - -[node name="VSeparator2" type="VSeparator" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer2"] -offset_left = 96.0 -offset_right = 100.0 -offset_bottom = 44.0 - -[node name="GridContainer4" type="GridContainer" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer2"] -unique_name_in_owner = true -offset_left = 104.0 -offset_right = 196.0 -offset_bottom = 44.0 -columns = 4 - -[node name="Button25" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer2/GridContainer4" instance=ExtResource("2")] -offset_right = 20.0 -offset_bottom = 20.0 -text = "25" - -[node name="Button26" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer2/GridContainer4" instance=ExtResource("2")] -offset_left = 24.0 -offset_right = 44.0 -offset_bottom = 20.0 -text = "26" - -[node name="Button27" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer2/GridContainer4" instance=ExtResource("2")] -offset_left = 48.0 -offset_right = 68.0 -offset_bottom = 20.0 -text = "27" - -[node name="Button28" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer2/GridContainer4" instance=ExtResource("2")] -offset_left = 72.0 -offset_right = 92.0 -offset_bottom = 20.0 -text = "28" - -[node name="Button29" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer2/GridContainer4" instance=ExtResource("2")] -offset_top = 24.0 -offset_right = 20.0 -offset_bottom = 44.0 -text = "29" - -[node name="Button30" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer2/GridContainer4" instance=ExtResource("2")] -offset_left = 24.0 -offset_top = 24.0 -offset_right = 44.0 -offset_bottom = 44.0 -text = "30" - -[node name="Button31" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer2/GridContainer4" instance=ExtResource("2")] -offset_left = 48.0 -offset_top = 24.0 -offset_right = 68.0 -offset_bottom = 44.0 -text = "31" - -[node name="Button32" parent="MarginContainer/HBoxContainer/VBoxContainer/HBoxContainer2/GridContainer4" instance=ExtResource("2")] -offset_left = 72.0 -offset_top = 24.0 -offset_right = 92.0 -offset_bottom = 44.0 -text = "32" - -[node name="VBoxContainer2" type="VBoxContainer" parent="MarginContainer/HBoxContainer"] -offset_left = 1000.0 -offset_right = 1024.0 -offset_bottom = 100.0 -alignment = 1 - -[node name="EnableAll" type="Button" parent="MarginContainer/HBoxContainer/VBoxContainer2"] -offset_right = 24.0 -offset_bottom = 48.0 -size_flags_vertical = 3 -hint_tooltip = "Enable all layers" -focus_mode = 0 -icon = ExtResource("4_h30jm") -flat = true -expand_icon = true - -[node name="ClearButton" type="Button" parent="MarginContainer/HBoxContainer/VBoxContainer2"] -offset_top = 52.0 -offset_right = 24.0 -offset_bottom = 100.0 -size_flags_vertical = 3 -hint_tooltip = "Clear all layers" -focus_mode = 0 -icon = ExtResource("4") -flat = true - -[connection signal="pressed" from="MarginContainer/HBoxContainer/VBoxContainer2/EnableAll" to="." method="_on_enable_all_pressed"] -[connection signal="pressed" from="MarginContainer/HBoxContainer/VBoxContainer2/ClearButton" to="." method="_on_clear_pressed"] diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_bool.gd b/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_bool.gd deleted file mode 100644 index cdd2f2f..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_bool.gd +++ /dev/null @@ -1,23 +0,0 @@ -@tool -extends "base_parameter.gd" - - -@onready var _label: Label = $Label -@onready var _check_box: CheckBox = $CheckBox - - -func _ready() -> void: - # warning-ignore:return_value_discarded - _check_box.connect("toggled", _on_value_changed) - - -func set_parameter_name(text: String) -> void: - _label.text = text - - -func get_value() -> bool: - return _check_box.button_pressed - - -func _set_value(val: bool) -> void: - _check_box.button_pressed = val diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_bool.tscn b/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_bool.tscn deleted file mode 100644 index 49aa944..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_bool.tscn +++ /dev/null @@ -1,21 +0,0 @@ -[gd_scene load_steps=2 format=3 uid="uid://10wqs13p5i3d"] - -[ext_resource type="Script" path="res://addons/proton_scatter/src/stack/inspector_plugin/ui/modifier/components/parameter_bool.gd" id="1"] - -[node name="ParameterScalar" type="HBoxContainer"] -anchor_right = 1.0 -script = ExtResource( "1" ) - -[node name="Label" type="Label" parent="."] -offset_top = 2.0 -offset_right = 996.0 -offset_bottom = 28.0 -size_flags_horizontal = 3 -text = "Parameter name" - -[node name="CheckBox" type="CheckBox" parent="."] -offset_left = 1000.0 -offset_right = 1024.0 -offset_bottom = 31.0 -focus_mode = 0 -mouse_filter = 1 diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_curve.gd b/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_curve.gd deleted file mode 100644 index 763002e..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_curve.gd +++ /dev/null @@ -1,26 +0,0 @@ -@tool -extends "base_parameter.gd" - - -const Util = preload("../../../../../common/util.gd") - - -@onready var _label: Label = $Label -@onready var _panel: Control = $MarginContainer/CurvePanel - - -func set_parameter_name(text: String) -> void: - _label.text = text - - -func get_value() -> String: - return Util.curve_to_string(_panel.get_curve()) - - -func _set_value(val: String) -> void: - var curve = Util.string_to_curve(val) - _panel.set_curve(curve) - - -func _on_curve_updated() -> void: - _on_value_changed(get_value()) diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_curve.tscn b/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_curve.tscn deleted file mode 100644 index c15dd91..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_curve.tscn +++ /dev/null @@ -1,32 +0,0 @@ -[gd_scene load_steps=3 format=3] - -[ext_resource type="Script" path="res://addons/proton_scatter/src/stack/inspector_plugin/ui/modifier/components/parameter_curve.gd" id="1"] -[ext_resource type="Script" path="res://addons/proton_scatter/src/stack/inspector_plugin/ui/modifier/components/curve_panel.gd" id="2"] - -[node name="ParameterCurve" type="VBoxContainer"] -anchor_right = 1.0 -anchor_bottom = 1.0 -script = ExtResource( 1 ) -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="Label" type="Label" parent="."] -margin_right = 1280.0 -margin_bottom = 14.0 -text = "Curve name" - -[node name="MarginContainer" type="MarginContainer" parent="."] -margin_top = 18.0 -margin_right = 1280.0 -margin_bottom = 168.0 - -[node name="CurvePanel" type="PanelContainer" parent="MarginContainer"] -margin_right = 1280.0 -margin_bottom = 150.0 -rect_min_size = Vector2( 0, 150 ) -rect_clip_content = true -script = ExtResource( 2 ) -selected_point_color = Color( 0.878431, 0.47451, 0, 1 ) - -[connection signal="curve_updated" from="MarginContainer/CurvePanel" to="." method="_on_curve_updated"] diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_file.gd b/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_file.gd deleted file mode 100644 index 7f5b9e3..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_file.gd +++ /dev/null @@ -1,54 +0,0 @@ -@tool -extends "base_parameter.gd" - - -@onready var _label: Label = $%Label -@onready var _select_button: Button = $%FileButton -@onready var _dialog: FileDialog = $%FileDialog -@onready var _texture: Button = $%TextureButton -@onready var _preview_root: Control = $%PreviewRoot - -var _path := "" -var _is_texture := false - - -func set_parameter_name(text: String) -> void: - _label.text = text - - -func set_hint_string(hint: String) -> void: - _is_texture = hint == "Texture" - _set_value(get_value()) - - -func _set_value(val: String) -> void: - _path = val - _select_button.text = val.get_file() - _preview_root.visible = false - - if val.is_empty(): - _select_button.text = "Select a file" - - if _is_texture: - var texture = load(get_value()) - if texture is Texture: - _texture.icon = texture - _preview_root.visible = true - - -func get_value() -> String: - return _path - - -func _on_clear_button_pressed() -> void: - _set_value("") - _on_value_changed("") - - -func _on_select_button_pressed() -> void: - _dialog.popup_centered() - - -func _on_file_selected(file: String) -> void: - _set_value(file) - _on_value_changed(file) diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_file.tscn b/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_file.tscn deleted file mode 100644 index 93ec9b2..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_file.tscn +++ /dev/null @@ -1,93 +0,0 @@ -[gd_scene load_steps=3 format=3 uid="uid://cvgj4rdc0mxxq"] - -[ext_resource type="Texture2D" uid="uid://bosx22dy64f11" path="res://addons/proton_scatter/icons/clear.svg" id="1"] -[ext_resource type="Script" path="res://addons/proton_scatter/src/stack/inspector_plugin/ui/modifier/components/parameter_file.gd" id="2"] - -[node name="ParameterFile" type="VBoxContainer"] -anchors_preset = 10 -anchor_right = 1.0 -offset_bottom = 31.0 -size_flags_horizontal = 0 -size_flags_vertical = 0 -theme_override_constants/separation = 0 -script = ExtResource("2") - -[node name="HBoxContainer" type="HBoxContainer" parent="."] -layout_mode = 2 -offset_right = 1152.0 -offset_bottom = 31.0 - -[node name="Label" type="Label" parent="HBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 -offset_top = 2.0 -offset_right = 574.0 -offset_bottom = 28.0 -size_flags_horizontal = 3 -text = "Parameter name" - -[node name="HBoxContainer" type="HBoxContainer" parent="HBoxContainer"] -layout_mode = 2 -offset_left = 578.0 -offset_right = 1152.0 -offset_bottom = 31.0 -size_flags_horizontal = 3 - -[node name="FileButton" type="Button" parent="HBoxContainer/HBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 -offset_right = 546.0 -offset_bottom = 31.0 -size_flags_horizontal = 3 -text = "Select a file" - -[node name="ClearButton" type="Button" parent="HBoxContainer/HBoxContainer"] -layout_mode = 2 -offset_left = 550.0 -offset_right = 574.0 -offset_bottom = 31.0 -icon = ExtResource("1") - -[node name="PreviewRoot" type="HBoxContainer" parent="."] -unique_name_in_owner = true -visible = false -layout_mode = 2 -offset_top = 31.0 -offset_right = 1024.0 -offset_bottom = 39.0 -size_flags_horizontal = 3 - -[node name="Control" type="Control" parent="PreviewRoot"] -layout_mode = 2 -anchors_preset = 0 -offset_right = 1012.0 -offset_bottom = 8.0 -size_flags_horizontal = 3 - -[node name="TextureButton" type="Button" parent="PreviewRoot"] -unique_name_in_owner = true -layout_mode = 2 -offset_left = 1016.0 -offset_right = 1024.0 -offset_bottom = 8.0 -flat = true - -[node name="Control" type="Control" parent="."] -layout_mode = 2 -anchors_preset = 0 -offset_top = 31.0 -offset_right = 1152.0 -offset_bottom = 31.0 - -[node name="FileDialog" type="FileDialog" parent="Control"] -unique_name_in_owner = true -title = "Open a texture file" -size = Vector2i(400, 600) -ok_button_text = "Open" -file_mode = 0 -filters = PackedStringArray("*.bmp", "*.dds", "*.exr", "*.hdr", "*.jpg", "*.jpeg", "*.png", "*.tga", "*.svg", "*.svgz", "*.webp") - -[connection signal="pressed" from="HBoxContainer/HBoxContainer/FileButton" to="." method="_on_select_button_pressed"] -[connection signal="pressed" from="HBoxContainer/HBoxContainer/ClearButton" to="." method="_on_clear_button_pressed"] -[connection signal="pressed" from="PreviewRoot/TextureButton" to="." method="_on_select_button_pressed"] -[connection signal="file_selected" from="Control/FileDialog" to="." method="_on_file_selected"] diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_node_selector.gd b/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_node_selector.gd deleted file mode 100644 index b9353e4..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_node_selector.gd +++ /dev/null @@ -1,86 +0,0 @@ -@tool -extends "base_parameter.gd" - - -@onready var _label: Label = $%Label -@onready var _select_button: Button = $%SelectButton -@onready var _clear_button: Button = $%ClearButton -@onready var _popup: ConfirmationDialog = $%ConfirmationDialog -@onready var _tree: Tree = $%Tree - -var _full_path: NodePath -var _root: Node -var _selected: Node - - -func set_root(root) -> void: - _root = root - - -func set_parameter_name(text: String) -> void: - _label.text = text - - -func _set_value(val) -> void: - if val == null: - return - - _full_path = val - - if val.is_empty(): - return - - _select_button.text = val.get_name(val.get_name_count() - 1) - - if _root and _root.has_node(val): - _selected = _root.get_node(val) - - if val.is_empty(): - _select_button.text = "Select a node" - - -func get_value() -> NodePath: - #if _root and _selected: - # _full_path = String(_root.get_path_to(_selected)) - return _full_path - - -func _populate_tree() -> void: - _tree.clear() - var scene_root: Node = get_tree().get_edited_scene_root() - - var tmp = EditorPlugin.new() # TODO: check if this works in release builds - var gui: Control = tmp.get_editor_interface().get_base_control() - var editor_theme = gui.get_theme() - tmp.queue_free() - - _create_items_recursive(scene_root, null, editor_theme) - - -func _create_items_recursive(node, parent, theme) -> void: - if parent and not node.owner: - return # Hidden node. - - var node_item = _tree.create_item(parent) - node_item.set_text(0, node.get_name()) - node_item.set_meta("node", node) - node_item.set_icon(0, theme.get_icon(node.get_class(), "EditorIcons")) - - for child in node.get_children(): - _create_items_recursive(child, node_item, theme) - - -func _on_select_button_pressed() -> void: - _populate_tree() - _popup.popup_centered(Vector2i(400, 600)) - - -func _on_clear_button_pressed() -> void: - _select_button.text = "Select a node" - _full_path = NodePath() - - -func _on_node_selected(): - var node = _tree.get_selected().get_meta("node") - _set_value(_root.get_path_to(node)) - _on_value_changed(get_value()) diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_node_selector.tscn b/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_node_selector.tscn deleted file mode 100644 index baaff4b..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_node_selector.tscn +++ /dev/null @@ -1,66 +0,0 @@ -[gd_scene load_steps=3 format=3 uid="uid://bku7i3ct7ftui"] - -[ext_resource type="Texture2D" uid="uid://bosx22dy64f11" path="res://addons/proton_scatter/icons/clear.svg" id="1"] -[ext_resource type="Script" path="res://addons/proton_scatter/src/stack/inspector_plugin/ui/modifier/components/parameter_node_selector.gd" id="2"] - -[node name="NodeSelector" type="MarginContainer"] -anchors_preset = 10 -anchor_right = 1.0 -script = ExtResource("2") - -[node name="HBoxContainer" type="HBoxContainer" parent="."] -layout_mode = 2 -offset_right = 1152.0 -offset_bottom = 31.0 - -[node name="Label" type="Label" parent="HBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 -offset_top = 2.0 -offset_right = 560.0 -offset_bottom = 28.0 -size_flags_horizontal = 3 -text = "Parameter name" - -[node name="SelectButton" type="Button" parent="HBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 -offset_left = 564.0 -offset_right = 1124.0 -offset_bottom = 31.0 -size_flags_horizontal = 3 -text = "Select Node" -flat = true - -[node name="ClearButton" type="Button" parent="HBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 -offset_left = 1128.0 -offset_right = 1152.0 -offset_bottom = 31.0 -icon = ExtResource("1") - -[node name="ConfirmationDialog" type="ConfirmationDialog" parent="."] -unique_name_in_owner = true -size = Vector2i(400, 500) - -[node name="ScrollContainer" type="ScrollContainer" parent="ConfirmationDialog"] -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -offset_left = 8.0 -offset_top = 8.0 -offset_right = -960.0 -offset_bottom = -597.0 - -[node name="Tree" type="Tree" parent="ConfirmationDialog/ScrollContainer"] -unique_name_in_owner = true -layout_mode = 2 -offset_right = 184.0 -offset_bottom = 43.0 -size_flags_horizontal = 3 -size_flags_vertical = 3 - -[connection signal="pressed" from="HBoxContainer/SelectButton" to="." method="_on_select_button_pressed"] -[connection signal="pressed" from="HBoxContainer/ClearButton" to="." method="_on_clear_button_pressed"] -[connection signal="confirmed" from="ConfirmationDialog" to="." method="_on_node_selected"] diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_scalar.gd b/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_scalar.gd deleted file mode 100644 index 19871da..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_scalar.gd +++ /dev/null @@ -1,114 +0,0 @@ -# warning-ignore-all:return_value_discarded - -@tool -extends "base_parameter.gd" - - -var _is_int := false -var _is_enum := false - -@onready var _label: Label = $Label -@onready var _spinbox: SpinBox = $%SpinBox -@onready var _option: OptionButton = $%OptionButton - - -func _ready() -> void: - _spinbox.value_changed.connect(_on_value_changed) - _option.item_selected.connect(_on_value_changed) - mark_as_int(_is_int) - - -func mark_as_int(val: bool) -> void: - _is_int = val - if _is_int and _spinbox: - _spinbox.step = 1 - - -func mark_as_enum(val: bool) -> void: - _is_enum = val - - -func toggle_option_item(idx: int, value := false) -> void: - _option.set_item_disabled(idx, not value) - - -func set_parameter_name(text: String) -> void: - _label.text = text - - -func set_hint_string(hint: String) -> void: - # No hint provided, ignore. - if hint.is_empty(): - return - - if hint == "float": - _spinbox.step = 0.01 - return - - if hint == "int": - _spinbox.step = 1 - return - - # One integer provided - if hint.is_valid_int(): - _set_range(0, hint.to_int()) - return - - # Multiple items provided, check their types - var tokens = hint.split(",") - var all_int = true - var all_float = true - - for t in tokens: - if not t.is_valid_int(): - all_int = false - if not t.is_valid_float(): - all_float = false - - # All items are integer - if all_int and tokens.size() >= 2: - _set_range(tokens[0].to_int(), tokens[1].to_int()) - return - - # All items are float - if all_float: - if tokens.size() >= 2: - _set_range(tokens[0].to_float(), tokens[1].to_float()) - if tokens.size() >= 3: - _spinbox.step = tokens[2].to_float() - return - - # All items are strings, make it a dropdown - _spinbox.visible = false - _option.visible = true - _is_enum = true - _is_int = true - - for i in tokens.size(): - _option.add_item(tokens[i], i) - set_value(int(_spinbox.get_value())) - - -func get_value(): - if _is_enum: - return _option.get_selected_id() - if _is_int: - return int(_spinbox.get_value()) - return _spinbox.get_value() - - -func _set_value(val) -> void: - if _is_int: - val = int(val) - if _is_enum: - _option.select(val) - else: - _spinbox.set_value(val) - - -func _set_range(start, end) -> void: - if start < end: - _spinbox.min_value = start - _spinbox.max_value = end - _spinbox.allow_greater = false - _spinbox.allow_lesser = false diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_scalar.tscn b/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_scalar.tscn deleted file mode 100644 index dce7fe4..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_scalar.tscn +++ /dev/null @@ -1,55 +0,0 @@ -[gd_scene load_steps=2 format=3 uid="uid://bspbhkrpgak0e"] - -[ext_resource type="Script" path="res://addons/proton_scatter/src/stack/inspector_plugin/ui/modifier/components/parameter_scalar.gd" id="1"] - -[node name="ParameterScalar" type="HBoxContainer"] -anchors_preset = 10 -anchor_right = 1.0 -script = ExtResource("1") - -[node name="Label" type="Label" parent="."] -layout_mode = 2 -offset_top = 2.0 -offset_right = 1833.0 -offset_bottom = 28.0 -size_flags_horizontal = 3 -text = "Parameter name" - -[node name="MarginContainer" type="MarginContainer" parent="."] -layout_mode = 2 -offset_left = 1837.0 -offset_right = 1920.0 -offset_bottom = 31.0 -mouse_filter = 2 - -[node name="Panel" type="Panel" parent="MarginContainer"] -visible = false -layout_mode = 2 -offset_right = 83.0 -offset_bottom = 31.0 -mouse_filter = 2 - -[node name="MarginContainer" type="MarginContainer" parent="MarginContainer"] -layout_mode = 2 -offset_right = 83.0 -offset_bottom = 31.0 -mouse_filter = 2 - -[node name="SpinBox" type="SpinBox" parent="MarginContainer/MarginContainer"] -unique_name_in_owner = true -layout_mode = 2 -offset_right = 83.0 -offset_bottom = 31.0 -mouse_filter = 1 -min_value = -100.0 -step = 0.001 -allow_greater = true -allow_lesser = true - -[node name="OptionButton" type="OptionButton" parent="MarginContainer/MarginContainer"] -unique_name_in_owner = true -visible = false -layout_mode = 2 -offset_right = 83.0 -offset_bottom = 31.0 -focus_mode = 0 diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_string.gd b/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_string.gd deleted file mode 100644 index 390d07d..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_string.gd +++ /dev/null @@ -1,27 +0,0 @@ -@tool -extends "base_parameter.gd" - - -@onready var _label: Label = $Label -@onready var _line_edit: LineEdit = $MarginContainer/MarginContainer/LineEdit - - -func _ready() -> void: - _line_edit.connect("text_entered", _on_value_changed) - _line_edit.connect("focus_exited", _on_focus_exited) - - -func set_parameter_name(text: String) -> void: - _label.text = text - - -func _set_value(val: String) -> void: - _line_edit.text = val - - -func get_value() -> String: - return _line_edit.get_text() - - -func _on_focus_exited() -> void: - _on_value_changed(get_value()) diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_string.tscn b/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_string.tscn deleted file mode 100644 index 00fbce5..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_string.tscn +++ /dev/null @@ -1,56 +0,0 @@ -[gd_scene load_steps=4 format=3] - -[ext_resource type="Script" path="res://addons/proton_scatter/src/stack/inspector_plugin/ui/modifier/components/parameter_string.gd" id="1"] - -[sub_resource type="StyleBoxFlat" id=1] -bg_color = Color( 0, 0, 0, 0.392157 ) - -[sub_resource type="StyleBoxFlat" id=2] -bg_color = Color( 0.6, 0.6, 0.6, 0 ) - -[node name="ParameterString" type="HBoxContainer"] -anchor_right = 1.0 -script = ExtResource( 1 ) -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="Label" type="Label" parent="."] -margin_top = 2.0 -margin_right = 638.0 -margin_bottom = 16.0 -size_flags_horizontal = 3 -text = "Parameter name" -valign = 1 - -[node name="MarginContainer" type="MarginContainer" parent="."] -margin_left = 642.0 -margin_right = 1280.0 -margin_bottom = 18.0 -mouse_filter = 2 -size_flags_horizontal = 3 - -[node name="Panel" type="Panel" parent="MarginContainer"] -margin_right = 638.0 -margin_bottom = 18.0 -mouse_filter = 2 -custom_styles/panel = SubResource( 1 ) - -[node name="MarginContainer" type="MarginContainer" parent="MarginContainer"] -margin_right = 638.0 -margin_bottom = 18.0 -mouse_filter = 2 -custom_constants/margin_right = 4 -custom_constants/margin_top = 2 -custom_constants/margin_left = 4 -custom_constants/margin_bottom = 2 - -[node name="LineEdit" type="LineEdit" parent="MarginContainer/MarginContainer"] -margin_left = 4.0 -margin_top = 2.0 -margin_right = 634.0 -margin_bottom = 16.0 -mouse_filter = 1 -custom_styles/focus = SubResource( 2 ) -custom_styles/normal = SubResource( 2 ) -clear_button_enabled = true diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_vector2.gd b/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_vector2.gd deleted file mode 100644 index 7a90a73..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_vector2.gd +++ /dev/null @@ -1,47 +0,0 @@ -# warning-ignore-all:return_value_discarded - -@tool -extends "base_parameter.gd" - - -@onready var _label: Label = $Label -@onready var _x: SpinBox = $%X -@onready var _y: SpinBox = $%Y -@onready var _link: Button = $%LinkButton - - -func _ready() -> void: - _x.value_changed.connect(_on_spinbox_value_changed) - _y.value_changed.connect(_on_spinbox_value_changed) - - -func set_parameter_name(text: String) -> void: - _label.text = text - - -func get_value() -> Vector2: - var vec2 = Vector2.ZERO - vec2.x = _x.get_value() - vec2.y = _y.get_value() - return vec2 - - -func _set_value(val: Vector2) -> void: - _x.set_value(val.x) - _y.set_value(val.y) - - -func _on_clear_pressed(): - var old = get_value() - set_value(Vector2.ZERO) - _previous = old - _on_value_changed(Vector2.ZERO) - - -func _on_spinbox_value_changed(value: float) -> void: - if _link.button_pressed: - var old = get_value() - set_value(Vector2(value, value)) - _previous = old - - _on_value_changed(get_value()) diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_vector2.tscn b/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_vector2.tscn deleted file mode 100644 index b7cf67d..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_vector2.tscn +++ /dev/null @@ -1,136 +0,0 @@ -[gd_scene load_steps=4 format=3 uid="uid://bjn8ydwp80y7q"] - -[ext_resource type="Script" path="res://addons/proton_scatter/src/stack/inspector_plugin/ui/modifier/components/parameter_vector2.gd" id="1"] -[ext_resource type="Texture2D" uid="uid://bosx22dy64f11" path="res://addons/proton_scatter/icons/clear.svg" id="2"] -[ext_resource type="Texture2D" uid="uid://dbn0ytoameq8f" path="res://addons/proton_scatter/icons/link.svg" id="3_u2lry"] - -[node name="ParameterVector2" type="HBoxContainer"] -anchor_right = 1.0 -script = ExtResource("1") - -[node name="Label" type="Label" parent="."] -offset_right = 884.0 -offset_bottom = 66.0 -size_flags_horizontal = 3 -size_flags_vertical = 5 -text = "Parameter name" - -[node name="MarginContainer" type="MarginContainer" parent="."] -offset_left = 888.0 -offset_right = 1024.0 -offset_bottom = 66.0 -size_flags_horizontal = 0 -mouse_filter = 2 - -[node name="Panel" type="Panel" parent="MarginContainer"] -offset_right = 136.0 -offset_bottom = 66.0 -mouse_filter = 2 - -[node name="MarginContainer" type="MarginContainer" parent="MarginContainer"] -offset_right = 136.0 -offset_bottom = 66.0 -size_flags_horizontal = 0 -size_flags_vertical = 4 -mouse_filter = 2 -theme_override_constants/margin_left = 6 -theme_override_constants/margin_right = 6 - -[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/MarginContainer"] -offset_left = 6.0 -offset_right = 130.0 -offset_bottom = 66.0 - -[node name="GridContainer" type="GridContainer" parent="MarginContainer/MarginContainer/HBoxContainer"] -offset_right = 96.0 -offset_bottom = 66.0 - -[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/MarginContainer/HBoxContainer/GridContainer"] -offset_right = 96.0 -offset_bottom = 31.0 - -[node name="Label" type="Label" parent="MarginContainer/MarginContainer/HBoxContainer/GridContainer/HBoxContainer"] -modulate = Color(1, 0.447059, 0.368627, 1) -offset_top = 2.0 -offset_right = 9.0 -offset_bottom = 28.0 -text = "x" - -[node name="X" type="SpinBox" parent="MarginContainer/MarginContainer/HBoxContainer/GridContainer/HBoxContainer"] -unique_name_in_owner = true -offset_left = 13.0 -offset_right = 96.0 -offset_bottom = 31.0 -mouse_filter = 1 -min_value = -100.0 -step = 0.001 -allow_greater = true -allow_lesser = true - -[node name="HBoxContainer2" type="HBoxContainer" parent="MarginContainer/MarginContainer/HBoxContainer/GridContainer"] -offset_top = 35.0 -offset_right = 96.0 -offset_bottom = 66.0 - -[node name="Label" type="Label" parent="MarginContainer/MarginContainer/HBoxContainer/GridContainer/HBoxContainer2"] -modulate = Color(0.564706, 0.992157, 0.298039, 1) -offset_top = 2.0 -offset_right = 9.0 -offset_bottom = 28.0 -text = "y" - -[node name="Y" type="SpinBox" parent="MarginContainer/MarginContainer/HBoxContainer/GridContainer/HBoxContainer2"] -unique_name_in_owner = true -offset_left = 13.0 -offset_right = 96.0 -offset_bottom = 31.0 -mouse_filter = 1 -min_value = -100.0 -step = 0.001 -allow_greater = true -allow_lesser = true - -[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/MarginContainer/HBoxContainer"] -offset_left = 100.0 -offset_right = 124.0 -offset_bottom = 66.0 - -[node name="Control" type="Control" parent="MarginContainer/MarginContainer/HBoxContainer/VBoxContainer"] -offset_right = 24.0 -size_flags_vertical = 3 - -[node name="ClearButton" type="Button" parent="MarginContainer/MarginContainer/HBoxContainer/VBoxContainer"] -offset_top = 4.0 -offset_right = 24.0 -offset_bottom = 28.0 -size_flags_vertical = 4 -focus_mode = 0 -mouse_filter = 1 -icon = ExtResource("2") -flat = true - -[node name="Control2" type="Control" parent="MarginContainer/MarginContainer/HBoxContainer/VBoxContainer"] -offset_top = 32.0 -offset_right = 24.0 -offset_bottom = 33.0 -size_flags_vertical = 3 - -[node name="LinkButton" type="Button" parent="MarginContainer/MarginContainer/HBoxContainer/VBoxContainer"] -unique_name_in_owner = true -offset_top = 37.0 -offset_right = 24.0 -offset_bottom = 61.0 -size_flags_vertical = 4 -focus_mode = 0 -mouse_filter = 1 -toggle_mode = true -icon = ExtResource("3_u2lry") -flat = true - -[node name="Control3" type="Control" parent="MarginContainer/MarginContainer/HBoxContainer/VBoxContainer"] -offset_top = 65.0 -offset_right = 24.0 -offset_bottom = 66.0 -size_flags_vertical = 3 - -[connection signal="pressed" from="MarginContainer/MarginContainer/HBoxContainer/VBoxContainer/ClearButton" to="." method="_on_clear_pressed"] diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_vector3.gd b/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_vector3.gd deleted file mode 100644 index 55678c9..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_vector3.gd +++ /dev/null @@ -1,49 +0,0 @@ -@tool -extends "base_parameter.gd" - - -@onready var _label: Label = $Label -@onready var _x: SpinBox = $%X -@onready var _y: SpinBox = $%Y -@onready var _z: SpinBox = $%Z -@onready var _link: Button = $%LinkButton - - -func _ready() -> void: - _x.value_changed.connect(_on_spinbox_value_changed) - _y.value_changed.connect(_on_spinbox_value_changed) - _z.value_changed.connect(_on_spinbox_value_changed) - - -func set_parameter_name(text: String) -> void: - _label.text = text - - -func get_value() -> Vector3: - var vec3 = Vector3.ZERO - vec3.x = _x.get_value() - vec3.y = _y.get_value() - vec3.z = _z.get_value() - return vec3 - - -func _set_value(val: Vector3) -> void: - _x.set_value(val.x) - _y.set_value(val.y) - _z.set_value(val.z) - - -func _on_clear_pressed(): - var old = get_value() - set_value(Vector3.ZERO) - _previous = old - _on_value_changed(Vector3.ZERO) - - -func _on_spinbox_value_changed(value: float) -> void: - if _link.button_pressed: - var old = get_value() - set_value(Vector3(value, value, value)) - _previous = old - - _on_value_changed(get_value()) diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_vector3.tscn b/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_vector3.tscn deleted file mode 100644 index 463f697..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/components/parameter_vector3.tscn +++ /dev/null @@ -1,162 +0,0 @@ -[gd_scene load_steps=4 format=3 uid="uid://cdpfgf0447ph4"] - -[ext_resource type="Script" path="res://addons/proton_scatter/src/stack/inspector_plugin/ui/modifier/components/parameter_vector3.gd" id="1"] -[ext_resource type="Texture2D" uid="uid://bosx22dy64f11" path="res://addons/proton_scatter/icons/clear.svg" id="2"] -[ext_resource type="Texture2D" uid="uid://dbn0ytoameq8f" path="res://addons/proton_scatter/icons/link.svg" id="3_gq2ti"] - -[node name="ParameterVector3" type="HBoxContainer"] -anchor_right = 1.0 -script = ExtResource("1") - -[node name="Label" type="Label" parent="."] -offset_right = 884.0 -offset_bottom = 101.0 -size_flags_horizontal = 3 -size_flags_vertical = 5 -text = "Parameter name" - -[node name="MarginContainer" type="MarginContainer" parent="."] -offset_left = 888.0 -offset_right = 1024.0 -offset_bottom = 101.0 -size_flags_horizontal = 0 -mouse_filter = 2 - -[node name="Panel" type="Panel" parent="MarginContainer"] -offset_right = 136.0 -offset_bottom = 101.0 -mouse_filter = 2 - -[node name="MarginContainer" type="MarginContainer" parent="MarginContainer"] -offset_right = 136.0 -offset_bottom = 101.0 -size_flags_horizontal = 0 -size_flags_vertical = 4 -mouse_filter = 2 -theme_override_constants/margin_left = 6 -theme_override_constants/margin_right = 6 - -[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/MarginContainer"] -offset_left = 6.0 -offset_right = 130.0 -offset_bottom = 101.0 - -[node name="GridContainer" type="GridContainer" parent="MarginContainer/MarginContainer/HBoxContainer"] -offset_right = 96.0 -offset_bottom = 101.0 - -[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/MarginContainer/HBoxContainer/GridContainer"] -offset_right = 96.0 -offset_bottom = 31.0 - -[node name="Label" type="Label" parent="MarginContainer/MarginContainer/HBoxContainer/GridContainer/HBoxContainer"] -modulate = Color(1, 0.447059, 0.368627, 1) -offset_top = 2.0 -offset_right = 9.0 -offset_bottom = 28.0 -text = "x" - -[node name="X" type="SpinBox" parent="MarginContainer/MarginContainer/HBoxContainer/GridContainer/HBoxContainer"] -unique_name_in_owner = true -offset_left = 13.0 -offset_right = 96.0 -offset_bottom = 31.0 -mouse_filter = 1 -min_value = -100.0 -step = 0.001 -allow_greater = true -allow_lesser = true - -[node name="HBoxContainer2" type="HBoxContainer" parent="MarginContainer/MarginContainer/HBoxContainer/GridContainer"] -offset_top = 35.0 -offset_right = 96.0 -offset_bottom = 66.0 - -[node name="Label" type="Label" parent="MarginContainer/MarginContainer/HBoxContainer/GridContainer/HBoxContainer2"] -modulate = Color(0.564706, 0.992157, 0.298039, 1) -offset_top = 2.0 -offset_right = 9.0 -offset_bottom = 28.0 -text = "y" - -[node name="Y" type="SpinBox" parent="MarginContainer/MarginContainer/HBoxContainer/GridContainer/HBoxContainer2"] -unique_name_in_owner = true -offset_left = 13.0 -offset_right = 96.0 -offset_bottom = 31.0 -mouse_filter = 1 -min_value = -100.0 -step = 0.001 -allow_greater = true -allow_lesser = true - -[node name="HBoxContainer3" type="HBoxContainer" parent="MarginContainer/MarginContainer/HBoxContainer/GridContainer"] -offset_top = 70.0 -offset_right = 96.0 -offset_bottom = 101.0 - -[node name="Label" type="Label" parent="MarginContainer/MarginContainer/HBoxContainer/GridContainer/HBoxContainer3"] -modulate = Color(0.14902, 0.8, 1, 1) -offset_top = 2.0 -offset_right = 8.0 -offset_bottom = 28.0 -text = "z" - -[node name="Z" type="SpinBox" parent="MarginContainer/MarginContainer/HBoxContainer/GridContainer/HBoxContainer3"] -unique_name_in_owner = true -offset_left = 12.0 -offset_right = 95.0 -offset_bottom = 31.0 -mouse_filter = 1 -min_value = -100.0 -step = 0.001 -allow_greater = true -allow_lesser = true - -[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/MarginContainer/HBoxContainer"] -offset_left = 100.0 -offset_right = 124.0 -offset_bottom = 101.0 -size_flags_vertical = 3 -alignment = 1 - -[node name="Control3" type="Control" parent="MarginContainer/MarginContainer/HBoxContainer/VBoxContainer"] -offset_right = 24.0 -offset_bottom = 12.0 -size_flags_vertical = 3 - -[node name="ClearButton" type="Button" parent="MarginContainer/MarginContainer/HBoxContainer/VBoxContainer"] -offset_top = 16.0 -offset_right = 24.0 -offset_bottom = 40.0 -size_flags_vertical = 4 -focus_mode = 0 -mouse_filter = 1 -icon = ExtResource("2") -flat = true - -[node name="Control" type="Control" parent="MarginContainer/MarginContainer/HBoxContainer/VBoxContainer"] -offset_top = 44.0 -offset_right = 24.0 -offset_bottom = 56.0 -size_flags_vertical = 3 - -[node name="LinkButton" type="Button" parent="MarginContainer/MarginContainer/HBoxContainer/VBoxContainer"] -unique_name_in_owner = true -offset_top = 60.0 -offset_right = 24.0 -offset_bottom = 84.0 -size_flags_vertical = 4 -focus_mode = 0 -mouse_filter = 1 -toggle_mode = true -icon = ExtResource("3_gq2ti") -flat = true - -[node name="Control2" type="Control" parent="MarginContainer/MarginContainer/HBoxContainer/VBoxContainer"] -offset_top = 88.0 -offset_right = 24.0 -offset_bottom = 101.0 -size_flags_vertical = 3 - -[connection signal="pressed" from="MarginContainer/MarginContainer/HBoxContainer/VBoxContainer/ClearButton" to="." method="_on_clear_pressed"] diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/drag_container.gd b/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/drag_container.gd deleted file mode 100644 index 5b9957b..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/drag_container.gd +++ /dev/null @@ -1,93 +0,0 @@ -@tool -extends Container - -# DragContainer -# Custom containner similar to a VBoxContainer, but the user can rearrange the -# children order via drag and drop. This is only used in the inspector plugin -# for the modifier stack and won't work with arbitrary control nodes. - - -signal child_moved(last_index: int, new_index: int) - - -var _separation: int = 0 -var _drag_offset = null -var _dragged_child = null -var _old_index: int -var _new_index: int -var _map := [] # Stores the y top position of each child in the stack - - -func _ready() -> void: - _separation = get_theme_constant("separation", "VBoxContainer") - - -func _notification(what): - if what == NOTIFICATION_SORT_CHILDREN or what == NOTIFICATION_RESIZED: - _update_layout() - - -func _can_drop_data(at_position, data) -> bool: - if data.get_parent() != self: - return false - - # Drag just started - if not _dragged_child: - _dragged_child = data - _drag_offset = at_position - data.position - _old_index = data.get_index() - _new_index = _old_index - - # Dragged control only follow the y mouse position - data.position.y = at_position.y - _drag_offset.y - - # Check if the children order should be changed - var computed_index = 0 - for pos_y in _map: - if pos_y > data.position.y - 16: - break - computed_index += 1 - - if computed_index != data.get_index(): - move_child(data, computed_index) - _new_index = computed_index - - return true - - -# Called once at the end of the drag -func _drop_data(at_position, data) -> void: - _drag_offset = null - _dragged_child = null - _update_layout() - - if _old_index != _new_index: - child_moved.emit(_old_index, _new_index) - - -# Detects if the user drops the children outside the container and treats it -# as if the drop happened the moment the mouse left the container. -func _unhandled_input(event): - if not _dragged_child: - return - - if event is InputEventMouseButton and not event.pressed: - _drop_data(_dragged_child.position, _dragged_child) - - -func _update_layout() -> void: - _map.clear() - var offset := Vector2.ZERO - - for c in get_children(): - if c is Control: - _map.push_back(offset.y) - var child_min_size = c.get_combined_minimum_size() - var possible_space = Rect2(offset, Vector2(size.x, child_min_size.y)) - - if c != _dragged_child: - fit_child_in_rect(c, possible_space) - - offset.y += c.size.y + _separation - - custom_minimum_size.y = offset.y - _separation diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/modifier_panel.gd b/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/modifier_panel.gd deleted file mode 100644 index 8291a19..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/modifier_panel.gd +++ /dev/null @@ -1,201 +0,0 @@ -@tool -extends Control - - -signal value_changed -signal removed -signal documentation_requested -signal duplication_requested - - -const ParameterBool := preload("./components/parameter_bool.tscn") -const ParameterScalar := preload("./components/parameter_scalar.tscn") -const ParameterNodeSelector = preload("./components/parameter_node_selector.tscn") -const ParameterFile = preload("./components/parameter_file.tscn") -const ParameterCurve = preload("./components/parameter_curve.tscn") -const ParameterBitmask = preload("./components/parameter_bitmask.tscn") -const ParameterString = preload("./components/parameter_string.tscn") -const ParameterVector3 = preload("./components/parameter_vector3.tscn") -const ParameterVector2 = preload("./components/parameter_vector2.tscn") -const PARAMETER_IGNORE_LIST := [ - "enabled", - "override_global_seed", - "custom_seed", - "restrict_height", - "reference_frame", - ] - -var _scatter -var _modifier - -@onready var _parameters: Control = $%ParametersRoot -@onready var _name: Label = $%ModifierName -@onready var _expand: Button = $%Expand -@onready var _enabled: Button = $%Enabled -@onready var _remove: Button = $%Remove -@onready var _warning: Button = $%Warning -@onready var _warning_dialog: AcceptDialog = $WarningDialog -@onready var _drag_control: Control = $%DragControl -@onready var _override_ui = $%OverrideGlobalSeed -@onready var _custom_seed_ui = $%CustomSeed -@onready var _restrict_height_ui = $%RestrictHeight -@onready var _transform_space_ui = $%TransformSpace - - -func _ready() -> void: - _name.text = name - _enabled.toggled.connect(_on_enable_toggled) - _remove.pressed.connect(_on_remove_pressed) - _warning.pressed.connect(_on_warning_icon_pressed) - _expand.toggled.connect(_on_expand_toggled) - $%MenuButton.get_popup().id_pressed.connect(_on_menu_item_pressed) - - -func _get_drag_data(at_position: Vector2): - var drag_control_position = _drag_control.global_position - global_position - var drag_rect := Rect2(drag_control_position, _drag_control.size) - if drag_rect.has_point(at_position): - return self - - return null - - -func set_root(val) -> void: - _scatter = val - - -# Loops through all exposed parameters and create an UI component for each of -# them. For special properties (listed in PARAMATER_IGNORE_LIST), a special -# UI is created. -func create_ui_for(modifier) -> void: - _modifier = modifier - _modifier.warning_changed.connect(_on_warning_changed) - _on_warning_changed() - - _name.text = modifier.display_name - _enabled.button_pressed = modifier.enabled - - # Enable or disable irrelevant controls for this modifier - _override_ui.enable(modifier.can_override_seed) - _restrict_height_ui.enable(modifier.can_restrict_height) - _transform_space_ui.mark_as_enum(true) - _transform_space_ui.toggle_option_item(0, modifier.global_reference_frame_available) - _transform_space_ui.toggle_option_item(1, modifier.local_reference_frame_available) - _transform_space_ui.toggle_option_item(2, modifier.individual_instances_reference_frame_available) - if not modifier.global_reference_frame_available and \ - not modifier.local_reference_frame_available and \ - not modifier.individual_instances_reference_frame_available: - _transform_space_ui.visible = false - - # Setup header connections - _override_ui.value_changed.connect(_on_parameter_value_changed.bind("override_global_seed", _override_ui)) - _custom_seed_ui.value_changed.connect(_on_parameter_value_changed.bind("custom_seed", _custom_seed_ui)) - _restrict_height_ui.value_changed.connect(_on_parameter_value_changed.bind("restrict_height", _restrict_height_ui)) - _transform_space_ui.value_changed.connect(_on_parameter_value_changed.bind("reference_frame", _transform_space_ui)) - - # Restore header values - _override_ui.set_value(modifier.override_global_seed) - _custom_seed_ui.set_value(modifier.custom_seed) - _restrict_height_ui.set_value(modifier.restrict_height) - _transform_space_ui.set_value(modifier.reference_frame) - - # Loop over the other properties and create a ui component for each of them - for property in modifier.get_property_list(): - if property.usage != PROPERTY_USAGE_DEFAULT + PROPERTY_USAGE_SCRIPT_VARIABLE: - continue - - if property.name in PARAMETER_IGNORE_LIST: - continue - - var parameter_ui - match property.type: - TYPE_BOOL: - parameter_ui = ParameterBool.instantiate() - TYPE_FLOAT: - parameter_ui = ParameterScalar.instantiate() - TYPE_INT: - if property.hint == PROPERTY_HINT_LAYERS_3D_PHYSICS: - parameter_ui = ParameterBitmask.instantiate() - else: - parameter_ui = ParameterScalar.instantiate() - parameter_ui.mark_as_int(true) - TYPE_STRING: - if property.hint_string == "File" or property.hint_string == "Texture": - parameter_ui = ParameterFile.instantiate() - elif property.hint_string == "Curve": - parameter_ui = ParameterCurve.instantiate() - else: - parameter_ui = ParameterString.instantiate() - TYPE_VECTOR3: - parameter_ui = ParameterVector3.instantiate() - TYPE_VECTOR2: - parameter_ui = ParameterVector2.instantiate() - TYPE_NODE_PATH: - parameter_ui = ParameterNodeSelector.instantiate() - parameter_ui.set_root(_scatter) - - if parameter_ui: - _parameters.add_child(parameter_ui) - parameter_ui.set_parameter_name(property.name.capitalize()) - parameter_ui.set_value(modifier.get(property.name)) - parameter_ui.set_hint_string(property.hint_string) - parameter_ui.value_changed.connect(_on_parameter_value_changed.bind(property.name, parameter_ui)) - - _expand.button_pressed = _modifier.expanded - - -func _restore_value(name, val, ui) -> void: - _modifier.set(name, val) - ui.set_value(val) - value_changed.emit() - - -func _on_expand_toggled(toggled: bool) -> void: - $%ParametersContainer.visible = toggled - _modifier.expanded = toggled - - -func _on_remove_pressed() -> void: - removed.emit() - - -func _on_parameter_value_changed(value, previous, parameter_name, ui) -> void: - if _scatter.undo_redo: - _scatter.undo_redo.create_action("Change value " + parameter_name.capitalize()) - _scatter.undo_redo.add_undo_method(self, "_restore_value", parameter_name, previous, ui) - _scatter.undo_redo.add_do_method(self, "_restore_value", parameter_name, value, ui) - _scatter.undo_redo.commit_action() - else: - _modifier.set(parameter_name, value) - value_changed.emit() - - -func _on_enable_toggled(pressed: bool): - _modifier.enabled = pressed - value_changed.emit() - - -func _on_removed_pressed() -> void: - removed.emit() - - -func _on_warning_changed() -> void: - var warning = _modifier.get_warning() - _warning.visible = (warning != "") - _warning_dialog.dialog_text = warning - - -func _on_warning_icon_pressed() -> void: - _warning_dialog.popup_centered() - - -func _on_menu_item_pressed(id) -> void: - match id: - 0: - documentation_requested.emit() - 2: - duplication_requested.emit() - 3: - _on_remove_pressed() - _: - pass diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/modifier_panel.tscn b/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/modifier_panel.tscn deleted file mode 100644 index f679c1d..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/modifier_panel.tscn +++ /dev/null @@ -1,352 +0,0 @@ -[gd_scene load_steps=21 format=3 uid="uid://blpobpd0eweog"] - -[ext_resource type="Script" path="res://addons/proton_scatter/src/stack/inspector_plugin/ui/modifier/modifier_panel.gd" id="1"] -[ext_resource type="Texture2D" uid="uid://hshxh8s6k677" path="res://addons/proton_scatter/icons/arrow_right.svg" id="2_2djuo"] -[ext_resource type="Script" path="res://addons/proton_scatter/src/stack/inspector_plugin/ui/modifier/toggle_button.gd" id="4"] -[ext_resource type="Texture2D" uid="uid://85r2q2fd8gyh" path="res://addons/proton_scatter/icons/arrow_down.svg" id="4_7nlfc"] -[ext_resource type="Texture2D" uid="uid://dahwdjl2er75o" path="res://addons/proton_scatter/icons/close.svg" id="5"] -[ext_resource type="Texture2D" uid="uid://n66mufjib4ds" path="res://addons/proton_scatter/icons/menu.svg" id="6_lmo8k"] -[ext_resource type="Texture2D" uid="uid://dpigmdo0x73yb" path="res://addons/proton_scatter/icons/duplicate.svg" id="7_f6nan"] -[ext_resource type="Texture2D" uid="uid://cnwg3p2m4lbf3" path="res://addons/proton_scatter/icons/doc.svg" id="7_owhij"] -[ext_resource type="Texture2D" uid="uid://dj0y6peid681t" path="res://addons/proton_scatter/icons/warning.svg" id="9"] -[ext_resource type="Texture2D" uid="uid://lkb3k4nuipjn" path="res://addons/proton_scatter/icons/drag_area.svg" id="9_t6pse"] -[ext_resource type="Script" path="res://addons/proton_scatter/src/stack/inspector_plugin/ui/modifier/override_seed_button.gd" id="10_ptukr"] -[ext_resource type="Texture2D" uid="uid://dvlwsskebnfyf" path="res://addons/proton_scatter/icons/dice.svg" id="11_qwhro"] -[ext_resource type="PackedScene" uid="uid://w6ycb4oveqhd" path="res://addons/proton_scatter/src/stack/inspector_plugin/ui/modifier/components/header/parameter_button.tscn" id="11_y7srw"] -[ext_resource type="Texture2D" uid="uid://bxgtlg3v183xe" path="res://addons/proton_scatter/icons/restrict_volume.svg" id="12_lx60d"] -[ext_resource type="Texture2D" uid="uid://d4hayrcip1oo0" path="res://addons/proton_scatter/icons/local.svg" id="13_txjs8"] -[ext_resource type="PackedScene" uid="uid://c36gqn03pvlnr" path="res://addons/proton_scatter/src/stack/inspector_plugin/ui/modifier/components/header/parameter_spinbox.tscn" id="13_vhfch"] -[ext_resource type="Texture2D" uid="uid://bjha4mlvffrca" path="res://addons/proton_scatter/icons/restrict_volume_lock.svg" id="15_0w0as"] -[ext_resource type="Texture2D" uid="uid://bpygylbuxdu0f" path="res://addons/proton_scatter/icons/global.svg" id="16_ocvvf"] -[ext_resource type="PackedScene" uid="uid://bspbhkrpgak0e" path="res://addons/proton_scatter/src/stack/inspector_plugin/ui/modifier/components/parameter_scalar.tscn" id="17_aoulv"] -[ext_resource type="Texture2D" uid="uid://be7s3se8bo32r" path="res://addons/proton_scatter/icons/individual_instances.svg" id="19_ln8a3"] - -[node name="ModifierPanel" type="MarginContainer"] -anchors_preset = 10 -anchor_right = 1.0 -grow_horizontal = 2 -theme_type_variation = &"fg" -script = ExtResource("1") - -[node name="Panel" type="Panel" parent="."] -layout_mode = 2 -offset_right = 1920.0 -offset_bottom = 34.0 -mouse_filter = 2 - -[node name="MarginContainer" type="MarginContainer" parent="."] -layout_mode = 2 -offset_right = 1920.0 -offset_bottom = 34.0 -grow_horizontal = 2 -mouse_filter = 2 -theme_override_constants/margin_left = 4 -theme_override_constants/margin_top = 4 -theme_override_constants/margin_right = 4 -theme_override_constants/margin_bottom = 4 -metadata/_edit_layout_mode = 1 -metadata/_edit_use_custom_anchors = false - -[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer"] -layout_mode = 2 -offset_left = 4.0 -offset_top = 4.0 -offset_right = 1916.0 -offset_bottom = 30.0 - -[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/VBoxContainer"] -layout_mode = 2 -offset_right = 1912.0 -offset_bottom = 26.0 -size_flags_vertical = 0 - -[node name="Expand" type="Button" parent="MarginContainer/VBoxContainer/HBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 -offset_right = 20.0 -offset_bottom = 26.0 -tooltip_text = "Toggle the parameters view" -focus_mode = 0 -mouse_filter = 1 -toggle_mode = true -icon = ExtResource("2_2djuo") -flat = true -icon_alignment = 1 -script = ExtResource("4") -default_icon = ExtResource("2_2djuo") -pressed_icon = ExtResource("4_7nlfc") - -[node name="ModifierName" type="Label" parent="MarginContainer/VBoxContainer/HBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 -offset_left = 24.0 -offset_right = 1808.0 -offset_bottom = 26.0 -size_flags_horizontal = 3 -text = "ModifierPanel" -vertical_alignment = 1 -clip_text = true - -[node name="Buttons" type="HBoxContainer" parent="MarginContainer/VBoxContainer/HBoxContainer"] -layout_mode = 2 -offset_left = 1812.0 -offset_right = 1912.0 -offset_bottom = 26.0 -theme_override_constants/separation = 2 -alignment = 1 - -[node name="Warning" type="Button" parent="MarginContainer/VBoxContainer/HBoxContainer/Buttons"] -unique_name_in_owner = true -visible = false -layout_mode = 2 -offset_right = 24.0 -offset_bottom = 31.0 -size_flags_horizontal = 0 -focus_mode = 0 -mouse_filter = 1 -icon = ExtResource("9") -flat = true - -[node name="MenuButton" type="MenuButton" parent="MarginContainer/VBoxContainer/HBoxContainer/Buttons"] -unique_name_in_owner = true -layout_mode = 2 -offset_right = 24.0 -offset_bottom = 26.0 -tooltip_text = "Show options" -icon = ExtResource("6_lmo8k") -item_count = 4 -popup/item_0/text = "Show documentation" -popup/item_0/icon = ExtResource("7_owhij") -popup/item_0/id = 0 -popup/item_1/text = "" -popup/item_1/id = 1 -popup/item_1/separator = true -popup/item_2/text = "Duplicate" -popup/item_2/icon = ExtResource("7_f6nan") -popup/item_2/id = 2 -popup/item_3/text = "Delete" -popup/item_3/icon = ExtResource("5") -popup/item_3/id = 3 - -[node name="Enabled" type="CheckBox" parent="MarginContainer/VBoxContainer/HBoxContainer/Buttons"] -unique_name_in_owner = true -layout_mode = 2 -offset_left = 26.0 -offset_right = 50.0 -offset_bottom = 26.0 -tooltip_text = "Toggle the modifier. - -If the modifier is disabled, it will not contribute to the final result but will still remain in the stack. - -Use this feature to quickly see how the modifier affects the overall stack." -focus_mode = 0 -mouse_filter = 1 - -[node name="Remove" type="Button" parent="MarginContainer/VBoxContainer/HBoxContainer/Buttons"] -unique_name_in_owner = true -layout_mode = 2 -offset_left = 52.0 -offset_top = 1.0 -offset_right = 76.0 -offset_bottom = 25.0 -size_flags_vertical = 4 -tooltip_text = "Delete the modifier. -This will remove it from the stack." -focus_mode = 0 -mouse_filter = 1 -icon = ExtResource("5") -flat = true -icon_alignment = 1 - -[node name="VSeparator" type="VSeparator" parent="MarginContainer/VBoxContainer/HBoxContainer/Buttons"] -modulate = Color(1, 1, 1, 0.54902) -layout_mode = 2 -offset_left = 78.0 -offset_right = 82.0 -offset_bottom = 26.0 - -[node name="DragControl" type="TextureRect" parent="MarginContainer/VBoxContainer/HBoxContainer/Buttons"] -unique_name_in_owner = true -layout_mode = 2 -offset_left = 84.0 -offset_right = 100.0 -offset_bottom = 26.0 -tooltip_text = "Drag and move this button to change the stack order. - -Modifiers are processed from top to bottom." -mouse_default_cursor_shape = 6 -texture = ExtResource("9_t6pse") -stretch_mode = 3 - -[node name="ParametersContainer" type="MarginContainer" parent="MarginContainer/VBoxContainer"] -unique_name_in_owner = true -visible = false -layout_mode = 2 -offset_top = 30.0 -offset_right = 1912.0 -offset_bottom = 72.0 -theme_override_constants/margin_left = 3 -theme_override_constants/margin_top = 3 -theme_override_constants/margin_right = 3 -theme_override_constants/margin_bottom = 3 - -[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/VBoxContainer/ParametersContainer"] -layout_mode = 2 -offset_left = 3.0 -offset_top = 3.0 -offset_right = 1909.0 -offset_bottom = 39.0 - -[node name="ParametersRoot" type="VBoxContainer" parent="MarginContainer/VBoxContainer/ParametersContainer/VBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 -offset_right = 1906.0 - -[node name="HSeparator" type="HSeparator" parent="MarginContainer/VBoxContainer/ParametersContainer/VBoxContainer"] -layout_mode = 2 -offset_top = 4.0 -offset_right = 1906.0 -offset_bottom = 8.0 - -[node name="CommonHeader" type="HBoxContainer" parent="MarginContainer/VBoxContainer/ParametersContainer/VBoxContainer"] -layout_mode = 2 -offset_top = 12.0 -offset_right = 1906.0 -offset_bottom = 36.0 -size_flags_vertical = 4 -alignment = 1 - -[node name="ExpandButton" type="MarginContainer" parent="MarginContainer/VBoxContainer/ParametersContainer/VBoxContainer/CommonHeader"] -layout_mode = 2 -offset_right = 24.0 -offset_bottom = 24.0 -script = ExtResource("10_ptukr") - -[node name="OverrideGlobalSeed" parent="MarginContainer/VBoxContainer/ParametersContainer/VBoxContainer/CommonHeader/ExpandButton" instance=ExtResource("11_y7srw")] -unique_name_in_owner = true -layout_mode = 2 -offset_right = 24.0 -offset_bottom = 24.0 -size_flags_horizontal = 3 -size_flags_vertical = 3 - -[node name="Button" parent="MarginContainer/VBoxContainer/ParametersContainer/VBoxContainer/CommonHeader/ExpandButton/OverrideGlobalSeed" index="0"] -layout_mode = 2 -offset_right = 24.0 -offset_bottom = 24.0 -tooltip_text = "Random seed. - -Enable to force a custom seed on this modifier only. If this option is disabled, the Global Seed from the ProtonScatter node will be used instead." -icon = ExtResource("11_qwhro") -icon_alignment = 0 -default_icon = ExtResource("11_qwhro") -pressed_icon = ExtResource("11_qwhro") - -[node name="SpinBoxRoot" type="HBoxContainer" parent="MarginContainer/VBoxContainer/ParametersContainer/VBoxContainer/CommonHeader/ExpandButton"] -visible = false -layout_mode = 2 -offset_right = 24.0 -offset_bottom = 24.0 -mouse_filter = 2 - -[node name="VSeparator" type="VSeparator" parent="MarginContainer/VBoxContainer/ParametersContainer/VBoxContainer/CommonHeader/ExpandButton/SpinBoxRoot"] -modulate = Color(1, 1, 1, 0) -layout_mode = 2 -offset_right = 28.0 -offset_bottom = 31.0 -mouse_filter = 2 -theme_override_constants/separation = 28 - -[node name="CustomSeed" parent="MarginContainer/VBoxContainer/ParametersContainer/VBoxContainer/CommonHeader/ExpandButton/SpinBoxRoot" instance=ExtResource("13_vhfch")] -unique_name_in_owner = true -layout_mode = 2 -offset_left = 31.0 -offset_right = 114.062 - -[node name="Control" type="Control" parent="MarginContainer/VBoxContainer/ParametersContainer/VBoxContainer/CommonHeader"] -layout_mode = 2 -anchors_preset = 0 -offset_left = 28.0 -offset_right = 1831.0 -offset_bottom = 24.0 -size_flags_horizontal = 3 - -[node name="RestrictHeight" parent="MarginContainer/VBoxContainer/ParametersContainer/VBoxContainer/CommonHeader" instance=ExtResource("11_y7srw")] -unique_name_in_owner = true -layout_mode = 2 -offset_left = 1835.0 -offset_right = 1859.0 -offset_bottom = 24.0 -size_flags_horizontal = 1 -size_flags_vertical = 3 - -[node name="Button" parent="MarginContainer/VBoxContainer/ParametersContainer/VBoxContainer/CommonHeader/RestrictHeight" index="0"] -layout_mode = 2 -offset_right = 24.0 -offset_bottom = 24.0 -tooltip_text = "Restrict height. - -If enabled, the modifier will try to remain in the local XZ plane instead of using the full volume defined by the ScatterShapes." -icon = ExtResource("12_lx60d") -default_icon = ExtResource("12_lx60d") -pressed_icon = ExtResource("15_0w0as") - -[node name="TransformSpace" parent="MarginContainer/VBoxContainer/ParametersContainer/VBoxContainer/CommonHeader" instance=ExtResource("17_aoulv")] -unique_name_in_owner = true -layout_mode = 2 -anchors_preset = 0 -anchor_right = 0.0 -offset_left = 1863.0 -offset_right = 1906.0 -offset_bottom = 24.0 -grow_horizontal = 2 - -[node name="Label" parent="MarginContainer/VBoxContainer/ParametersContainer/VBoxContainer/CommonHeader/TransformSpace" index="0"] -visible = false -offset_top = 4.0 -offset_right = 1.0 -offset_bottom = 27.0 -text = "" - -[node name="MarginContainer" parent="MarginContainer/VBoxContainer/ParametersContainer/VBoxContainer/CommonHeader/TransformSpace" index="1"] -offset_left = 0.0 -offset_right = 43.0 -offset_bottom = 24.0 - -[node name="Panel" parent="MarginContainer/VBoxContainer/ParametersContainer/VBoxContainer/CommonHeader/TransformSpace/MarginContainer" index="0"] -offset_right = 43.0 -offset_bottom = 24.0 - -[node name="MarginContainer" parent="MarginContainer/VBoxContainer/ParametersContainer/VBoxContainer/CommonHeader/TransformSpace/MarginContainer" index="1"] -offset_right = 43.0 -offset_bottom = 24.0 - -[node name="SpinBox" parent="MarginContainer/VBoxContainer/ParametersContainer/VBoxContainer/CommonHeader/TransformSpace/MarginContainer/MarginContainer" index="0"] -visible = false -offset_right = 43.0 -offset_bottom = 24.0 - -[node name="OptionButton" parent="MarginContainer/VBoxContainer/ParametersContainer/VBoxContainer/CommonHeader/TransformSpace/MarginContainer/MarginContainer" index="1"] -visible = true -offset_right = 43.0 -offset_bottom = 24.0 -item_count = 3 -fit_to_longest_item = false -popup/item_0/text = "Global" -popup/item_0/icon = ExtResource("16_ocvvf") -popup/item_0/id = 0 -popup/item_1/text = "Local" -popup/item_1/icon = ExtResource("13_txjs8") -popup/item_1/id = 1 -popup/item_2/text = "Individual" -popup/item_2/icon = ExtResource("19_ln8a3") -popup/item_2/id = 2 - -[node name="WarningDialog" type="AcceptDialog" parent="."] -title = "Warning" -unresizable = true -popup_window = true - -[editable path="MarginContainer/VBoxContainer/ParametersContainer/VBoxContainer/CommonHeader/ExpandButton/OverrideGlobalSeed"] -[editable path="MarginContainer/VBoxContainer/ParametersContainer/VBoxContainer/CommonHeader/RestrictHeight"] -[editable path="MarginContainer/VBoxContainer/ParametersContainer/VBoxContainer/CommonHeader/TransformSpace"] diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/override_seed_button.gd b/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/override_seed_button.gd deleted file mode 100644 index 1d89240..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/override_seed_button.gd +++ /dev/null @@ -1,14 +0,0 @@ -@tool -extends Control - - -@onready var _button: Button = $OverrideGlobalSeed/Button -@onready var _spinbox_root: Control = $SpinBoxRoot - - -func _ready(): - _button.toggled.connect(_on_toggled) - - -func _on_toggled(enabled: bool) -> void: - _spinbox_root.visible = enabled diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/toggle_button.gd b/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/toggle_button.gd deleted file mode 100644 index d02da8e..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier/toggle_button.gd +++ /dev/null @@ -1,18 +0,0 @@ -@tool -extends Button - - -@export var default_icon: Texture -@export var pressed_icon: Texture - - -func _ready() -> void: - toggled.connect(_on_toggled) - _on_toggled(button_pressed) - - -func _on_toggled(pressed: bool) -> void: - if pressed: - icon = pressed_icon - else: - icon = default_icon diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier_list_popup/category.gd b/addons/scatter-4/src/stack/inspector_plugin/ui/modifier_list_popup/category.gd deleted file mode 100644 index 2c73397..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier_list_popup/category.gd +++ /dev/null @@ -1,9 +0,0 @@ -@tool -extends VBoxContainer - - -@onready var label: Label = $Header/Label - - -func set_category_name(text) -> void: - label.text = text diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier_list_popup/category.tscn b/addons/scatter-4/src/stack/inspector_plugin/ui/modifier_list_popup/category.tscn deleted file mode 100644 index 690edec..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier_list_popup/category.tscn +++ /dev/null @@ -1,26 +0,0 @@ -[gd_scene load_steps=2 format=3] - -[ext_resource type="Script" path="res://addons/proton_scatter/src/stack/inspector_plugin/ui/modifier_list_popup/category.gd" id="1"] - -[node name="VBoxContainer" type="VBoxContainer"] -margin_right = 40.0 -margin_bottom = 40.0 -rect_pivot_offset = Vector2( -591.851, -77.5574 ) -size_flags_horizontal = 3 -script = ExtResource( 1 ) -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="Header" type="VBoxContainer" parent="."] -margin_right = 40.0 -margin_bottom = 22.0 - -[node name="Label" type="Label" parent="Header"] -margin_right = 40.0 -margin_bottom = 14.0 - -[node name="HSeparator" type="HSeparator" parent="Header"] -margin_top = 18.0 -margin_right = 40.0 -margin_bottom = 22.0 diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier_list_popup/popup.gd b/addons/scatter-4/src/stack/inspector_plugin/ui/modifier_list_popup/popup.gd deleted file mode 100644 index 360c925..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier_list_popup/popup.gd +++ /dev/null @@ -1,113 +0,0 @@ -@tool -extends PopupPanel - - -signal add_modifier - -var _modifiers := [] - -@onready var _category_root: Control = $MarginContainer/CategoryRoot - - -func _ready() -> void: - _rebuild_ui() - - -func _rebuild_ui(): - for c in _category_root.get_children(): - c.queue_free() - - _discover_modifiers() - for modifier in _modifiers: - var instance = modifier.new() - if instance.enabled: - var category = _get_or_create_category(instance.category) - var button = _create_button(instance.display_name) - category.add_child(button, true) - button.pressed.connect(_on_pressed.bind(modifier)) - - for category in _category_root.get_children(): - var header = category.get_child(0) - _sort_children_by_name(category) - category.move_child(header, 0) - - -func _create_button(display_name) -> Button: - var button = Button.new() - button.name = display_name - button.text = display_name - button.alignment = HORIZONTAL_ALIGNMENT_LEFT - return button - - -func _sort_children_by_name(node: Node) -> void: - var dict := {} - var names := [] - - for child in node.get_children(): - names.push_back(child.name) - dict[child.name] = child - - names.sort_custom(func(a, b): return String(a) < String(b)) - - for i in names.size(): - var n = names[i] - node.move_child(dict[n], i) - - -func _get_or_create_category(text: String) -> Control: - if _category_root.has_node(text): - return _category_root.get_node(text) as Control - - var c = preload("category.tscn").instantiate() - c.name = text - _category_root.add_child(c, true) - c.set_category_name(text) - return c - - -func _discover_modifiers() -> void: - if _modifiers.is_empty(): - var path = _get_root_folder() + "/src/modifiers/" - _discover_modifiers_recursive(path) - - -func _discover_modifiers_recursive(path) -> void: - var dir = DirAccess.open(path) - dir.list_dir_begin() - var path_root = dir.get_current_dir() + "/" - - while true: - var file = dir.get_next() - if file == "": - break - if file == "base_modifier.gd": - continue - if dir.current_is_dir(): - _discover_modifiers_recursive(path_root + file) - continue - if not file.ends_with(".gd") and not file.ends_with(".gdc"): - continue - - var full_path = path_root + file - var script = load(full_path) - if not script or not script.can_instantiate(): - print("Error: Failed to load script ", file) - continue - - _modifiers.push_back(script) - - dir.list_dir_end() - - -func _get_root_folder() -> String: - var script: Script = get_script() - var path: String = script.get_path().get_base_dir() - var folders = path.right(-6) # Remove the res:// - var tokens = folders.split('/') - return "res://" + tokens[0] + "/" + tokens[1] - - -func _on_pressed(modifier) -> void: - add_modifier.emit(modifier.new()) - visible = false diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier_list_popup/popup.tscn b/addons/scatter-4/src/stack/inspector_plugin/ui/modifier_list_popup/popup.tscn deleted file mode 100644 index 644d361..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/modifier_list_popup/popup.tscn +++ /dev/null @@ -1,20 +0,0 @@ -[gd_scene load_steps=2 format=3 uid="uid://belutr5odecw2"] - -[ext_resource type="Script" path="res://addons/proton_scatter/src/stack/inspector_plugin/ui/modifier_list_popup/popup.gd" id="1"] - -[node name="ModifiersPopup" type="PopupPanel"] -size = Vector2i(597, 322) -visible = true -script = ExtResource("1") - -[node name="MarginContainer" type="MarginContainer" parent="."] -anchor_right = 1.0 -anchor_bottom = 1.0 -offset_left = 4.0 -offset_top = 4.0 -offset_right = -431.0 -offset_bottom = -282.0 - -[node name="CategoryRoot" type="HBoxContainer" parent="MarginContainer"] -offset_right = 589.0 -offset_bottom = 314.0 diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/presets/load_preset.gd b/addons/scatter-4/src/stack/inspector_plugin/ui/presets/load_preset.gd deleted file mode 100644 index 0c8306c..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/presets/load_preset.gd +++ /dev/null @@ -1,87 +0,0 @@ -@tool -extends Window - - -signal load_preset -signal delete_preset - - -@onready var _no_presets: Label = $MarginContainer/VBoxContainer/ScrollContainer/VBoxContainer/NoPresets -@onready var _root: VBoxContainer = $MarginContainer/VBoxContainer/ScrollContainer/VBoxContainer/PresetsRoot -@onready var _confirmation_dialog: ConfirmationDialog = $ConfirmationDialog - -var _selected: String -var _selected_ui: Node - - -func _ready(): - _rebuild_ui() - about_to_popup.connect(_rebuild_ui) - - -func _rebuild_ui(): - for c in _root.get_children(): - c.queue_free() - _root.visible = false - - var presets = _find_all_presets() - if presets.empty(): - _no_presets.visible = true - return - - _no_presets.visible = false - _root.visible = true - for p in presets: - var ui = preload("./preset.tscn").instantiate() - _root.add_child(ui) - ui.set_preset_name(p) - ui.load_preset.connect(_on_load_preset.bind(p)) - ui.delete_preset.connect(_on_delete_preset.bind(p, ui)) - - -func _find_all_presets() -> Array: - var root := _get_root_folder() + "/presets/" - var res := [] - var dir = DirAccess.open(root) - if not dir: - return res - - dir.list_dir_begin() - while true: - var file = dir.get_next() - if file == "": - break - - if file.ends_with(".tscn"): - res.push_back(file.get_basename()) - - dir.list_dir_end() - res.sort() - return res - - -func _get_root_folder() -> String: - var path: String = get_script().get_path().get_base_dir() - var folders = path.right(6) # Remove the res:// - var tokens = folders.split('/') - return "res://" + tokens[0] + "/" + tokens[1] - - -func _on_load_preset(preset_name) -> void: - emit_signal("load_preset", preset_name) - visible = false - - -func _on_delete_preset(preset_name, ui) -> void: - _selected = preset_name - _selected_ui = ui - _confirmation_dialog.popup_centered() - - -func _on_delete_preset_confirmed(): - DirAccess.remove_absolute(_get_root_folder() + "/presets/" + _selected + ".tscn") - _selected_ui.queue_free() - - -func _on_cancel_pressed(): - visible = false diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/presets/load_preset.tscn b/addons/scatter-4/src/stack/inspector_plugin/ui/presets/load_preset.tscn deleted file mode 100644 index 7016386..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/presets/load_preset.tscn +++ /dev/null @@ -1,101 +0,0 @@ -[gd_scene load_steps=2 format=3] - -[ext_resource type="Script" path="res://addons/proton_scatter/src/stack/inspector_plugin/ui/presets/load_preset.gd" id="1"] - -[node name="LoadPresetPopup" type="WindowDialog"] -visible = true -anchor_left = 0.5 -anchor_top = 0.5 -anchor_right = 0.5 -anchor_bottom = 0.5 -margin_left = -147.5 -margin_top = -156.5 -margin_right = 147.5 -margin_bottom = 156.5 -size_flags_horizontal = 5 -size_flags_vertical = 5 -window_title = "Load Presets" -resizable = true -script = ExtResource( 1 ) -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="MarginContainer" type="MarginContainer" parent="."] -anchor_right = 1.0 -anchor_bottom = 1.0 -custom_constants/margin_right = 8 -custom_constants/margin_top = 8 -custom_constants/margin_left = 8 -custom_constants/margin_bottom = 8 -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer"] -margin_left = 8.0 -margin_top = 8.0 -margin_right = 287.0 -margin_bottom = 305.0 -custom_constants/separation = 6 - -[node name="ScrollContainer" type="ScrollContainer" parent="MarginContainer/VBoxContainer"] -margin_right = 279.0 -margin_bottom = 271.0 -size_flags_vertical = 3 -scroll_horizontal_enabled = false - -[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/VBoxContainer/ScrollContainer"] -margin_right = 279.0 -margin_bottom = 271.0 -size_flags_horizontal = 3 -size_flags_vertical = 3 - -[node name="NoPresets" type="Label" parent="MarginContainer/VBoxContainer/ScrollContainer/VBoxContainer"] -visible = false -margin_right = 247.0 -margin_bottom = 118.0 -size_flags_horizontal = 3 -size_flags_vertical = 3 -text = "No presets found. - -Create new presets by pressing the \"Save Preset\" button first." -valign = 1 -autowrap = true - -[node name="PresetsRoot" type="VBoxContainer" parent="MarginContainer/VBoxContainer/ScrollContainer/VBoxContainer"] -margin_right = 279.0 -margin_bottom = 271.0 -size_flags_horizontal = 3 -size_flags_vertical = 3 - -[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/VBoxContainer"] -margin_left = 112.0 -margin_top = 277.0 -margin_right = 166.0 -margin_bottom = 297.0 -size_flags_horizontal = 4 - -[node name="CancelButton" type="Button" parent="MarginContainer/VBoxContainer/HBoxContainer"] -margin_right = 54.0 -margin_bottom = 20.0 -text = "Cancel" - -[node name="ConfirmationDialog" type="ConfirmationDialog" parent="."] -visible = true -margin_left = -320.0 -margin_top = 37.0 -margin_right = -120.0 -margin_bottom = 112.0 -dialog_text = "Delete preset? -(This action can't be undone)" -__meta__ = { -"_edit_use_anchors_": false -} - -[connection signal="pressed" from="MarginContainer/VBoxContainer/ScrollContainer/VBoxContainer/PresetsRoot/Preset" to="MarginContainer/VBoxContainer/ScrollContainer/VBoxContainer/PresetsRoot/Preset" method="_on_pressed"] -[connection signal="pressed" from="MarginContainer/VBoxContainer/ScrollContainer/VBoxContainer/PresetsRoot/Preset2" to="MarginContainer/VBoxContainer/ScrollContainer/VBoxContainer/PresetsRoot/Preset2" method="_on_pressed"] -[connection signal="pressed" from="MarginContainer/VBoxContainer/ScrollContainer/VBoxContainer/PresetsRoot/Preset3" to="MarginContainer/VBoxContainer/ScrollContainer/VBoxContainer/PresetsRoot/Preset3" method="_on_pressed"] -[connection signal="pressed" from="MarginContainer/VBoxContainer/ScrollContainer/VBoxContainer/PresetsRoot/Preset4" to="MarginContainer/VBoxContainer/ScrollContainer/VBoxContainer/PresetsRoot/Preset4" method="_on_pressed"] -[connection signal="pressed" from="MarginContainer/VBoxContainer/HBoxContainer/CancelButton" to="." method="_on_cancel_pressed"] -[connection signal="confirmed" from="ConfirmationDialog" to="." method="_on_delete_preset_confirmed"] diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/presets/preset.gd b/addons/scatter-4/src/stack/inspector_plugin/ui/presets/preset.gd deleted file mode 100644 index dba1842..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/presets/preset.gd +++ /dev/null @@ -1,21 +0,0 @@ -@tool -extends Button - - -signal load_preset -signal delete_preset - - -@onready var _label: Label = $MarginContainer/HBoxContainer/Label - - -func set_preset_name(text) -> void: - _label.text = text - - -func _on_pressed() -> void: - emit_signal("load_preset") - - -func _on_delete() -> void: - emit_signal("delete_preset") diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/presets/preset.tscn b/addons/scatter-4/src/stack/inspector_plugin/ui/presets/preset.tscn deleted file mode 100644 index 967db9a..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/presets/preset.tscn +++ /dev/null @@ -1,54 +0,0 @@ -[gd_scene load_steps=3 format=3] - -[ext_resource type="Texture" uid="uid://dahwdjl2er75o" path="res://addons/proton_scatter/icons/close.svg" id="1"] -[ext_resource type="Script" path="res://addons/proton_scatter/src/stack/inspector_plugin/ui/presets/preset.gd" id="2"] - -[node name="Preset" type="Button"] -anchor_top = 0.5 -anchor_right = 1.0 -anchor_bottom = 0.5 -margin_top = -10.0 -margin_bottom = 29.0 -rect_min_size = Vector2( 0, 40 ) -focus_mode = 0 -script = ExtResource( 2 ) -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="MarginContainer" type="MarginContainer" parent="."] -anchor_right = 1.0 -anchor_bottom = 1.0 -mouse_filter = 2 -custom_constants/margin_right = 6 -custom_constants/margin_top = 6 -custom_constants/margin_left = 6 -custom_constants/margin_bottom = 6 -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer"] -margin_left = 6.0 -margin_top = 6.0 -margin_right = 1274.0 -margin_bottom = 34.0 - -[node name="Label" type="Label" parent="MarginContainer/HBoxContainer"] -margin_top = 7.0 -margin_right = 1236.0 -margin_bottom = 21.0 -size_flags_horizontal = 3 -text = "Preset name" -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="Delete" type="Button" parent="MarginContainer/HBoxContainer"] -margin_left = 1240.0 -margin_right = 1268.0 -margin_bottom = 28.0 -icon = ExtResource( 1 ) - -[connection signal="pressed" from="." to="." method="_on_pressed"] -[connection signal="pressed" from="MarginContainer/HBoxContainer/Delete" to="." method="_on_delete"] diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/presets/save_preset.gd b/addons/scatter-4/src/stack/inspector_plugin/ui/presets/save_preset.gd deleted file mode 100644 index 91cfed0..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/presets/save_preset.gd +++ /dev/null @@ -1,78 +0,0 @@ -@tool -extends Window - - -signal save_preset - - -@onready var _line_edit: LineEdit = $MarginContainer/VBoxContainer/LineEdit -@onready var _cancel: Button = $MarginContainer/VBoxContainer/HBoxContainer/Cancel -@onready var _save: Button = $MarginContainer/VBoxContainer/HBoxContainer/Save -@onready var _warning: Label = $MarginContainer/VBoxContainer/Warning -@onready var _confirm_overwrite = $ConfirmationDialog - - -func _ready(): - _cancel.pressed.connect(_on_cancel_pressed) - _save.pressed.connect(_on_save_pressed) - _warning.text = "" - _confirm_overwrite.confirmed.connect(_save_preset) - - -func _on_cancel_pressed() -> void: - visible = false - _line_edit.text = "" - - -func _on_save_pressed() -> void: - var preset_name: String = _line_edit.text - if preset_name.is_empty(): - _warning.text = "Preset name can't be empty" - return - - if not preset_name.is_valid_filename(): - _warning.text = """Preset name must be a valid file name. - It cannot contain the following characters: - : / \\ ? * " | % < >""" - return - - _warning.text = "" - if _exists(preset_name): - _confirm_overwrite.dialog_text = "Preset \"" + preset_name + "\" already exists. Overwrite?" - _confirm_overwrite.popup_centered() - else: - _save_preset() - - -func _save_preset() -> void: - emit_signal("save_preset", _line_edit.text) - visible = false - _line_edit.text = "" - - -func _exists(preset: String) -> bool: - var dir = DirAccess.open(_get_root_folder() + "/presets/") - if not dir: - return false - - dir.list_dir_begin() - - while true: - var file = dir.get_next() - if file == "": - break - - if file == preset + ".tscn": - dir.list_dir_end() - return true - - dir.list_dir_end() - return false - - -func _get_root_folder() -> String: - var script: Script = get_script() - var path: String = script.get_path().get_base_dir() - var folders = path.right(6) # Remove the res:// - var tokens = folders.split('/') - return "res://" + tokens[0] + "/" + tokens[1] diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/presets/save_preset.tscn b/addons/scatter-4/src/stack/inspector_plugin/ui/presets/save_preset.tscn deleted file mode 100644 index 65e7922..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/presets/save_preset.tscn +++ /dev/null @@ -1,96 +0,0 @@ -[gd_scene load_steps=2 format=3] - -[ext_resource type="Script" path="res://addons/proton_scatter/src/stack/inspector_plugin/ui/presets/save_preset.gd" id="1"] - -[node name="SavePresetPopup" type="WindowDialog"] -visible = true -anchor_left = 0.5 -anchor_top = 0.5 -anchor_right = 0.5 -anchor_bottom = 0.5 -margin_left = -180.0 -margin_top = -81.0 -margin_right = 180.0 -margin_bottom = 81.0 -size_flags_horizontal = 5 -size_flags_vertical = 5 -window_title = "Save Preset" -resizable = true -script = ExtResource( 1 ) -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="MarginContainer" type="MarginContainer" parent="."] -anchor_right = 1.0 -anchor_bottom = 1.0 -custom_constants/margin_right = 24 -custom_constants/margin_top = 4 -custom_constants/margin_left = 24 -custom_constants/margin_bottom = 24 -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer"] -margin_left = 24.0 -margin_top = 4.0 -margin_right = 336.0 -margin_bottom = 120.0 -size_flags_vertical = 0 -custom_constants/separation = 12 -__meta__ = { -"_edit_use_anchors_": false -} - -[node name="Warning" type="Label" parent="MarginContainer/VBoxContainer"] -modulate = Color( 1, 0.513726, 0.278431, 1 ) -margin_right = 312.0 -margin_bottom = 48.0 -text = "Preset name must be a valid file name. -It cannot contain the following characters: -: / \\\\ ? * \" | % < >" -valign = 2 -autowrap = true - -[node name="LineEdit" type="LineEdit" parent="MarginContainer/VBoxContainer"] -margin_top = 60.0 -margin_right = 312.0 -margin_bottom = 84.0 -placeholder_text = "Preset Name" -caret_blink = true - -[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/VBoxContainer"] -margin_top = 96.0 -margin_right = 312.0 -margin_bottom = 116.0 -custom_constants/separation = 24 -alignment = 1 - -[node name="Cancel" type="Button" parent="MarginContainer/VBoxContainer/HBoxContainer"] -margin_left = 96.0 -margin_right = 150.0 -margin_bottom = 20.0 -text = "Cancel" - -[node name="Save" type="Button" parent="MarginContainer/VBoxContainer/HBoxContainer"] -margin_left = 174.0 -margin_right = 215.0 -margin_bottom = 20.0 -text = "Save" - -[node name="ConfirmationDialog" type="ConfirmationDialog" parent="."] -visible = true -anchor_left = 0.5 -anchor_top = 0.5 -anchor_right = 0.5 -anchor_bottom = 0.5 -margin_left = -135.0 -margin_top = -44.0 -margin_right = 135.0 -margin_bottom = 44.0 -window_title = "Overwrite existing preset?" -dialog_autowrap = true -__meta__ = { -"_edit_use_anchors_": false -} diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/stack_panel.gd b/addons/scatter-4/src/stack/inspector_plugin/ui/stack_panel.gd deleted file mode 100644 index 4089b2d..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/stack_panel.gd +++ /dev/null @@ -1,157 +0,0 @@ -@tool -extends Control - - -const ModifierPanel := preload("./modifier/modifier_panel.tscn") - - -@onready var _modifiers_container: Control = $%ModifiersContainer -@onready var _modifiers_popup: PopupPanel = $%ModifiersPopup - -var _scatter -var _modifier_stack -var _undo_redo -var _is_ready := false - - -func _ready(): - _modifiers_popup.add_modifier.connect(_on_modifier_added) - _modifiers_container.child_moved.connect(_on_modifier_moved) - $%Rebuild.pressed.connect(_on_rebuild_pressed) - $%DocumentationButton.pressed.connect(_on_documentation_requested.bind("ProtonScatter")) - $%LoadPreset.pressed.connect(_on_load_preset_pressed) - $%SavePreset.pressed.connect(_on_save_preset_pressed) - - _is_ready = true - rebuild_ui() - - -func set_node(node) -> void: - if not node: - return - - _scatter = node - _undo_redo = _scatter.undo_redo - $%Documentation.set_editor_plugin(_scatter.editor_plugin) - $%Presets.set_editor_plugin(_scatter.editor_plugin) - rebuild_ui() - - -func rebuild_ui() -> void: - if not _is_ready: - return - - _validate_stack_connections() - _clear() - for m in _modifier_stack.stack: - var ui = ModifierPanel.instantiate() - _modifiers_container.add_child(ui) - ui.set_root(_scatter) - ui.create_ui_for(m) - ui.removed.connect(_on_modifier_removed.bind(m)) - ui.value_changed.connect(_on_value_changed) - ui.documentation_requested.connect(_on_documentation_requested.bind(m.display_name)) - ui.duplication_requested.connect(_on_modifier_duplicated.bind(m)) - - -func _clear() -> void: - for c in _modifiers_container.get_children(): - _modifiers_container.remove_child(c) - c.queue_free() - - -func _validate_stack_connections() -> void: - if not _scatter: - return - - if _modifier_stack: - _modifier_stack.stack_changed.disconnect(_on_stack_changed) - - _modifier_stack = _scatter.modifier_stack - _modifier_stack.stack_changed.connect(_on_stack_changed) - - if _modifier_stack.just_created: - $%Presets.load_default(_scatter) - - -func _set_children_owner(new_owner: Node, node: Node): - for child in node.get_children(): - child.set_owner(new_owner) - if child.get_children().size() > 0: - _set_children_owner(new_owner, child) - - -func _get_root_folder() -> String: - var path: String = get_script().get_path().get_base_dir() - var folders = path.right(6) # Remove the res:// - var tokens = folders.split('/') - return "res://" + tokens[0] + "/" + tokens[1] - - -func _on_modifier_added(modifier) -> void: - if _undo_redo: - _undo_redo.create_action("Create modifier " + modifier.display_name) - _undo_redo.add_undo_method(_modifier_stack, "remove", modifier) - _undo_redo.add_do_method(_modifier_stack, "add", modifier) - _undo_redo.commit_action() - else: - _modifier_stack.add(modifier) - - -func _on_modifier_moved(old_index: int, new_index: int) -> void: - if _undo_redo: - _undo_redo.create_action("Move modifier") - _undo_redo.add_undo_method(_modifier_stack, "move", new_index, old_index) - _undo_redo.add_do_method(_modifier_stack, "move", old_index, new_index) - _undo_redo.commit_action() - else: - _modifier_stack.move(old_index, new_index) - - -func _on_modifier_removed(modifier) -> void: - if _undo_redo: - _undo_redo.create_action("Remove modifier " + modifier.display_name) - _undo_redo.add_undo_method(_modifier_stack, "add", modifier) - _undo_redo.add_do_method(_modifier_stack, "remove", modifier) - _undo_redo.commit_action() - else: - _modifier_stack.remove(modifier) - - -func _on_modifier_duplicated(modifier) -> void: - var index = _modifier_stack.get_index(modifier) - if index == -1: - return - - if _undo_redo: - _undo_redo.create_action("Duplicate modifier " + modifier.display_name) - _undo_redo.add_undo_method(_modifier_stack, "remove_at", index + 1) - _undo_redo.add_do_method(_modifier_stack, "duplicate_modifier", modifier) - _undo_redo.commit_action() - else: - _modifier_stack.duplicate_modifier(modifier) - - -func _on_stack_changed() -> void: - rebuild_ui() - - -func _on_value_changed() -> void: - _modifier_stack.value_changed.emit() - - -func _on_rebuild_pressed() -> void: - if _scatter: - _scatter.rebuild(true) - - -func _on_save_preset_pressed() -> void: - $%Presets.save_preset(_scatter) - - -func _on_load_preset_pressed() -> void: - $%Presets.load_preset(_scatter) - - -func _on_documentation_requested(page_name) -> void: - $%Documentation.show_page(page_name) diff --git a/addons/scatter-4/src/stack/inspector_plugin/ui/stack_panel.tscn b/addons/scatter-4/src/stack/inspector_plugin/ui/stack_panel.tscn deleted file mode 100644 index 72b12b5..0000000 --- a/addons/scatter-4/src/stack/inspector_plugin/ui/stack_panel.tscn +++ /dev/null @@ -1,140 +0,0 @@ -[gd_scene load_steps=12 format=3 uid="uid://dllpt2dven8vw"] - -[ext_resource type="Texture2D" uid="uid://cun73k8jdmr4e" path="res://addons/proton_scatter/icons/add.svg" id="1_4vwtj"] -[ext_resource type="Script" path="res://addons/proton_scatter/src/stack/inspector_plugin/ui/stack_panel.gd" id="1_ga4or"] -[ext_resource type="Script" path="res://addons/proton_scatter/src/stack/inspector_plugin/ui/modifier/drag_container.gd" id="1_hg5ys"] -[ext_resource type="Texture2D" uid="uid://d2q0ecpon840i" path="res://addons/proton_scatter/icons/rebuild.svg" id="2_svid4"] -[ext_resource type="Script" path="res://addons/proton_scatter/src/stack/inspector_plugin/ui/add_modifier_button.gd" id="3_01ldn"] -[ext_resource type="PackedScene" uid="uid://belutr5odecw2" path="res://addons/proton_scatter/src/stack/inspector_plugin/ui/modifier_list_popup/popup.tscn" id="3_pkswu"] -[ext_resource type="Texture2D" uid="uid://ddjrq1h4mkn6a" path="res://addons/proton_scatter/icons/load.svg" id="3_w72lv"] -[ext_resource type="Texture2D" uid="uid://b2omj2e03x72e" path="res://addons/proton_scatter/icons/save.svg" id="4_5l2cx"] -[ext_resource type="Texture2D" uid="uid://cnwg3p2m4lbf3" path="res://addons/proton_scatter/icons/doc.svg" id="8_fgqhd"] -[ext_resource type="PackedScene" uid="uid://cfg8iqtuion8b" path="res://addons/proton_scatter/src/documentation/documentation.tscn" id="9_y57kc"] -[ext_resource type="PackedScene" uid="uid://bcsosdvstytoq" path="res://addons/proton_scatter/src/presets/presets.tscn" id="11_2ut8s"] - -[node name="StackPanel" type="MarginContainer"] -clip_children = 1 -clip_contents = true -offset_right = 456.0 -offset_bottom = 144.0 -theme_override_constants/margin_left = 4 -theme_override_constants/margin_top = 4 -theme_override_constants/margin_right = 4 -theme_override_constants/margin_bottom = 4 -script = ExtResource("1_ga4or") - -[node name="VBoxContainer" type="VBoxContainer" parent="."] -layout_mode = 2 -offset_left = 4.0 -offset_top = 4.0 -offset_right = 452.0 -offset_bottom = 140.0 -theme_override_constants/separation = 16 - -[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer"] -layout_mode = 2 -offset_right = 448.0 -offset_bottom = 31.0 - -[node name="Add" type="Button" parent="VBoxContainer/HBoxContainer"] -layout_mode = 2 -offset_right = 131.0 -offset_bottom = 31.0 -size_flags_horizontal = 2 -focus_mode = 0 -toggle_mode = true -text = " Add modifier" -icon = ExtResource("1_4vwtj") -script = ExtResource("3_01ldn") - -[node name="ModifiersPopup" parent="VBoxContainer/HBoxContainer/Add" instance=ExtResource("3_pkswu")] -unique_name_in_owner = true -size = Vector2i(755, 322) -visible = false - -[node name="Rebuild" type="Button" parent="VBoxContainer/HBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 -offset_left = 324.0 -offset_right = 348.0 -offset_bottom = 31.0 -size_flags_horizontal = 4 -tooltip_text = "Force rebuild. - -If the placed items does not look as expected, you can press this button to force it to regenerate the result. - -Usually, you shouldn't have to use it so please report it on Github if you found a case where it's necessary to click this. " -focus_mode = 0 -icon = ExtResource("2_svid4") -icon_alignment = 1 - -[node name="VSeparator" type="VSeparator" parent="VBoxContainer/HBoxContainer"] -modulate = Color(1, 1, 1, 0.54902) -layout_mode = 2 -offset_left = 352.0 -offset_right = 356.0 -offset_bottom = 31.0 - -[node name="LoadPreset" type="Button" parent="VBoxContainer/HBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 -offset_left = 360.0 -offset_right = 384.0 -offset_bottom = 31.0 -tooltip_text = "Load a preset." -focus_mode = 0 -text = " -" -icon = ExtResource("3_w72lv") -icon_alignment = 1 - -[node name="SavePreset" type="Button" parent="VBoxContainer/HBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 -offset_left = 388.0 -offset_right = 412.0 -offset_bottom = 31.0 -tooltip_text = "Save a preset." -focus_mode = 0 -text = " -" -icon = ExtResource("4_5l2cx") -icon_alignment = 1 - -[node name="VSeparator2" type="VSeparator" parent="VBoxContainer/HBoxContainer"] -modulate = Color(1, 1, 1, 0.54902) -layout_mode = 2 -offset_left = 416.0 -offset_right = 420.0 -offset_bottom = 31.0 - -[node name="DocumentationButton" type="Button" parent="VBoxContainer/HBoxContainer"] -unique_name_in_owner = true -layout_mode = 2 -offset_left = 424.0 -offset_right = 448.0 -offset_bottom = 31.0 -tooltip_text = "Open documentation" -focus_mode = 0 -text = " -" -icon = ExtResource("8_fgqhd") -icon_alignment = 1 - -[node name="ModifiersContainer" type="Container" parent="VBoxContainer"] -unique_name_in_owner = true -clip_children = 1 -custom_minimum_size = Vector2(0, -4) -layout_mode = 2 -offset_top = 47.0 -offset_right = 448.0 -offset_bottom = 136.0 -size_flags_vertical = 3 -mouse_filter = 0 -script = ExtResource("1_hg5ys") - -[node name="Documentation" parent="." instance=ExtResource("9_y57kc")] -unique_name_in_owner = true - -[node name="Presets" parent="." instance=ExtResource("11_2ut8s")] -unique_name_in_owner = true diff --git a/addons/scatter-4/src/stack/modifier_stack.gd b/addons/scatter-4/src/stack/modifier_stack.gd deleted file mode 100644 index 018a34f..0000000 --- a/addons/scatter-4/src/stack/modifier_stack.gd +++ /dev/null @@ -1,85 +0,0 @@ -@tool -extends Resource - - -signal stack_changed -signal value_changed -signal transforms_ready - - -const ProtonScatter := preload("../scatter.gd") -const TransformList = preload("../common/transform_list.gd") - - -@export var stack: Array[Resource] = [] - -var just_created := false - - -func start_update(scatter_node: ProtonScatter, domain) -> void: - var transforms = TransformList.new() - - for modifier in stack: - await modifier.process_transforms(transforms, domain, scatter_node.global_seed) - - transforms_ready.emit(transforms) - - -func add(modifier) -> void: - stack.push_back(modifier) - stack_changed.emit() - - -func move(old_index: int, new_index: int) -> void: - var modifier = stack.pop_at(old_index) - stack.insert(new_index, modifier) - stack_changed.emit() - - -func remove(modifier) -> void: - if stack.has(modifier): - stack.erase(modifier) - stack_changed.emit() - - -func remove_at(index: int) -> void: - if stack.size() > index: - stack.remove_at(index) - stack_changed.emit() - - -func duplicate_modifier(modifier) -> void: - var index: int = stack.find(modifier) - if index != -1: - var duplicate = modifier.get_copy() - add(duplicate) - move(stack.size() - 1, index + 1) - - -func get_copy(): - var copy = get_script().new() - for modifier in stack: - copy.stack.push_back(modifier.duplicate()) - return copy - - -func get_index(modifier) -> int: - return stack.find(modifier) - - -func is_using_edge_data() -> bool: - for modifier in stack: - if modifier.use_edge_data: - return true - - return false - - -# Returns true if at least one modifier does not require shapes in order to work. -# (This is the case for the "Add single item" modifier for example) -func does_not_require_shapes() -> bool: - for modifier in stack: - if modifier.warning_ignore_no_shape: - return true - - return false diff --git a/project.godot b/project.godot index 518a839..98547f3 100644 --- a/project.godot +++ b/project.godot @@ -29,7 +29,7 @@ window/stretch/mode="canvas_items" [editor_plugins] -enabled=PackedStringArray("res://addons/scatter-4/plugin.cfg", "res://addons/zylann.hterrain/plugin.cfg") +enabled=PackedStringArray("res://addons/zylann.hterrain/plugin.cfg") [input] diff --git a/scenes/mainmenu.tscn b/scenes/mainmenu.tscn index a89edc3..157265b 100644 --- a/scenes/mainmenu.tscn +++ b/scenes/mainmenu.tscn @@ -123,7 +123,7 @@ offset_left = 4.0 offset_top = 622.0 offset_right = 94.0 offset_bottom = 648.0 -text = "Version: 20230715" +text = "Version: 20230910" [node name="OurTimeIsNowSolo" type="Sprite2D" parent="."] position = Vector2(123, 104)