summaryrefslogtreecommitdiff
path: root/scene/resources
diff options
context:
space:
mode:
Diffstat (limited to 'scene/resources')
-rw-r--r--scene/resources/audio_stream_sample.cpp4
-rw-r--r--scene/resources/audio_stream_sample.h2
-rw-r--r--scene/resources/default_theme/default_theme.cpp4
-rw-r--r--scene/resources/immediate_mesh.cpp3
-rw-r--r--scene/resources/immediate_mesh.h1
-rw-r--r--scene/resources/material.cpp4
-rw-r--r--scene/resources/mesh.cpp110
-rw-r--r--scene/resources/mesh.h39
-rw-r--r--scene/resources/mesh_library.cpp19
-rw-r--r--scene/resources/mesh_library.h3
-rw-r--r--scene/resources/resource_format_text.cpp10
-rw-r--r--scene/resources/surface_tool.cpp49
-rw-r--r--scene/resources/texture.cpp24
-rw-r--r--scene/resources/texture.h2
-rw-r--r--scene/resources/tile_set.cpp786
-rw-r--r--scene/resources/tile_set.h98
-rw-r--r--scene/resources/world_boundary_shape_2d.cpp (renamed from scene/resources/world_margin_shape_2d.cpp)36
-rw-r--r--scene/resources/world_boundary_shape_2d.h (renamed from scene/resources/world_margin_shape_2d.h)16
-rw-r--r--scene/resources/world_boundary_shape_3d.cpp (renamed from scene/resources/world_margin_shape_3d.cpp)22
-rw-r--r--scene/resources/world_boundary_shape_3d.h (renamed from scene/resources/world_margin_shape_3d.h)18
20 files changed, 878 insertions, 372 deletions
diff --git a/scene/resources/audio_stream_sample.cpp b/scene/resources/audio_stream_sample.cpp
index 2ab9b7b5a4..d018103e64 100644
--- a/scene/resources/audio_stream_sample.cpp
+++ b/scene/resources/audio_stream_sample.cpp
@@ -480,6 +480,10 @@ float AudioStreamSample::get_length() const {
return float(len) / mix_rate;
}
+bool AudioStreamSample::is_monophonic() const {
+ return false;
+}
+
void AudioStreamSample::set_data(const Vector<uint8_t> &p_data) {
AudioServer::get_singleton()->lock();
if (data) {
diff --git a/scene/resources/audio_stream_sample.h b/scene/resources/audio_stream_sample.h
index 8bf3d29123..24198e3c98 100644
--- a/scene/resources/audio_stream_sample.h
+++ b/scene/resources/audio_stream_sample.h
@@ -136,6 +136,8 @@ public:
virtual float get_length() const override; //if supported, otherwise return 0
+ virtual bool is_monophonic() const override;
+
void set_data(const Vector<uint8_t> &p_data);
Vector<uint8_t> get_data() const;
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index 4845c556c6..fa3824e6eb 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -502,8 +502,10 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_icon("increment", "HScrollBar", empty_icon);
theme->set_icon("increment_highlight", "HScrollBar", empty_icon);
+ theme->set_icon("increment_pressed", "HScrollBar", empty_icon);
theme->set_icon("decrement", "HScrollBar", empty_icon);
theme->set_icon("decrement_highlight", "HScrollBar", empty_icon);
+ theme->set_icon("decrement_pressed", "HScrollBar", empty_icon);
// VScrollBar
@@ -515,8 +517,10 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_icon("increment", "VScrollBar", empty_icon);
theme->set_icon("increment_highlight", "VScrollBar", empty_icon);
+ theme->set_icon("increment_pressed", "VScrollBar", empty_icon);
theme->set_icon("decrement", "VScrollBar", empty_icon);
theme->set_icon("decrement_highlight", "VScrollBar", empty_icon);
+ theme->set_icon("decrement_pressed", "VScrollBar", empty_icon);
// HSlider
diff --git a/scene/resources/immediate_mesh.cpp b/scene/resources/immediate_mesh.cpp
index 05d1a7bf94..fe7124de9e 100644
--- a/scene/resources/immediate_mesh.cpp
+++ b/scene/resources/immediate_mesh.cpp
@@ -335,9 +335,6 @@ int ImmediateMesh::surface_get_array_len(int p_idx) const {
int ImmediateMesh::surface_get_array_index_len(int p_idx) const {
return 0;
}
-bool ImmediateMesh::surface_is_softbody_friendly(int p_idx) const {
- return false;
-}
Array ImmediateMesh::surface_get_arrays(int p_surface) const {
ERR_FAIL_INDEX_V(p_surface, int(surfaces.size()), Array());
return RS::get_singleton()->mesh_surface_get_arrays(mesh, p_surface);
diff --git a/scene/resources/immediate_mesh.h b/scene/resources/immediate_mesh.h
index 7010d40719..6673ee6f3d 100644
--- a/scene/resources/immediate_mesh.h
+++ b/scene/resources/immediate_mesh.h
@@ -94,7 +94,6 @@ public:
virtual int get_surface_count() const override;
virtual int surface_get_array_len(int p_idx) const override;
virtual int surface_get_array_index_len(int p_idx) const override;
- virtual bool surface_is_softbody_friendly(int p_idx) const override;
virtual Array surface_get_arrays(int p_surface) const override;
virtual Array surface_get_blend_shape_arrays(int p_surface) const override;
virtual Dictionary surface_get_lods(int p_surface) const override;
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index 1d2a2ef26c..77a68151c4 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -963,7 +963,9 @@ void BaseMaterial3D::_update_shader() {
} else {
code += " float depth = 1.0 - texture(texture_heightmap, base_uv).r;\n";
}
- code += " vec2 ofs = base_uv - view_dir.xy / view_dir.z * (depth * heightmap_scale);\n";
+ // Use offset limiting to improve the appearance of non-deep parallax.
+ // This reduces the impression of depth, but avoids visible warping in the distance.
+ code += " vec2 ofs = base_uv - view_dir.xy * depth * heightmap_scale;\n";
}
code += " base_uv=ofs;\n";
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index ad589a605e..67db8c1a10 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -38,7 +38,7 @@
#include <stdlib.h>
-Mesh::ConvexDecompositionFunc Mesh::convex_composition_function = nullptr;
+Mesh::ConvexDecompositionFunc Mesh::convex_decomposition_function = nullptr;
Ref<TriangleMesh> Mesh::generate_triangle_mesh() const {
if (triangle_mesh.is_valid()) {
@@ -156,75 +156,19 @@ void Mesh::generate_debug_mesh_indices(Vector<Vector3> &r_points) {
}
}
-bool Mesh::surface_is_softbody_friendly(int p_idx) const {
- const uint32_t surface_format = surface_get_format(p_idx);
- return (surface_format & Mesh::ARRAY_FLAG_USE_DYNAMIC_UPDATE);
-}
-
Vector<Face3> Mesh::get_faces() const {
Ref<TriangleMesh> tm = generate_triangle_mesh();
if (tm.is_valid()) {
return tm->get_faces();
}
return Vector<Face3>();
- /*
- for (int i=0;i<surfaces.size();i++) {
- if (RenderingServer::get_singleton()->mesh_surface_get_primitive_type( mesh, i ) != RenderingServer::PRIMITIVE_TRIANGLES )
- continue;
-
- Vector<int> indices;
- Vector<Vector3> vertices;
-
- vertices=RenderingServer::get_singleton()->mesh_surface_get_array(mesh, i,RenderingServer::ARRAY_VERTEX);
-
- int len=RenderingServer::get_singleton()->mesh_surface_get_array_index_len(mesh, i);
- bool has_indices;
-
- if (len>0) {
- indices=RenderingServer::get_singleton()->mesh_surface_get_array(mesh, i,RenderingServer::ARRAY_INDEX);
- has_indices=true;
-
- } else {
- len=vertices.size();
- has_indices=false;
- }
-
- if (len<=0)
- continue;
-
- const int* indicesr = indices.ptr();
- const int *indicesptr = indicesr.ptr();
-
- const Vector3* verticesr = vertices.ptr();
- const Vector3 *verticesptr = verticesr.ptr();
-
- int old_faces=faces.size();
- int new_faces=old_faces+(len/3);
-
- faces.resize(new_faces);
-
- Face3* facesw = faces.ptrw();
- Face3 *facesptr=facesw.ptr();
-
-
- for (int i=0;i<len/3;i++) {
- Face3 face;
-
- for (int j=0;j<3;j++) {
- int idx=i*3+j;
- face.vertex[j] = has_indices ? verticesptr[ indicesptr[ idx ] ] : verticesptr[idx];
- }
-
- facesptr[i+old_faces]=face;
- }
-
- }
-*/
}
Ref<Shape3D> Mesh::create_convex_shape(bool p_clean, bool p_simplify) const {
if (p_simplify) {
- Vector<Ref<Shape3D>> decomposed = convex_decompose(1);
+ ConvexDecompositionSettings settings;
+ settings.max_convex_hulls = 1;
+ Vector<Ref<Shape3D>> decomposed = convex_decompose(settings);
if (decomposed.size() == 1) {
return decomposed[0];
} else {
@@ -543,6 +487,7 @@ void Mesh::_bind_methods() {
BIND_ENUM_CONSTANT(ARRAY_FORMAT_BLEND_SHAPE_MASK);
BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM_BASE);
+ BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM_BITS);
BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM0_SHIFT);
BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM1_SHIFT);
BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM2_SHIFT);
@@ -564,36 +509,37 @@ void Mesh::clear_cache() const {
debug_lines.clear();
}
-Vector<Ref<Shape3D>> Mesh::convex_decompose(int p_max_convex_hulls) const {
- ERR_FAIL_COND_V(!convex_composition_function, Vector<Ref<Shape3D>>());
+Vector<Ref<Shape3D>> Mesh::convex_decompose(const ConvexDecompositionSettings &p_settings) const {
+ ERR_FAIL_COND_V(!convex_decomposition_function, Vector<Ref<Shape3D>>());
- const Vector<Face3> faces = get_faces();
-
- Vector<Vector<Face3>> decomposed = convex_composition_function(faces, p_max_convex_hulls);
+ Ref<TriangleMesh> tm = generate_triangle_mesh();
+ ERR_FAIL_COND_V(!tm.is_valid(), Vector<Ref<Shape3D>>());
- Vector<Ref<Shape3D>> ret;
+ const Vector<TriangleMesh::Triangle> &triangles = tm->get_triangles();
+ int triangle_count = triangles.size();
- for (int i = 0; i < decomposed.size(); i++) {
- Set<Vector3> points;
- for (int j = 0; j < decomposed[i].size(); j++) {
- points.insert(decomposed[i][j].vertex[0]);
- points.insert(decomposed[i][j].vertex[1]);
- points.insert(decomposed[i][j].vertex[2]);
- }
-
- Vector<Vector3> convex_points;
- convex_points.resize(points.size());
- {
- Vector3 *w = convex_points.ptrw();
- int idx = 0;
- for (Set<Vector3>::Element *E = points.front(); E; E = E->next()) {
- w[idx++] = E->get();
+ Vector<uint32_t> indices;
+ {
+ indices.resize(triangle_count * 3);
+ uint32_t *w = indices.ptrw();
+ for (int i = 0; i < triangle_count; i++) {
+ for (int j = 0; j < 3; j++) {
+ w[i * 3 + j] = triangles[i].indices[j];
}
}
+ }
+
+ const Vector<Vector3> &vertices = tm->get_vertices();
+ int vertex_count = vertices.size();
+ Vector<Vector<Vector3>> decomposed = convex_decomposition_function((real_t *)vertices.ptr(), vertex_count, indices.ptr(), triangle_count, p_settings, nullptr);
+
+ Vector<Ref<Shape3D>> ret;
+
+ for (int i = 0; i < decomposed.size(); i++) {
Ref<ConvexPolygonShape3D> shape;
shape.instantiate();
- shape->set_points(convex_points);
+ shape->set_points(decomposed[i]);
ret.push_back(shape);
}
diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h
index 27b0eb098b..8d5571d67c 100644
--- a/scene/resources/mesh.h
+++ b/scene/resources/mesh.h
@@ -105,6 +105,7 @@ public:
ARRAY_FORMAT_BLEND_SHAPE_MASK = RS::ARRAY_FORMAT_BLEND_SHAPE_MASK,
ARRAY_FORMAT_CUSTOM_BASE = RS::ARRAY_FORMAT_CUSTOM_BASE,
+ ARRAY_FORMAT_CUSTOM_BITS = RS::ARRAY_FORMAT_CUSTOM_BITS,
ARRAY_FORMAT_CUSTOM0_SHIFT = RS::ARRAY_FORMAT_CUSTOM0_SHIFT,
ARRAY_FORMAT_CUSTOM1_SHIFT = RS::ARRAY_FORMAT_CUSTOM1_SHIFT,
ARRAY_FORMAT_CUSTOM2_SHIFT = RS::ARRAY_FORMAT_CUSTOM2_SHIFT,
@@ -131,7 +132,6 @@ public:
virtual int get_surface_count() const = 0;
virtual int surface_get_array_len(int p_idx) const = 0;
virtual int surface_get_array_index_len(int p_idx) const = 0;
- virtual bool surface_is_softbody_friendly(int p_idx) const;
virtual Array surface_get_arrays(int p_surface) const = 0;
virtual Array surface_get_blend_shape_arrays(int p_surface) const = 0;
virtual Dictionary surface_get_lods(int p_surface) const = 0;
@@ -159,11 +159,42 @@ public:
Size2i get_lightmap_size_hint() const;
void clear_cache() const;
- typedef Vector<Vector<Face3>> (*ConvexDecompositionFunc)(const Vector<Face3> &p_faces, int p_max_convex_hulls);
+ struct ConvexDecompositionSettings {
+ enum Mode : int {
+ CONVEX_DECOMPOSITION_MODE_VOXEL = 0,
+ CONVEX_DECOMPOSITION_MODE_TETRAHEDRON
+ };
+
+ /// Maximum concavity. [Range: 0.0 -> 1.0]
+ real_t max_concavity = 1.0;
+ /// Controls the bias toward clipping along symmetry planes. [Range: 0.0 -> 1.0]
+ real_t symmetry_planes_clipping_bias = 0.05;
+ /// Controls the bias toward clipping along revolution axes. [Range: 0.0 -> 1.0]
+ real_t revolution_axes_clipping_bias = 0.05;
+ real_t min_volume_per_convex_hull = 0.0001;
+ /// Maximum number of voxels generated during the voxelization stage.
+ uint32_t resolution = 10'000;
+ uint32_t max_num_vertices_per_convex_hull = 32;
+ /// Controls the granularity of the search for the "best" clipping plane.
+ /// [Range: 1 -> 16]
+ uint32_t plane_downsampling = 4;
+ /// Controls the precision of the convex-hull generation process during the
+ /// clipping plane selection stage.
+ /// [Range: 1 -> 16]
+ uint32_t convexhull_downsampling = 4;
+ /// enable/disable normalizing the mesh before applying the convex decomposition.
+ bool normalize_mesh = false;
+ Mode mode = CONVEX_DECOMPOSITION_MODE_VOXEL;
+ bool convexhull_approximation = true;
+ /// This is the maximum number of convex hulls to produce from the merge operation.
+ uint32_t max_convex_hulls = 1;
+ bool project_hull_vertices = true;
+ };
+ typedef Vector<Vector<Vector3>> (*ConvexDecompositionFunc)(const real_t *p_vertices, int p_vertex_count, const uint32_t *p_triangles, int p_triangle_count, const ConvexDecompositionSettings &p_settings, Vector<Vector<uint32_t>> *r_convex_indices);
- static ConvexDecompositionFunc convex_composition_function;
+ static ConvexDecompositionFunc convex_decomposition_function;
- Vector<Ref<Shape3D>> convex_decompose(int p_max_convex_hulls = -1) const;
+ Vector<Ref<Shape3D>> convex_decompose(const ConvexDecompositionSettings &p_settings) const;
virtual int get_builtin_bind_pose_count() const;
virtual Transform3D get_builtin_bind_pose(int p_index) const;
diff --git a/scene/resources/mesh_library.cpp b/scene/resources/mesh_library.cpp
index 33c9ca6d1e..cfb7c3e037 100644
--- a/scene/resources/mesh_library.cpp
+++ b/scene/resources/mesh_library.cpp
@@ -43,6 +43,8 @@ bool MeshLibrary::_set(const StringName &p_name, const Variant &p_value) {
set_item_name(idx, p_value);
} else if (what == "mesh") {
set_item_mesh(idx, p_value);
+ } else if (what == "mesh_transform") {
+ set_item_mesh_transform(idx, p_value);
} else if (what == "shape") {
Vector<ShapeData> shapes;
ShapeData sd;
@@ -77,6 +79,8 @@ bool MeshLibrary::_get(const StringName &p_name, Variant &r_ret) const {
r_ret = get_item_name(idx);
} else if (what == "mesh") {
r_ret = get_item_mesh(idx);
+ } else if (what == "mesh_transform") {
+ r_ret = get_item_mesh_transform(idx);
} else if (what == "shapes") {
r_ret = _get_item_shapes(idx);
} else if (what == "navmesh") {
@@ -127,6 +131,14 @@ void MeshLibrary::set_item_mesh(int p_item, const Ref<Mesh> &p_mesh) {
notify_property_list_changed();
}
+void MeshLibrary::set_item_mesh_transform(int p_item, const Transform3D &p_transform) {
+ ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
+ item_map[p_item].mesh_transform = p_transform;
+ notify_change_to_owners();
+ emit_changed();
+ notify_property_list_changed();
+}
+
void MeshLibrary::set_item_shapes(int p_item, const Vector<ShapeData> &p_shapes) {
ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
item_map[p_item].shapes = p_shapes;
@@ -170,6 +182,11 @@ Ref<Mesh> MeshLibrary::get_item_mesh(int p_item) const {
return item_map[p_item].mesh;
}
+Transform3D MeshLibrary::get_item_mesh_transform(int p_item) const {
+ ERR_FAIL_COND_V_MSG(!item_map.has(p_item), Transform3D(), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
+ return item_map[p_item].mesh_transform;
+}
+
Vector<MeshLibrary::ShapeData> MeshLibrary::get_item_shapes(int p_item) const {
ERR_FAIL_COND_V_MSG(!item_map.has(p_item), Vector<ShapeData>(), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
return item_map[p_item].shapes;
@@ -271,12 +288,14 @@ void MeshLibrary::_bind_methods() {
ClassDB::bind_method(D_METHOD("create_item", "id"), &MeshLibrary::create_item);
ClassDB::bind_method(D_METHOD("set_item_name", "id", "name"), &MeshLibrary::set_item_name);
ClassDB::bind_method(D_METHOD("set_item_mesh", "id", "mesh"), &MeshLibrary::set_item_mesh);
+ ClassDB::bind_method(D_METHOD("set_item_mesh_transform", "id", "mesh_transform"), &MeshLibrary::set_item_mesh_transform);
ClassDB::bind_method(D_METHOD("set_item_navmesh", "id", "navmesh"), &MeshLibrary::set_item_navmesh);
ClassDB::bind_method(D_METHOD("set_item_navmesh_transform", "id", "navmesh"), &MeshLibrary::set_item_navmesh_transform);
ClassDB::bind_method(D_METHOD("set_item_shapes", "id", "shapes"), &MeshLibrary::_set_item_shapes);
ClassDB::bind_method(D_METHOD("set_item_preview", "id", "texture"), &MeshLibrary::set_item_preview);
ClassDB::bind_method(D_METHOD("get_item_name", "id"), &MeshLibrary::get_item_name);
ClassDB::bind_method(D_METHOD("get_item_mesh", "id"), &MeshLibrary::get_item_mesh);
+ ClassDB::bind_method(D_METHOD("get_item_mesh_transform", "id"), &MeshLibrary::get_item_mesh_transform);
ClassDB::bind_method(D_METHOD("get_item_navmesh", "id"), &MeshLibrary::get_item_navmesh);
ClassDB::bind_method(D_METHOD("get_item_navmesh_transform", "id"), &MeshLibrary::get_item_navmesh_transform);
ClassDB::bind_method(D_METHOD("get_item_shapes", "id"), &MeshLibrary::_get_item_shapes);
diff --git a/scene/resources/mesh_library.h b/scene/resources/mesh_library.h
index 1e8a6bf3ff..c25df757e9 100644
--- a/scene/resources/mesh_library.h
+++ b/scene/resources/mesh_library.h
@@ -52,6 +52,7 @@ public:
Vector<ShapeData> shapes;
Ref<Texture2D> preview;
Transform3D navmesh_transform;
+ Transform3D mesh_transform;
Ref<NavigationMesh> navmesh;
};
@@ -72,12 +73,14 @@ public:
void create_item(int p_item);
void set_item_name(int p_item, const String &p_name);
void set_item_mesh(int p_item, const Ref<Mesh> &p_mesh);
+ void set_item_mesh_transform(int p_item, const Transform3D &p_transform);
void set_item_navmesh(int p_item, const Ref<NavigationMesh> &p_navmesh);
void set_item_navmesh_transform(int p_item, const Transform3D &p_transform);
void set_item_shapes(int p_item, const Vector<ShapeData> &p_shapes);
void set_item_preview(int p_item, const Ref<Texture2D> &p_preview);
String get_item_name(int p_item) const;
Ref<Mesh> get_item_mesh(int p_item) const;
+ Transform3D get_item_mesh_transform(int p_item) const;
Ref<NavigationMesh> get_item_navmesh(int p_item) const;
Transform3D get_item_navmesh_transform(int p_item) const;
Vector<ShapeData> get_item_shapes(int p_item) const;
diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp
index b863a309c0..341ce22185 100644
--- a/scene/resources/resource_format_text.cpp
+++ b/scene/resources/resource_format_text.cpp
@@ -1849,10 +1849,16 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
}
if (groups.size()) {
+ // Write all groups on the same line as they're part of a section header.
+ // This improves readability while not impacting VCS friendliness too much,
+ // since it's rare to have more than 5 groups assigned to a single node.
groups.sort_custom<StringName::AlphCompare>();
- String sgroups = " groups=[\n";
+ String sgroups = " groups=[";
for (int j = 0; j < groups.size(); j++) {
- sgroups += "\"" + String(groups[j]).c_escape() + "\",\n";
+ sgroups += "\"" + String(groups[j]).c_escape() + "\"";
+ if (j < groups.size() - 1) {
+ sgroups += ", ";
+ }
}
sgroups += "]";
header += sgroups;
diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp
index 875aa30824..d5e370568d 100644
--- a/scene/resources/surface_tool.cpp
+++ b/scene/resources/surface_tool.cpp
@@ -409,7 +409,7 @@ Array SurfaceTool::commit_to_arrays() {
for (uint32_t idx = 0; idx < vertex_array.size(); idx++) {
const Vertex &v = vertex_array[idx];
- const Color &c = v.custom[idx];
+ const Color &c = v.custom[fmt];
w[idx * 4 + 0] = CLAMP(int32_t(c.r * 255.0), 0, 255);
w[idx * 4 + 1] = CLAMP(int32_t(c.g * 255.0), 0, 255);
w[idx * 4 + 2] = CLAMP(int32_t(c.b * 255.0), 0, 255);
@@ -426,7 +426,7 @@ Array SurfaceTool::commit_to_arrays() {
for (uint32_t idx = 0; idx < vertex_array.size(); idx++) {
const Vertex &v = vertex_array[idx];
- const Color &c = v.custom[idx];
+ const Color &c = v.custom[fmt];
w[idx * 4 + 0] = uint8_t(int8_t(CLAMP(int32_t(c.r * 127.0), -128, 127)));
w[idx * 4 + 1] = uint8_t(int8_t(CLAMP(int32_t(c.g * 127.0), -128, 127)));
w[idx * 4 + 2] = uint8_t(int8_t(CLAMP(int32_t(c.b * 127.0), -128, 127)));
@@ -443,7 +443,7 @@ Array SurfaceTool::commit_to_arrays() {
for (uint32_t idx = 0; idx < vertex_array.size(); idx++) {
const Vertex &v = vertex_array[idx];
- const Color &c = v.custom[idx];
+ const Color &c = v.custom[fmt];
w[idx * 2 + 0] = Math::make_half_float(c.r);
w[idx * 2 + 1] = Math::make_half_float(c.g);
}
@@ -458,7 +458,7 @@ Array SurfaceTool::commit_to_arrays() {
for (uint32_t idx = 0; idx < vertex_array.size(); idx++) {
const Vertex &v = vertex_array[idx];
- const Color &c = v.custom[idx];
+ const Color &c = v.custom[fmt];
w[idx * 4 + 0] = Math::make_half_float(c.r);
w[idx * 4 + 1] = Math::make_half_float(c.g);
w[idx * 4 + 2] = Math::make_half_float(c.b);
@@ -475,7 +475,7 @@ Array SurfaceTool::commit_to_arrays() {
for (uint32_t idx = 0; idx < vertex_array.size(); idx++) {
const Vertex &v = vertex_array[idx];
- const Color &c = v.custom[idx];
+ const Color &c = v.custom[fmt];
w[idx] = c.r;
}
@@ -489,7 +489,7 @@ Array SurfaceTool::commit_to_arrays() {
for (uint32_t idx = 0; idx < vertex_array.size(); idx++) {
const Vertex &v = vertex_array[idx];
- const Color &c = v.custom[idx];
+ const Color &c = v.custom[fmt];
w[idx * 2 + 0] = c.r;
w[idx * 2 + 1] = c.g;
}
@@ -504,7 +504,7 @@ Array SurfaceTool::commit_to_arrays() {
for (uint32_t idx = 0; idx < vertex_array.size(); idx++) {
const Vertex &v = vertex_array[idx];
- const Color &c = v.custom[idx];
+ const Color &c = v.custom[fmt];
w[idx * 3 + 0] = c.r;
w[idx * 3 + 1] = c.g;
w[idx * 3 + 2] = c.b;
@@ -520,7 +520,7 @@ Array SurfaceTool::commit_to_arrays() {
for (uint32_t idx = 0; idx < vertex_array.size(); idx++) {
const Vertex &v = vertex_array[idx];
- const Color &c = v.custom[idx];
+ const Color &c = v.custom[fmt];
w[idx * 4 + 0] = c.r;
w[idx * 4 + 1] = c.g;
w[idx * 4 + 2] = c.b;
@@ -679,6 +679,9 @@ void SurfaceTool::_create_list(const Ref<Mesh> &p_existing, int p_surface, Local
_create_list_from_arrays(arr, r_vertex, r_index, lformat);
}
+static const uint32_t custom_mask[RS::ARRAY_CUSTOM_COUNT] = { Mesh::ARRAY_FORMAT_CUSTOM0, Mesh::ARRAY_FORMAT_CUSTOM1, Mesh::ARRAY_FORMAT_CUSTOM2, Mesh::ARRAY_FORMAT_CUSTOM3 };
+static const uint32_t custom_shift[RS::ARRAY_CUSTOM_COUNT] = { Mesh::ARRAY_FORMAT_CUSTOM0_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM1_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM2_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM3_SHIFT };
+
void SurfaceTool::create_vertex_array_from_triangle_arrays(const Array &p_arrays, LocalVector<SurfaceTool::Vertex> &ret, uint32_t *r_format) {
ret.clear();
@@ -733,8 +736,6 @@ void SurfaceTool::create_vertex_array_from_triangle_arrays(const Array &p_arrays
if (warr.size()) {
lformat |= RS::ARRAY_FORMAT_WEIGHTS;
}
- static const uint32_t custom_mask[RS::ARRAY_CUSTOM_COUNT] = { Mesh::ARRAY_FORMAT_CUSTOM0, Mesh::ARRAY_FORMAT_CUSTOM1, Mesh::ARRAY_FORMAT_CUSTOM2, Mesh::ARRAY_FORMAT_CUSTOM3 };
- static const uint32_t custom_shift[RS::ARRAY_CUSTOM_COUNT] = { Mesh::ARRAY_FORMAT_CUSTOM0_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM1_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM2_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM3_SHIFT };
for (int i = 0; i < RS::ARRAY_CUSTOM_COUNT; i++) {
ERR_CONTINUE_MSG(p_arrays[RS::ARRAY_CUSTOM0 + i].get_type() == Variant::PACKED_BYTE_ARRAY, "Extracting Byte/Half formats is not supported");
@@ -832,6 +833,12 @@ void SurfaceTool::create_from_triangle_arrays(const Array &p_arrays) {
clear();
primitive = Mesh::PRIMITIVE_TRIANGLES;
_create_list_from_arrays(p_arrays, &vertex_array, &index_array, format);
+
+ for (int j = 0; j < RS::ARRAY_CUSTOM_COUNT; j++) {
+ if (format & custom_mask[j]) {
+ last_custom_format[j] = (CustomFormat)((format >> custom_shift[j]) & RS::ARRAY_FORMAT_CUSTOM_MASK);
+ }
+ }
}
void SurfaceTool::create_from(const Ref<Mesh> &p_existing, int p_surface) {
@@ -841,6 +848,12 @@ void SurfaceTool::create_from(const Ref<Mesh> &p_existing, int p_surface) {
primitive = p_existing->surface_get_primitive_type(p_surface);
_create_list(p_existing, p_surface, &vertex_array, &index_array, format);
material = p_existing->surface_get_material(p_surface);
+
+ for (int j = 0; j < RS::ARRAY_CUSTOM_COUNT; j++) {
+ if (format & custom_mask[j]) {
+ last_custom_format[j] = (CustomFormat)((format >> custom_shift[j]) & RS::ARRAY_FORMAT_CUSTOM_MASK);
+ }
+ }
}
void SurfaceTool::create_from_blend_shape(const Ref<Mesh> &p_existing, int p_surface, const String &p_blend_shape_name) {
@@ -863,6 +876,12 @@ void SurfaceTool::create_from_blend_shape(const Ref<Mesh> &p_existing, int p_sur
Array mesh = arr[shape_idx];
ERR_FAIL_COND(mesh.size() != RS::ARRAY_MAX);
_create_list_from_arrays(arr[shape_idx], &vertex_array, &index_array, format);
+
+ for (int j = 0; j < RS::ARRAY_CUSTOM_COUNT; j++) {
+ if (format & custom_mask[j]) {
+ last_custom_format[j] = (CustomFormat)((format >> custom_shift[j]) & RS::ARRAY_FORMAT_CUSTOM_MASK);
+ }
+ }
}
void SurfaceTool::append_from(const Ref<Mesh> &p_existing, int p_surface, const Transform3D &p_xform) {
@@ -878,6 +897,16 @@ void SurfaceTool::append_from(const Ref<Mesh> &p_existing, int p_surface, const
LocalVector<int> nindices;
_create_list(p_existing, p_surface, &nvertices, &nindices, nformat);
format |= nformat;
+
+ for (int j = 0; j < RS::ARRAY_CUSTOM_COUNT; j++) {
+ if (format & custom_mask[j]) {
+ CustomFormat new_format = (CustomFormat)((format >> custom_shift[j]) & RS::ARRAY_FORMAT_CUSTOM_MASK);
+ if (last_custom_format[j] != CUSTOM_MAX && last_custom_format[j] != new_format) {
+ WARN_PRINT(vformat("Custom %d format %d mismatch when appending format %d", j, last_custom_format[j], new_format));
+ }
+ last_custom_format[j] = new_format;
+ }
+ }
int vfrom = vertex_array.size();
for (uint32_t vi = 0; vi < nvertices.size(); vi++) {
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 063a13efc0..3dc32632cc 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -131,25 +131,6 @@ void ImageTexture::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::VECTOR2, "size", PROPERTY_HINT_NONE, ""));
}
-void ImageTexture::_reload_hook(const RID &p_hook) {
- String path = get_path();
- if (!path.is_resource_file()) {
- return;
- }
-
- Ref<Image> img;
- img.instantiate();
- Error err = ImageLoader::load_image(path, img);
-
- ERR_FAIL_COND_MSG(err != OK, "Cannot load image from path '" + path + "'.");
-
- RID new_texture = RenderingServer::get_singleton()->texture_2d_create(img);
- RenderingServer::get_singleton()->texture_replace(texture, new_texture);
-
- notify_property_list_changed();
- emit_changed();
-}
-
void ImageTexture::create_from_image(const Ref<Image> &p_image) {
ERR_FAIL_COND_MSG(p_image.is_null() || p_image->is_empty(), "Invalid image");
w = p_image->get_width();
@@ -192,10 +173,6 @@ void ImageTexture::update(const Ref<Image> &p_image) {
image_stored = true;
}
-void ImageTexture::_resource_path_changed() {
- String path = get_path();
-}
-
Ref<Image> ImageTexture::get_image() const {
if (image_stored) {
return RenderingServer::get_singleton()->texture_2d_get(texture);
@@ -303,7 +280,6 @@ void ImageTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("update", "image"), &ImageTexture::update);
ClassDB::bind_method(D_METHOD("set_size_override", "size"), &ImageTexture::set_size_override);
- ClassDB::bind_method(D_METHOD("_reload_hook", "rid"), &ImageTexture::_reload_hook);
}
ImageTexture::ImageTexture() {}
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index f6b991c335..93f4e2de5a 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -98,8 +98,6 @@ protected:
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
- void _reload_hook(const RID &p_hook);
- virtual void _resource_path_changed() override;
static void _bind_methods();
public:
diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp
index fcd31143a8..918fc3fe9c 100644
--- a/scene/resources/tile_set.cpp
+++ b/scene/resources/tile_set.cpp
@@ -205,25 +205,46 @@ bool TileSet::is_uv_clipping() const {
return uv_clipping;
};
-void TileSet::set_occlusion_layers_count(int p_occlusion_layers_count) {
- ERR_FAIL_COND(p_occlusion_layers_count < 0);
- if (occlusion_layers.size() == p_occlusion_layers_count) {
- return;
- }
+int TileSet::get_occlusion_layers_count() const {
+ return occlusion_layers.size();
+};
- occlusion_layers.resize(p_occlusion_layers_count);
+void TileSet::add_occlusion_layer(int p_index) {
+ if (p_index < 0) {
+ p_index = occlusion_layers.size();
+ }
+ ERR_FAIL_INDEX(p_index, occlusion_layers.size() + 1);
+ occlusion_layers.insert(p_index, OcclusionLayer());
- for (Map<int, Ref<TileSetSource>>::Element *E_source = sources.front(); E_source; E_source = E_source->next()) {
- E_source->get()->notify_tile_data_properties_should_change();
+ for (KeyValue<int, Ref<TileSetSource>> source : sources) {
+ source.value->add_occlusion_layer(p_index);
}
notify_property_list_changed();
emit_changed();
}
-int TileSet::get_occlusion_layers_count() const {
- return occlusion_layers.size();
-};
+void TileSet::move_occlusion_layer(int p_from_index, int p_to_pos) {
+ ERR_FAIL_INDEX(p_from_index, occlusion_layers.size());
+ ERR_FAIL_INDEX(p_to_pos, occlusion_layers.size() + 1);
+ occlusion_layers.insert(p_to_pos, occlusion_layers[p_from_index]);
+ occlusion_layers.remove(p_to_pos < p_from_index ? p_from_index + 1 : p_from_index);
+ for (KeyValue<int, Ref<TileSetSource>> source : sources) {
+ source.value->move_occlusion_layer(p_from_index, p_to_pos);
+ }
+ notify_property_list_changed();
+ emit_changed();
+}
+
+void TileSet::remove_occlusion_layer(int p_index) {
+ ERR_FAIL_INDEX(p_index, occlusion_layers.size());
+ occlusion_layers.remove(p_index);
+ for (KeyValue<int, Ref<TileSetSource>> source : sources) {
+ source.value->remove_occlusion_layer(p_index);
+ }
+ notify_property_list_changed();
+ emit_changed();
+}
void TileSet::set_occlusion_layer_light_mask(int p_layer_index, int p_light_mask) {
ERR_FAIL_INDEX(p_layer_index, occlusion_layers.size());
@@ -236,7 +257,7 @@ int TileSet::get_occlusion_layer_light_mask(int p_layer_index) const {
return occlusion_layers[p_layer_index].light_mask;
}
-void TileSet::set_occlusion_layer_sdf_collision(int p_layer_index, int p_sdf_collision) {
+void TileSet::set_occlusion_layer_sdf_collision(int p_layer_index, bool p_sdf_collision) {
ERR_FAIL_INDEX(p_layer_index, occlusion_layers.size());
occlusion_layers.write[p_layer_index].sdf_collision = p_sdf_collision;
emit_changed();
@@ -247,25 +268,45 @@ bool TileSet::get_occlusion_layer_sdf_collision(int p_layer_index) const {
return occlusion_layers[p_layer_index].sdf_collision;
}
-// Physics
-void TileSet::set_physics_layers_count(int p_physics_layers_count) {
- ERR_FAIL_COND(p_physics_layers_count < 0);
- if (physics_layers.size() == p_physics_layers_count) {
- return;
- }
+int TileSet::get_physics_layers_count() const {
+ return physics_layers.size();
+}
- physics_layers.resize(p_physics_layers_count);
+void TileSet::add_physics_layer(int p_index) {
+ if (p_index < 0) {
+ p_index = physics_layers.size();
+ }
+ ERR_FAIL_INDEX(p_index, physics_layers.size() + 1);
+ physics_layers.insert(p_index, PhysicsLayer());
- for (Map<int, Ref<TileSetSource>>::Element *E_source = sources.front(); E_source; E_source = E_source->next()) {
- E_source->get()->notify_tile_data_properties_should_change();
+ for (KeyValue<int, Ref<TileSetSource>> source : sources) {
+ source.value->add_physics_layer(p_index);
}
notify_property_list_changed();
emit_changed();
}
-int TileSet::get_physics_layers_count() const {
- return physics_layers.size();
+void TileSet::move_physics_layer(int p_from_index, int p_to_pos) {
+ ERR_FAIL_INDEX(p_from_index, physics_layers.size());
+ ERR_FAIL_INDEX(p_to_pos, physics_layers.size() + 1);
+ physics_layers.insert(p_to_pos, physics_layers[p_from_index]);
+ physics_layers.remove(p_to_pos < p_from_index ? p_from_index + 1 : p_from_index);
+ for (KeyValue<int, Ref<TileSetSource>> source : sources) {
+ source.value->move_physics_layer(p_from_index, p_to_pos);
+ }
+ notify_property_list_changed();
+ emit_changed();
+}
+
+void TileSet::remove_physics_layer(int p_index) {
+ ERR_FAIL_INDEX(p_index, physics_layers.size());
+ physics_layers.remove(p_index);
+ for (KeyValue<int, Ref<TileSetSource>> source : sources) {
+ source.value->remove_physics_layer(p_index);
+ }
+ notify_property_list_changed();
+ emit_changed();
}
void TileSet::set_physics_layer_collision_layer(int p_layer_index, uint32_t p_layer) {
@@ -301,17 +342,45 @@ Ref<PhysicsMaterial> TileSet::get_physics_layer_physics_material(int p_layer_ind
}
// Terrains
-void TileSet::set_terrain_sets_count(int p_terrains_sets_count) {
- ERR_FAIL_COND(p_terrains_sets_count < 0);
+int TileSet::get_terrain_sets_count() const {
+ return terrain_sets.size();
+}
- terrain_sets.resize(p_terrains_sets_count);
+void TileSet::add_terrain_set(int p_index) {
+ if (p_index < 0) {
+ p_index = terrain_sets.size();
+ }
+ ERR_FAIL_INDEX(p_index, terrain_sets.size() + 1);
+ terrain_sets.insert(p_index, TerrainSet());
+
+ for (KeyValue<int, Ref<TileSetSource>> source : sources) {
+ source.value->add_terrain_set(p_index);
+ }
notify_property_list_changed();
emit_changed();
}
-int TileSet::get_terrain_sets_count() const {
- return terrain_sets.size();
+void TileSet::move_terrain_set(int p_from_index, int p_to_pos) {
+ ERR_FAIL_INDEX(p_from_index, terrain_sets.size());
+ ERR_FAIL_INDEX(p_to_pos, terrain_sets.size() + 1);
+ terrain_sets.insert(p_to_pos, terrain_sets[p_from_index]);
+ terrain_sets.remove(p_to_pos < p_from_index ? p_from_index + 1 : p_from_index);
+ for (KeyValue<int, Ref<TileSetSource>> source : sources) {
+ source.value->move_terrain_set(p_from_index, p_to_pos);
+ }
+ notify_property_list_changed();
+ emit_changed();
+}
+
+void TileSet::remove_terrain_set(int p_index) {
+ ERR_FAIL_INDEX(p_index, terrain_sets.size());
+ terrain_sets.remove(p_index);
+ for (KeyValue<int, Ref<TileSetSource>> source : sources) {
+ source.value->remove_terrain_set(p_index);
+ }
+ notify_property_list_changed();
+ emit_changed();
}
void TileSet::set_terrain_set_mode(int p_terrain_set, TerrainMode p_terrain_mode) {
@@ -330,36 +399,61 @@ TileSet::TerrainMode TileSet::get_terrain_set_mode(int p_terrain_set) const {
return terrain_sets[p_terrain_set].mode;
}
-void TileSet::set_terrains_count(int p_terrain_set, int p_terrains_layers_count) {
+int TileSet::get_terrains_count(int p_terrain_set) const {
+ ERR_FAIL_INDEX_V(p_terrain_set, terrain_sets.size(), -1);
+ return terrain_sets[p_terrain_set].terrains.size();
+}
+
+void TileSet::add_terrain(int p_terrain_set, int p_index) {
ERR_FAIL_INDEX(p_terrain_set, terrain_sets.size());
- ERR_FAIL_COND(p_terrains_layers_count < 0);
- if (terrain_sets[p_terrain_set].terrains.size() == p_terrains_layers_count) {
- return;
+ Vector<Terrain> &terrains = terrain_sets.write[p_terrain_set].terrains;
+ if (p_index < 0) {
+ p_index = terrains.size();
}
-
- int old_size = terrain_sets[p_terrain_set].terrains.size();
- terrain_sets.write[p_terrain_set].terrains.resize(p_terrains_layers_count);
+ ERR_FAIL_INDEX(p_index, terrains.size() + 1);
+ terrains.insert(p_index, Terrain());
// Default name and color
- for (int i = old_size; i < terrain_sets.write[p_terrain_set].terrains.size(); i++) {
- float hue_rotate = (i * 2 % 16) / 16.0;
- Color c;
- c.set_hsv(Math::fmod(float(hue_rotate), float(1.0)), 0.5, 0.5);
- terrain_sets.write[p_terrain_set].terrains.write[i].color = c;
- terrain_sets.write[p_terrain_set].terrains.write[i].name = String(vformat("Terrain %d", i));
+ float hue_rotate = (terrains.size() % 16) / 16.0;
+ Color c;
+ c.set_hsv(Math::fmod(float(hue_rotate), float(1.0)), 0.5, 0.5);
+ terrains.write[p_index].color = c;
+ terrains.write[p_index].name = String(vformat("Terrain %d", p_index));
+
+ for (KeyValue<int, Ref<TileSetSource>> source : sources) {
+ source.value->add_terrain(p_terrain_set, p_index);
}
- for (Map<int, Ref<TileSetSource>>::Element *E_source = sources.front(); E_source; E_source = E_source->next()) {
- E_source->get()->notify_tile_data_properties_should_change();
- }
+ notify_property_list_changed();
+ emit_changed();
+}
+void TileSet::move_terrain(int p_terrain_set, int p_from_index, int p_to_pos) {
+ ERR_FAIL_INDEX(p_terrain_set, terrain_sets.size());
+ Vector<Terrain> &terrains = terrain_sets.write[p_terrain_set].terrains;
+
+ ERR_FAIL_INDEX(p_from_index, terrains.size());
+ ERR_FAIL_INDEX(p_to_pos, terrains.size() + 1);
+ terrains.insert(p_to_pos, terrains[p_from_index]);
+ terrains.remove(p_to_pos < p_from_index ? p_from_index + 1 : p_from_index);
+ for (KeyValue<int, Ref<TileSetSource>> source : sources) {
+ source.value->move_terrain(p_terrain_set, p_from_index, p_to_pos);
+ }
notify_property_list_changed();
emit_changed();
}
-int TileSet::get_terrains_count(int p_terrain_set) const {
- ERR_FAIL_INDEX_V(p_terrain_set, terrain_sets.size(), -1);
- return terrain_sets[p_terrain_set].terrains.size();
+void TileSet::remove_terrain(int p_terrain_set, int p_index) {
+ ERR_FAIL_INDEX(p_terrain_set, terrain_sets.size());
+ Vector<Terrain> &terrains = terrain_sets.write[p_terrain_set].terrains;
+
+ ERR_FAIL_INDEX(p_index, terrains.size());
+ terrains.remove(p_index);
+ for (KeyValue<int, Ref<TileSetSource>> source : sources) {
+ source.value->remove_terrain(p_terrain_set, p_index);
+ }
+ notify_property_list_changed();
+ emit_changed();
}
void TileSet::set_terrain_name(int p_terrain_set, int p_terrain_index, String p_name) {
@@ -485,24 +579,45 @@ bool TileSet::is_valid_peering_bit_terrain(int p_terrain_set, TileSet::CellNeigh
}
// Navigation
-void TileSet::set_navigation_layers_count(int p_navigation_layers_count) {
- ERR_FAIL_COND(p_navigation_layers_count < 0);
- if (navigation_layers.size() == p_navigation_layers_count) {
- return;
- }
+int TileSet::get_navigation_layers_count() const {
+ return navigation_layers.size();
+}
- navigation_layers.resize(p_navigation_layers_count);
+void TileSet::add_navigation_layer(int p_index) {
+ if (p_index < 0) {
+ p_index = navigation_layers.size();
+ }
+ ERR_FAIL_INDEX(p_index, navigation_layers.size() + 1);
+ navigation_layers.insert(p_index, NavigationLayer());
- for (Map<int, Ref<TileSetSource>>::Element *E_source = sources.front(); E_source; E_source = E_source->next()) {
- E_source->get()->notify_tile_data_properties_should_change();
+ for (KeyValue<int, Ref<TileSetSource>> source : sources) {
+ source.value->add_navigation_layer(p_index);
}
notify_property_list_changed();
emit_changed();
}
-int TileSet::get_navigation_layers_count() const {
- return navigation_layers.size();
+void TileSet::move_navigation_layer(int p_from_index, int p_to_pos) {
+ ERR_FAIL_INDEX(p_from_index, navigation_layers.size());
+ ERR_FAIL_INDEX(p_to_pos, navigation_layers.size() + 1);
+ navigation_layers.insert(p_to_pos, navigation_layers[p_from_index]);
+ navigation_layers.remove(p_to_pos < p_from_index ? p_from_index + 1 : p_from_index);
+ for (KeyValue<int, Ref<TileSetSource>> source : sources) {
+ source.value->move_navigation_layer(p_from_index, p_to_pos);
+ }
+ notify_property_list_changed();
+ emit_changed();
+}
+
+void TileSet::remove_navigation_layer(int p_index) {
+ ERR_FAIL_INDEX(p_index, navigation_layers.size());
+ navigation_layers.remove(p_index);
+ for (KeyValue<int, Ref<TileSetSource>> source : sources) {
+ source.value->remove_navigation_layer(p_index);
+ }
+ notify_property_list_changed();
+ emit_changed();
}
void TileSet::set_navigation_layer_layers(int p_layer_index, uint32_t p_layers) {
@@ -517,30 +632,52 @@ uint32_t TileSet::get_navigation_layer_layers(int p_layer_index) const {
}
// Custom data.
-void TileSet::set_custom_data_layers_count(int p_custom_data_layers_count) {
- ERR_FAIL_COND(p_custom_data_layers_count < 0);
- if (custom_data_layers.size() == p_custom_data_layers_count) {
- return;
- }
-
- custom_data_layers.resize(p_custom_data_layers_count);
+int TileSet::get_custom_data_layers_count() const {
+ return custom_data_layers.size();
+}
- for (Map<String, int>::Element *E = custom_data_layers_by_name.front(); E; E = E->next()) {
- if (E->get() >= custom_data_layers.size()) {
- custom_data_layers_by_name.erase(E);
- }
+void TileSet::add_custom_data_layer(int p_index) {
+ if (p_index < 0) {
+ p_index = custom_data_layers.size();
}
+ ERR_FAIL_INDEX(p_index, custom_data_layers.size() + 1);
+ custom_data_layers.insert(p_index, CustomDataLayer());
- for (Map<int, Ref<TileSetSource>>::Element *E_source = sources.front(); E_source; E_source = E_source->next()) {
- E_source->get()->notify_tile_data_properties_should_change();
+ for (KeyValue<int, Ref<TileSetSource>> source : sources) {
+ source.value->add_custom_data_layer(p_index);
}
notify_property_list_changed();
emit_changed();
}
-int TileSet::get_custom_data_layers_count() const {
- return custom_data_layers.size();
+void TileSet::move_custom_data_layer(int p_from_index, int p_to_pos) {
+ ERR_FAIL_INDEX(p_from_index, custom_data_layers.size());
+ ERR_FAIL_INDEX(p_to_pos, custom_data_layers.size() + 1);
+ custom_data_layers.insert(p_to_pos, custom_data_layers[p_from_index]);
+ custom_data_layers.remove(p_to_pos < p_from_index ? p_from_index + 1 : p_from_index);
+ for (KeyValue<int, Ref<TileSetSource>> source : sources) {
+ source.value->move_custom_data_layer(p_from_index, p_to_pos);
+ }
+ notify_property_list_changed();
+ emit_changed();
+}
+
+void TileSet::remove_custom_data_layer(int p_index) {
+ ERR_FAIL_INDEX(p_index, custom_data_layers.size());
+ custom_data_layers.remove(p_index);
+ for (KeyValue<String, int> E : custom_data_layers_by_name) {
+ if (E.value == p_index) {
+ custom_data_layers_by_name.erase(E.key);
+ break;
+ }
+ }
+
+ for (KeyValue<int, Ref<TileSetSource>> source : sources) {
+ source.value->remove_custom_data_layer(p_index);
+ }
+ notify_property_list_changed();
+ emit_changed();
}
int TileSet::get_custom_data_layer_by_name(String p_value) const {
@@ -845,10 +982,10 @@ void TileSet::clear_tile_proxies() {
Vector<Vector2> TileSet::get_tile_shape_polygon() {
Vector<Vector2> points;
if (tile_shape == TileSet::TILE_SHAPE_SQUARE) {
- points.append(Vector2(0.0, 0.0));
- points.append(Vector2(1.0, 0.0));
- points.append(Vector2(1.0, 1.0));
- points.append(Vector2(0.0, 1.0));
+ points.append(Vector2(-0.5, -0.5));
+ points.append(Vector2(0.5, -0.5));
+ points.append(Vector2(0.5, 0.5));
+ points.append(Vector2(-0.5, 0.5));
} else {
float overlap = 0.0;
switch (tile_shape) {
@@ -865,31 +1002,24 @@ Vector<Vector2> TileSet::get_tile_shape_polygon() {
break;
}
- points.append(Vector2(0.5, 0.0));
- points.append(Vector2(0.0, overlap));
- points.append(Vector2(0.0, 1.0 - overlap));
- points.append(Vector2(0.5, 1.0));
- points.append(Vector2(1.0, 1.0 - overlap));
- points.append(Vector2(1.0, overlap));
- points.append(Vector2(0.5, 0.0));
+ points.append(Vector2(0.0, -0.5));
+ points.append(Vector2(-0.5, overlap - 0.5));
+ points.append(Vector2(-0.5, 0.5 - overlap));
+ points.append(Vector2(0.0, 0.5));
+ points.append(Vector2(0.5, 0.5 - overlap));
+ points.append(Vector2(0.5, overlap - 0.5));
if (get_tile_offset_axis() == TileSet::TILE_OFFSET_AXIS_VERTICAL) {
for (int i = 0; i < points.size(); i++) {
points.write[i] = Vector2(points[i].y, points[i].x);
}
}
}
- for (int i = 0; i < points.size(); i++) {
- points.write[i] = points[i] * tile_size - tile_size / 2;
- }
return points;
}
-void TileSet::draw_tile_shape(CanvasItem *p_canvas_item, Rect2 p_region, Color p_color, bool p_filled, Ref<Texture2D> p_texture) {
+void TileSet::draw_tile_shape(CanvasItem *p_canvas_item, Transform2D p_transform, Color p_color, bool p_filled, Ref<Texture2D> p_texture) {
if (tile_meshes_dirty) {
Vector<Vector2> uvs = get_tile_shape_polygon();
- for (int i = 0; i < uvs.size(); i++) {
- uvs.write[i] = (uvs[i] + tile_size / 2) / tile_size;
- }
Vector<Color> colors;
colors.resize(uvs.size());
@@ -919,13 +1049,10 @@ void TileSet::draw_tile_shape(CanvasItem *p_canvas_item, Rect2 p_region, Color p
tile_meshes_dirty = false;
}
- Transform2D xform;
- xform.scale(p_region.size);
- xform.set_origin(p_region.get_position());
if (p_filled) {
- p_canvas_item->draw_mesh(tile_filled_mesh, p_texture, xform, p_color);
+ p_canvas_item->draw_mesh(tile_filled_mesh, p_texture, p_transform, p_color);
} else {
- p_canvas_item->draw_mesh(tile_lines_mesh, Ref<Texture2D>(), xform, p_color);
+ p_canvas_item->draw_mesh(tile_lines_mesh, Ref<Texture2D>(), p_transform, p_color);
}
}
@@ -1110,7 +1237,11 @@ Vector<Vector<Ref<Texture2D>>> TileSet::generate_terrains_icons(Size2i p_size) {
if (is_valid_peering_bit_terrain(terrain_set, cell_neighbor)) {
int terrain = tile_data->get_peering_bit_terrain(cell_neighbor);
if (terrain >= 0) {
- bit_counts[terrain] += 1;
+ if (terrain >= (int)bit_counts.size()) {
+ WARN_PRINT(vformat("Invalid peering bit terrain: %d", terrain));
+ } else {
+ bit_counts[terrain] += 1;
+ }
}
}
}
@@ -1825,19 +1956,19 @@ void TileSet::_compatibility_conversion() {
tile_data->set_flip_h(flip_h);
tile_data->set_flip_v(flip_v);
tile_data->set_transpose(transpose);
- tile_data->tile_set_material(ctd->material);
+ tile_data->set_material(ctd->material);
tile_data->set_modulate(ctd->modulate);
tile_data->set_z_index(ctd->z_index);
if (ctd->occluder.is_valid()) {
if (get_occlusion_layers_count() < 1) {
- set_occlusion_layers_count(1);
+ add_occlusion_layer();
}
tile_data->set_occluder(0, ctd->occluder);
}
if (ctd->navigation.is_valid()) {
if (get_navigation_layers_count() < 1) {
- set_navigation_layers_count(1);
+ add_navigation_layer();
}
tile_data->set_navigation_polygon(0, ctd->autotile_navpoly_map[coords]);
}
@@ -1847,7 +1978,7 @@ void TileSet::_compatibility_conversion() {
// Add the shapes.
if (ctd->shapes.size() > 0) {
if (get_physics_layers_count() < 1) {
- set_physics_layers_count(1);
+ add_physics_layer();
}
}
for (int k = 0; k < ctd->shapes.size(); k++) {
@@ -1917,18 +2048,18 @@ void TileSet::_compatibility_conversion() {
tile_data->set_flip_h(flip_h);
tile_data->set_flip_v(flip_v);
tile_data->set_transpose(transpose);
- tile_data->tile_set_material(ctd->material);
+ tile_data->set_material(ctd->material);
tile_data->set_modulate(ctd->modulate);
tile_data->set_z_index(ctd->z_index);
if (ctd->autotile_occluder_map.has(coords)) {
if (get_occlusion_layers_count() < 1) {
- set_occlusion_layers_count(1);
+ add_occlusion_layer();
}
tile_data->set_occluder(0, ctd->autotile_occluder_map[coords]);
}
if (ctd->autotile_navpoly_map.has(coords)) {
if (get_navigation_layers_count() < 1) {
- set_navigation_layers_count(1);
+ add_navigation_layer();
}
tile_data->set_navigation_polygon(0, ctd->autotile_navpoly_map[coords]);
}
@@ -1942,7 +2073,7 @@ void TileSet::_compatibility_conversion() {
// Add the shapes.
if (ctd->shapes.size() > 0) {
if (get_physics_layers_count() < 1) {
- set_physics_layers_count(1);
+ add_physics_layer();
}
}
for (int k = 0; k < ctd->shapes.size(); k++) {
@@ -2206,15 +2337,15 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
ERR_FAIL_COND_V(index < 0, false);
if (components[1] == "light_mask") {
ERR_FAIL_COND_V(p_value.get_type() != Variant::INT, false);
- if (index >= occlusion_layers.size()) {
- set_occlusion_layers_count(index + 1);
+ while (index >= occlusion_layers.size()) {
+ add_occlusion_layer();
}
set_occlusion_layer_light_mask(index, p_value);
return true;
} else if (components[1] == "sdf_collision") {
ERR_FAIL_COND_V(p_value.get_type() != Variant::BOOL, false);
- if (index >= occlusion_layers.size()) {
- set_occlusion_layers_count(index + 1);
+ while (index >= occlusion_layers.size()) {
+ add_occlusion_layer();
}
set_occlusion_layer_sdf_collision(index, p_value);
return true;
@@ -2225,23 +2356,22 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
ERR_FAIL_COND_V(index < 0, false);
if (components[1] == "collision_layer") {
ERR_FAIL_COND_V(p_value.get_type() != Variant::INT, false);
- if (index >= physics_layers.size()) {
- set_physics_layers_count(index + 1);
+ while (index >= physics_layers.size()) {
+ add_physics_layer();
}
set_physics_layer_collision_layer(index, p_value);
return true;
} else if (components[1] == "collision_mask") {
ERR_FAIL_COND_V(p_value.get_type() != Variant::INT, false);
- if (index >= physics_layers.size()) {
- set_physics_layers_count(index + 1);
+ while (index >= physics_layers.size()) {
+ add_physics_layer();
}
set_physics_layer_collision_mask(index, p_value);
return true;
} else if (components[1] == "physics_material") {
Ref<PhysicsMaterial> physics_material = p_value;
- ERR_FAIL_COND_V(!physics_material.is_valid(), false);
- if (index >= physics_layers.size()) {
- set_physics_layers_count(index + 1);
+ while (index >= physics_layers.size()) {
+ add_physics_layer();
}
set_physics_layer_physics_material(index, physics_material);
return true;
@@ -2252,37 +2382,30 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
ERR_FAIL_COND_V(terrain_set_index < 0, false);
if (components[1] == "mode") {
ERR_FAIL_COND_V(p_value.get_type() != Variant::INT, false);
- if (terrain_set_index >= terrain_sets.size()) {
- set_terrain_sets_count(terrain_set_index + 1);
+ while (terrain_set_index >= terrain_sets.size()) {
+ add_terrain_set();
}
set_terrain_set_mode(terrain_set_index, TerrainMode(int(p_value)));
- } else if (components[1] == "terrains_count") {
- ERR_FAIL_COND_V(p_value.get_type() != Variant::INT, false);
- if (terrain_set_index >= terrain_sets.size()) {
- set_terrain_sets_count(terrain_set_index + 1);
- }
- set_terrains_count(terrain_set_index, p_value);
- return true;
} else if (components.size() >= 3 && components[1].begins_with("terrain_") && components[1].trim_prefix("terrain_").is_valid_int()) {
int terrain_index = components[1].trim_prefix("terrain_").to_int();
ERR_FAIL_COND_V(terrain_index < 0, false);
if (components[2] == "name") {
ERR_FAIL_COND_V(p_value.get_type() != Variant::STRING, false);
- if (terrain_set_index >= terrain_sets.size()) {
- set_terrain_sets_count(terrain_set_index + 1);
+ while (terrain_set_index >= terrain_sets.size()) {
+ add_terrain_set();
}
- if (terrain_index >= terrain_sets[terrain_set_index].terrains.size()) {
- set_terrains_count(terrain_set_index, terrain_index + 1);
+ while (terrain_index >= terrain_sets[terrain_set_index].terrains.size()) {
+ add_terrain(terrain_set_index);
}
set_terrain_name(terrain_set_index, terrain_index, p_value);
return true;
} else if (components[2] == "color") {
ERR_FAIL_COND_V(p_value.get_type() != Variant::COLOR, false);
- if (terrain_set_index >= terrain_sets.size()) {
- set_terrain_sets_count(terrain_set_index + 1);
+ while (terrain_set_index >= terrain_sets.size()) {
+ add_terrain_set();
}
- if (terrain_index >= terrain_sets[terrain_set_index].terrains.size()) {
- set_terrains_count(terrain_set_index, terrain_index + 1);
+ while (terrain_index >= terrain_sets[terrain_set_index].terrains.size()) {
+ add_terrain(terrain_set_index);
}
set_terrain_color(terrain_set_index, terrain_index, p_value);
return true;
@@ -2294,8 +2417,8 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
ERR_FAIL_COND_V(index < 0, false);
if (components[1] == "layers") {
ERR_FAIL_COND_V(p_value.get_type() != Variant::INT, false);
- if (index >= navigation_layers.size()) {
- set_navigation_layers_count(index + 1);
+ while (index >= navigation_layers.size()) {
+ add_navigation_layer();
}
set_navigation_layer_layers(index, p_value);
return true;
@@ -2306,15 +2429,15 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
ERR_FAIL_COND_V(index < 0, false);
if (components[1] == "name") {
ERR_FAIL_COND_V(p_value.get_type() != Variant::STRING, false);
- if (index >= custom_data_layers.size()) {
- set_custom_data_layers_count(index + 1);
+ while (index >= custom_data_layers.size()) {
+ add_custom_data_layer();
}
set_custom_data_name(index, p_value);
return true;
} else if (components[1] == "type") {
ERR_FAIL_COND_V(p_value.get_type() != Variant::INT, false);
- if (index >= custom_data_layers.size()) {
- set_custom_data_layers_count(index + 1);
+ while (index >= custom_data_layers.size()) {
+ add_custom_data_layer();
}
set_custom_data_type(index, Variant::Type(int(p_value)));
return true;
@@ -2402,9 +2525,6 @@ bool TileSet::_get(const StringName &p_name, Variant &r_ret) const {
if (components[1] == "mode") {
r_ret = get_terrain_set_mode(terrain_set_index);
return true;
- } else if (components[1] == "terrains_count") {
- r_ret = get_terrains_count(terrain_set_index);
- return true;
} else if (components.size() >= 3 && components[1].begins_with("terrain_") && components[1].trim_prefix("terrain_").is_valid_int()) {
int terrain_index = components[1].trim_prefix("terrain_").to_int();
if (terrain_index < 0 || terrain_index >= terrain_sets[terrain_set_index].terrains.size()) {
@@ -2522,7 +2642,7 @@ void TileSet::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::NIL, "Terrains", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP));
for (int terrain_set_index = 0; terrain_set_index < terrain_sets.size(); terrain_set_index++) {
p_list->push_back(PropertyInfo(Variant::INT, vformat("terrain_set_%d/mode", terrain_set_index), PROPERTY_HINT_ENUM, "Match corners and sides,Match corners,Match sides"));
- p_list->push_back(PropertyInfo(Variant::INT, vformat("terrain_set_%d/terrains_count", terrain_set_index), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
+ p_list->push_back(PropertyInfo(Variant::NIL, vformat("terrain_set_%d/terrains", terrain_set_index), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_ARRAY, vformat("terrain_set_%d/terrain_", terrain_set_index)));
for (int terrain_index = 0; terrain_index < terrain_sets[terrain_set_index].terrains.size(); terrain_index++) {
p_list->push_back(PropertyInfo(Variant::STRING, vformat("terrain_set_%d/terrain_%d/name", terrain_set_index, terrain_index)));
p_list->push_back(PropertyInfo(Variant::COLOR, vformat("terrain_set_%d/terrain_%d/color", terrain_set_index, terrain_index)));
@@ -2563,13 +2683,13 @@ void TileSet::_get_property_list(List<PropertyInfo> *p_list) const {
void TileSet::_bind_methods() {
// Sources management.
ClassDB::bind_method(D_METHOD("get_next_source_id"), &TileSet::get_next_source_id);
- ClassDB::bind_method(D_METHOD("add_source", "atlas_source_id_override"), &TileSet::add_source, DEFVAL(TileSet::INVALID_SOURCE));
+ ClassDB::bind_method(D_METHOD("add_source", "source", "atlas_source_id_override"), &TileSet::add_source, DEFVAL(TileSet::INVALID_SOURCE));
ClassDB::bind_method(D_METHOD("remove_source", "source_id"), &TileSet::remove_source);
- ClassDB::bind_method(D_METHOD("set_source_id", "source_id"), &TileSet::set_source_id);
+ ClassDB::bind_method(D_METHOD("set_source_id", "source_id", "new_source_id"), &TileSet::set_source_id);
ClassDB::bind_method(D_METHOD("get_source_count"), &TileSet::get_source_count);
ClassDB::bind_method(D_METHOD("get_source_id", "index"), &TileSet::get_source_id);
- ClassDB::bind_method(D_METHOD("has_source", "index"), &TileSet::has_source);
- ClassDB::bind_method(D_METHOD("get_source", "index"), &TileSet::get_source);
+ ClassDB::bind_method(D_METHOD("has_source", "source_id"), &TileSet::has_source);
+ ClassDB::bind_method(D_METHOD("get_source", "source_id"), &TileSet::get_source);
// Shape and layout.
ClassDB::bind_method(D_METHOD("set_tile_shape", "shape"), &TileSet::set_tile_shape);
@@ -2590,16 +2710,20 @@ void TileSet::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_uv_clipping", "uv_clipping"), &TileSet::set_uv_clipping);
ClassDB::bind_method(D_METHOD("is_uv_clipping"), &TileSet::is_uv_clipping);
- ClassDB::bind_method(D_METHOD("set_occlusion_layers_count", "occlusion_layers_count"), &TileSet::set_occlusion_layers_count);
ClassDB::bind_method(D_METHOD("get_occlusion_layers_count"), &TileSet::get_occlusion_layers_count);
+ ClassDB::bind_method(D_METHOD("add_occlusion_layer", "to_position"), &TileSet::add_occlusion_layer, DEFVAL(-1));
+ ClassDB::bind_method(D_METHOD("move_occlusion_layer", "layer_index", "to_position"), &TileSet::move_occlusion_layer);
+ ClassDB::bind_method(D_METHOD("remove_occlusion_layer", "layer_index"), &TileSet::remove_occlusion_layer);
ClassDB::bind_method(D_METHOD("set_occlusion_layer_light_mask", "layer_index", "light_mask"), &TileSet::set_occlusion_layer_light_mask);
- ClassDB::bind_method(D_METHOD("get_occlusion_layer_light_mask"), &TileSet::get_occlusion_layer_light_mask);
+ ClassDB::bind_method(D_METHOD("get_occlusion_layer_light_mask", "layer_index"), &TileSet::get_occlusion_layer_light_mask);
ClassDB::bind_method(D_METHOD("set_occlusion_layer_sdf_collision", "layer_index", "sdf_collision"), &TileSet::set_occlusion_layer_sdf_collision);
- ClassDB::bind_method(D_METHOD("get_occlusion_layer_sdf_collision"), &TileSet::get_occlusion_layer_sdf_collision);
+ ClassDB::bind_method(D_METHOD("get_occlusion_layer_sdf_collision", "layer_index"), &TileSet::get_occlusion_layer_sdf_collision);
// Physics
- ClassDB::bind_method(D_METHOD("set_physics_layers_count", "physics_layers_count"), &TileSet::set_physics_layers_count);
ClassDB::bind_method(D_METHOD("get_physics_layers_count"), &TileSet::get_physics_layers_count);
+ ClassDB::bind_method(D_METHOD("add_physics_layer", "to_position"), &TileSet::add_physics_layer, DEFVAL(-1));
+ ClassDB::bind_method(D_METHOD("move_physics_layer", "layer_index", "to_position"), &TileSet::move_physics_layer);
+ ClassDB::bind_method(D_METHOD("remove_physics_layer", "layer_index"), &TileSet::remove_physics_layer);
ClassDB::bind_method(D_METHOD("set_physics_layer_collision_layer", "layer_index", "layer"), &TileSet::set_physics_layer_collision_layer);
ClassDB::bind_method(D_METHOD("get_physics_layer_collision_layer", "layer_index"), &TileSet::get_physics_layer_collision_layer);
ClassDB::bind_method(D_METHOD("set_physics_layer_collision_mask", "layer_index", "mask"), &TileSet::set_physics_layer_collision_mask);
@@ -2608,27 +2732,35 @@ void TileSet::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_physics_layer_physics_material", "layer_index"), &TileSet::get_physics_layer_physics_material);
// Terrains
- ClassDB::bind_method(D_METHOD("set_terrain_sets_count", "terrain_sets_count"), &TileSet::set_terrain_sets_count);
ClassDB::bind_method(D_METHOD("get_terrain_sets_count"), &TileSet::get_terrain_sets_count);
+ ClassDB::bind_method(D_METHOD("add_terrain_set", "to_position"), &TileSet::add_terrain_set, DEFVAL(-1));
+ ClassDB::bind_method(D_METHOD("move_terrain_set", "terrain_set", "to_position"), &TileSet::move_terrain_set);
+ ClassDB::bind_method(D_METHOD("remove_terrain_set", "terrain_set"), &TileSet::remove_terrain_set);
ClassDB::bind_method(D_METHOD("set_terrain_set_mode", "terrain_set", "mode"), &TileSet::set_terrain_set_mode);
ClassDB::bind_method(D_METHOD("get_terrain_set_mode", "terrain_set"), &TileSet::get_terrain_set_mode);
- ClassDB::bind_method(D_METHOD("set_terrains_count", "terrain_set", "terrains_count"), &TileSet::set_terrains_count);
ClassDB::bind_method(D_METHOD("get_terrains_count", "terrain_set"), &TileSet::get_terrains_count);
+ ClassDB::bind_method(D_METHOD("add_terrain", "terrain_set", "to_position"), &TileSet::add_terrain, DEFVAL(-1));
+ ClassDB::bind_method(D_METHOD("move_terrain", "terrain_set", "terrain_index", "to_position"), &TileSet::move_terrain);
+ ClassDB::bind_method(D_METHOD("remove_terrain", "terrain_set", "terrain_index"), &TileSet::remove_terrain);
ClassDB::bind_method(D_METHOD("set_terrain_name", "terrain_set", "terrain_index", "name"), &TileSet::set_terrain_name);
ClassDB::bind_method(D_METHOD("get_terrain_name", "terrain_set", "terrain_index"), &TileSet::get_terrain_name);
ClassDB::bind_method(D_METHOD("set_terrain_color", "terrain_set", "terrain_index", "color"), &TileSet::set_terrain_color);
ClassDB::bind_method(D_METHOD("get_terrain_color", "terrain_set", "terrain_index"), &TileSet::get_terrain_color);
// Navigation
- ClassDB::bind_method(D_METHOD("set_navigation_layers_count", "navigation_layers_count"), &TileSet::set_navigation_layers_count);
ClassDB::bind_method(D_METHOD("get_navigation_layers_count"), &TileSet::get_navigation_layers_count);
+ ClassDB::bind_method(D_METHOD("add_navigation_layer", "to_position"), &TileSet::add_navigation_layer, DEFVAL(-1));
+ ClassDB::bind_method(D_METHOD("move_navigation_layer", "layer_index", "to_position"), &TileSet::move_navigation_layer);
+ ClassDB::bind_method(D_METHOD("remove_navigation_layer", "layer_index"), &TileSet::remove_navigation_layer);
ClassDB::bind_method(D_METHOD("set_navigation_layer_layers", "layer_index", "layers"), &TileSet::set_navigation_layer_layers);
ClassDB::bind_method(D_METHOD("get_navigation_layer_layers", "layer_index"), &TileSet::get_navigation_layer_layers);
// Custom data
- ClassDB::bind_method(D_METHOD("set_custom_data_layers_count", "custom_data_layers_count"), &TileSet::set_custom_data_layers_count);
ClassDB::bind_method(D_METHOD("get_custom_data_layers_count"), &TileSet::get_custom_data_layers_count);
+ ClassDB::bind_method(D_METHOD("add_custom_data_layer", "to_position"), &TileSet::add_custom_data_layer, DEFVAL(-1));
+ ClassDB::bind_method(D_METHOD("move_custom_data_layer", "layer_index", "to_position"), &TileSet::move_custom_data_layer);
+ ClassDB::bind_method(D_METHOD("remove_custom_data_layer", "layer_index"), &TileSet::remove_custom_data_layer);
// Tile proxies
ClassDB::bind_method(D_METHOD("set_source_level_tile_proxy", "source_from", "source_to"), &TileSet::set_source_level_tile_proxy);
@@ -2653,19 +2785,19 @@ void TileSet::_bind_methods() {
ADD_GROUP("Rendering", "");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "uv_clipping"), "set_uv_clipping", "is_uv_clipping");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "occlusion_layers_count", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_occlusion_layers_count", "get_occlusion_layers_count");
+ ADD_ARRAY("occlusion_layers", "occlusion_layer_");
ADD_GROUP("Physics", "");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "physics_layers_count", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_physics_layers_count", "get_physics_layers_count");
+ ADD_ARRAY("physics_layers", "physics_layer_");
ADD_GROUP("Terrains", "");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "terrains_sets_count", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_terrain_sets_count", "get_terrain_sets_count");
+ ADD_ARRAY("terrain_sets", "terrain_set_");
ADD_GROUP("Navigation", "");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers_count", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_navigation_layers_count", "get_navigation_layers_count");
+ ADD_ARRAY("navigation_layers", "navigation_layer_");
ADD_GROUP("Custom data", "");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "custom_data_layers_count", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_custom_data_layers_count", "get_custom_data_layers_count");
+ ADD_ARRAY("custom_data_layers", "custom_data_layer_");
// -- Enum binding --
BIND_ENUM_CONSTANT(TILE_SHAPE_SQUARE);
@@ -2728,6 +2860,18 @@ void TileSetSource::set_tile_set(const TileSet *p_tile_set) {
tile_set = p_tile_set;
}
+void TileSetSource::_bind_methods() {
+ // Base tiles
+ ClassDB::bind_method(D_METHOD("get_tiles_count"), &TileSetSource::get_tiles_count);
+ ClassDB::bind_method(D_METHOD("get_tile_id", "index"), &TileSetSource::get_tile_id);
+ ClassDB::bind_method(D_METHOD("has_tile", "atlas_coords"), &TileSetSource::has_tile);
+
+ // Alternative tiles
+ ClassDB::bind_method(D_METHOD("get_alternative_tiles_count", "atlas_coords"), &TileSetSource::get_alternative_tiles_count);
+ ClassDB::bind_method(D_METHOD("get_alternative_tile_id", "atlas_coords", "index"), &TileSetSource::get_alternative_tile_id);
+ ClassDB::bind_method(D_METHOD("has_alternative_tile", "atlas_coords", "alternative_tile"), &TileSetSource::has_alternative_tile);
+}
+
/////////////////////////////// TileSetAtlasSource //////////////////////////////////////
void TileSetAtlasSource::set_tile_set(const TileSet *p_tile_set) {
@@ -2750,6 +2894,150 @@ void TileSetAtlasSource::notify_tile_data_properties_should_change() {
}
}
+void TileSetAtlasSource::add_occlusion_layer(int p_to_pos) {
+ for (KeyValue<Vector2i, TileAlternativesData> E_tile : tiles) {
+ for (KeyValue<int, TileData *> E_alternative : E_tile.value.alternatives) {
+ E_alternative.value->add_occlusion_layer(p_to_pos);
+ }
+ }
+}
+
+void TileSetAtlasSource::move_occlusion_layer(int p_from_index, int p_to_pos) {
+ for (KeyValue<Vector2i, TileAlternativesData> E_tile : tiles) {
+ for (KeyValue<int, TileData *> E_alternative : E_tile.value.alternatives) {
+ E_alternative.value->move_occlusion_layer(p_from_index, p_to_pos);
+ }
+ }
+}
+
+void TileSetAtlasSource::remove_occlusion_layer(int p_index) {
+ for (KeyValue<Vector2i, TileAlternativesData> E_tile : tiles) {
+ for (KeyValue<int, TileData *> E_alternative : E_tile.value.alternatives) {
+ E_alternative.value->remove_occlusion_layer(p_index);
+ }
+ }
+}
+
+void TileSetAtlasSource::add_physics_layer(int p_to_pos) {
+ for (KeyValue<Vector2i, TileAlternativesData> E_tile : tiles) {
+ for (KeyValue<int, TileData *> E_alternative : E_tile.value.alternatives) {
+ E_alternative.value->add_physics_layer(p_to_pos);
+ }
+ }
+}
+
+void TileSetAtlasSource::move_physics_layer(int p_from_index, int p_to_pos) {
+ for (KeyValue<Vector2i, TileAlternativesData> E_tile : tiles) {
+ for (KeyValue<int, TileData *> E_alternative : E_tile.value.alternatives) {
+ E_alternative.value->move_physics_layer(p_from_index, p_to_pos);
+ }
+ }
+}
+
+void TileSetAtlasSource::remove_physics_layer(int p_index) {
+ for (KeyValue<Vector2i, TileAlternativesData> E_tile : tiles) {
+ for (KeyValue<int, TileData *> E_alternative : E_tile.value.alternatives) {
+ E_alternative.value->remove_physics_layer(p_index);
+ }
+ }
+}
+
+void TileSetAtlasSource::add_terrain_set(int p_to_pos) {
+ for (KeyValue<Vector2i, TileAlternativesData> E_tile : tiles) {
+ for (KeyValue<int, TileData *> E_alternative : E_tile.value.alternatives) {
+ E_alternative.value->add_terrain_set(p_to_pos);
+ }
+ }
+}
+
+void TileSetAtlasSource::move_terrain_set(int p_from_index, int p_to_pos) {
+ for (KeyValue<Vector2i, TileAlternativesData> E_tile : tiles) {
+ for (KeyValue<int, TileData *> E_alternative : E_tile.value.alternatives) {
+ E_alternative.value->move_terrain_set(p_from_index, p_to_pos);
+ }
+ }
+}
+
+void TileSetAtlasSource::remove_terrain_set(int p_index) {
+ for (KeyValue<Vector2i, TileAlternativesData> E_tile : tiles) {
+ for (KeyValue<int, TileData *> E_alternative : E_tile.value.alternatives) {
+ E_alternative.value->remove_terrain_set(p_index);
+ }
+ }
+}
+
+void TileSetAtlasSource::add_terrain(int p_terrain_set, int p_to_pos) {
+ for (KeyValue<Vector2i, TileAlternativesData> E_tile : tiles) {
+ for (KeyValue<int, TileData *> E_alternative : E_tile.value.alternatives) {
+ E_alternative.value->add_terrain(p_terrain_set, p_to_pos);
+ }
+ }
+}
+
+void TileSetAtlasSource::move_terrain(int p_terrain_set, int p_from_index, int p_to_pos) {
+ for (KeyValue<Vector2i, TileAlternativesData> E_tile : tiles) {
+ for (KeyValue<int, TileData *> E_alternative : E_tile.value.alternatives) {
+ E_alternative.value->move_terrain(p_terrain_set, p_from_index, p_to_pos);
+ }
+ }
+}
+
+void TileSetAtlasSource::remove_terrain(int p_terrain_set, int p_index) {
+ for (KeyValue<Vector2i, TileAlternativesData> E_tile : tiles) {
+ for (KeyValue<int, TileData *> E_alternative : E_tile.value.alternatives) {
+ E_alternative.value->remove_terrain(p_terrain_set, p_index);
+ }
+ }
+}
+
+void TileSetAtlasSource::add_navigation_layer(int p_to_pos) {
+ for (KeyValue<Vector2i, TileAlternativesData> E_tile : tiles) {
+ for (KeyValue<int, TileData *> E_alternative : E_tile.value.alternatives) {
+ E_alternative.value->add_navigation_layer(p_to_pos);
+ }
+ }
+}
+
+void TileSetAtlasSource::move_navigation_layer(int p_from_index, int p_to_pos) {
+ for (KeyValue<Vector2i, TileAlternativesData> E_tile : tiles) {
+ for (KeyValue<int, TileData *> E_alternative : E_tile.value.alternatives) {
+ E_alternative.value->move_navigation_layer(p_from_index, p_to_pos);
+ }
+ }
+}
+
+void TileSetAtlasSource::remove_navigation_layer(int p_index) {
+ for (KeyValue<Vector2i, TileAlternativesData> E_tile : tiles) {
+ for (KeyValue<int, TileData *> E_alternative : E_tile.value.alternatives) {
+ E_alternative.value->remove_navigation_layer(p_index);
+ }
+ }
+}
+
+void TileSetAtlasSource::add_custom_data_layer(int p_to_pos) {
+ for (KeyValue<Vector2i, TileAlternativesData> E_tile : tiles) {
+ for (KeyValue<int, TileData *> E_alternative : E_tile.value.alternatives) {
+ E_alternative.value->add_custom_data_layer(p_to_pos);
+ }
+ }
+}
+
+void TileSetAtlasSource::move_custom_data_layer(int p_from_index, int p_to_pos) {
+ for (KeyValue<Vector2i, TileAlternativesData> E_tile : tiles) {
+ for (KeyValue<int, TileData *> E_alternative : E_tile.value.alternatives) {
+ E_alternative.value->move_custom_data_layer(p_from_index, p_to_pos);
+ }
+ }
+}
+
+void TileSetAtlasSource::remove_custom_data_layer(int p_index) {
+ for (KeyValue<Vector2i, TileAlternativesData> E_tile : tiles) {
+ for (KeyValue<int, TileData *> E_alternative : E_tile.value.alternatives) {
+ E_alternative.value->remove_custom_data_layer(p_index);
+ }
+ }
+}
+
void TileSetAtlasSource::reset_state() {
// Reset all TileData.
for (Map<Vector2i, TileAlternativesData>::Element *E_tile = tiles.front(); E_tile; E_tile = E_tile->next()) {
@@ -3273,32 +3561,24 @@ void TileSetAtlasSource::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", PROPERTY_USAGE_NOEDITOR), "set_texture", "get_texture");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "margins", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_margins", "get_margins");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "separation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_separation", "get_separation");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "tile_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_texture_region_size", "get_texture_region_size");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "texture_region_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_texture_region_size", "get_texture_region_size");
// Base tiles
ClassDB::bind_method(D_METHOD("create_tile", "atlas_coords", "size"), &TileSetAtlasSource::create_tile, DEFVAL(Vector2i(1, 1)));
ClassDB::bind_method(D_METHOD("remove_tile", "atlas_coords"), &TileSetAtlasSource::remove_tile); // Remove a tile. If p_tile_key.alternative_tile if different from 0, remove the alternative
- ClassDB::bind_method(D_METHOD("has_tile", "atlas_coords"), &TileSetAtlasSource::has_tile);
ClassDB::bind_method(D_METHOD("can_move_tile_in_atlas", "atlas_coords", "new_atlas_coords", "new_size"), &TileSetAtlasSource::can_move_tile_in_atlas, DEFVAL(INVALID_ATLAS_COORDS), DEFVAL(Vector2i(-1, -1)));
ClassDB::bind_method(D_METHOD("move_tile_in_atlas", "atlas_coords", "new_atlas_coords", "new_size"), &TileSetAtlasSource::move_tile_in_atlas, DEFVAL(INVALID_ATLAS_COORDS), DEFVAL(Vector2i(-1, -1)));
ClassDB::bind_method(D_METHOD("get_tile_size_in_atlas", "atlas_coords"), &TileSetAtlasSource::get_tile_size_in_atlas);
- ClassDB::bind_method(D_METHOD("get_tiles_count"), &TileSetAtlasSource::get_tiles_count);
- ClassDB::bind_method(D_METHOD("get_tile_id", "index"), &TileSetAtlasSource::get_tile_id);
-
ClassDB::bind_method(D_METHOD("get_tile_at_coords", "atlas_coords"), &TileSetAtlasSource::get_tile_at_coords);
// Alternative tiles
ClassDB::bind_method(D_METHOD("create_alternative_tile", "atlas_coords", "alternative_id_override"), &TileSetAtlasSource::create_alternative_tile, DEFVAL(INVALID_TILE_ALTERNATIVE));
ClassDB::bind_method(D_METHOD("remove_alternative_tile", "atlas_coords", "alternative_tile"), &TileSetAtlasSource::remove_alternative_tile);
ClassDB::bind_method(D_METHOD("set_alternative_tile_id", "atlas_coords", "alternative_tile", "new_id"), &TileSetAtlasSource::set_alternative_tile_id);
- ClassDB::bind_method(D_METHOD("has_alternative_tile", "atlas_coords", "alternative_tile"), &TileSetAtlasSource::has_alternative_tile);
ClassDB::bind_method(D_METHOD("get_next_alternative_tile_id", "atlas_coords"), &TileSetAtlasSource::get_next_alternative_tile_id);
- ClassDB::bind_method(D_METHOD("get_alternative_tiles_count", "atlas_coords"), &TileSetAtlasSource::get_alternative_tiles_count);
- ClassDB::bind_method(D_METHOD("get_alternative_tile_id", "atlas_coords", "index"), &TileSetAtlasSource::get_alternative_tile_id);
-
- ClassDB::bind_method(D_METHOD("get_tile_data", "atlas_coords", "index"), &TileSetAtlasSource::get_tile_data);
+ ClassDB::bind_method(D_METHOD("get_tile_data", "atlas_coords", "alternative_tile"), &TileSetAtlasSource::get_tile_data);
// Helpers.
ClassDB::bind_method(D_METHOD("get_atlas_grid_size"), &TileSetAtlasSource::get_atlas_grid_size);
@@ -3511,16 +3791,6 @@ void TileSetScenesCollectionSource::_get_property_list(List<PropertyInfo> *p_lis
}
void TileSetScenesCollectionSource::_bind_methods() {
- // Base tiles
- ClassDB::bind_method(D_METHOD("get_tiles_count"), &TileSetScenesCollectionSource::get_tiles_count);
- ClassDB::bind_method(D_METHOD("get_tile_id", "index"), &TileSetScenesCollectionSource::get_tile_id);
- ClassDB::bind_method(D_METHOD("has_tile", "atlas_coords"), &TileSetScenesCollectionSource::has_tile);
-
- // Alternative tiles
- ClassDB::bind_method(D_METHOD("get_alternative_tiles_count", "atlas_coords"), &TileSetScenesCollectionSource::get_alternative_tiles_count);
- ClassDB::bind_method(D_METHOD("get_alternative_tile_id", "atlas_coords", "index"), &TileSetScenesCollectionSource::get_alternative_tile_id);
- ClassDB::bind_method(D_METHOD("has_alternative_tile", "atlas_coords", "alternative_tile"), &TileSetScenesCollectionSource::has_alternative_tile);
-
ClassDB::bind_method(D_METHOD("get_scene_tiles_count"), &TileSetScenesCollectionSource::get_scene_tiles_count);
ClassDB::bind_method(D_METHOD("get_scene_tile_id", "index"), &TileSetScenesCollectionSource::get_scene_tile_id);
ClassDB::bind_method(D_METHOD("has_scene_tile_id", "id"), &TileSetScenesCollectionSource::has_scene_tile_id);
@@ -3575,6 +3845,155 @@ void TileData::notify_tile_data_properties_should_change() {
emit_signal(SNAME("changed"));
}
+void TileData::add_occlusion_layer(int p_to_pos) {
+ if (p_to_pos < 0) {
+ p_to_pos = occluders.size();
+ }
+ ERR_FAIL_INDEX(p_to_pos, occluders.size() + 1);
+ occluders.insert(p_to_pos, Ref<OccluderPolygon2D>());
+}
+
+void TileData::move_occlusion_layer(int p_from_index, int p_to_pos) {
+ ERR_FAIL_INDEX(p_from_index, occluders.size());
+ ERR_FAIL_INDEX(p_to_pos, occluders.size() + 1);
+ occluders.insert(p_to_pos, occluders[p_from_index]);
+ occluders.remove(p_to_pos < p_from_index ? p_from_index + 1 : p_from_index);
+}
+
+void TileData::remove_occlusion_layer(int p_index) {
+ ERR_FAIL_INDEX(p_index, occluders.size());
+ occluders.remove(p_index);
+}
+
+void TileData::add_physics_layer(int p_to_pos) {
+ if (p_to_pos < 0) {
+ p_to_pos = physics.size();
+ }
+ ERR_FAIL_INDEX(p_to_pos, physics.size() + 1);
+ physics.insert(p_to_pos, PhysicsLayerTileData());
+}
+
+void TileData::move_physics_layer(int p_from_index, int p_to_pos) {
+ ERR_FAIL_INDEX(p_from_index, physics.size());
+ ERR_FAIL_INDEX(p_to_pos, physics.size() + 1);
+ physics.insert(p_to_pos, physics[p_from_index]);
+ physics.remove(p_to_pos < p_from_index ? p_from_index + 1 : p_from_index);
+}
+
+void TileData::remove_physics_layer(int p_index) {
+ ERR_FAIL_INDEX(p_index, physics.size());
+ physics.remove(p_index);
+}
+
+void TileData::add_terrain_set(int p_to_pos) {
+ if (p_to_pos >= 0 && p_to_pos <= terrain_set) {
+ terrain_set += 1;
+ }
+}
+
+void TileData::move_terrain_set(int p_from_index, int p_to_pos) {
+ if (p_from_index == terrain_set) {
+ terrain_set = (p_from_index < p_to_pos) ? p_to_pos - 1 : p_to_pos;
+ } else {
+ if (p_from_index < terrain_set) {
+ terrain_set -= 1;
+ }
+ if (p_to_pos <= terrain_set) {
+ terrain_set += 1;
+ }
+ }
+}
+
+void TileData::remove_terrain_set(int p_index) {
+ if (p_index == terrain_set) {
+ terrain_set = -1;
+ for (int i = 0; i < 16; i++) {
+ terrain_peering_bits[i] = -1;
+ }
+ } else if (terrain_set > p_index) {
+ terrain_set -= 1;
+ }
+}
+
+void TileData::add_terrain(int p_terrain_set, int p_to_pos) {
+ if (terrain_set == p_terrain_set) {
+ for (int i = 0; i < 16; i++) {
+ if (p_to_pos >= 0 && p_to_pos <= terrain_peering_bits[i]) {
+ terrain_peering_bits[i] += 1;
+ }
+ }
+ }
+}
+
+void TileData::move_terrain(int p_terrain_set, int p_from_index, int p_to_pos) {
+ if (terrain_set == p_terrain_set) {
+ for (int i = 0; i < 16; i++) {
+ if (p_from_index == terrain_peering_bits[i]) {
+ terrain_peering_bits[i] = (p_from_index < p_to_pos) ? p_to_pos - 1 : p_to_pos;
+ } else {
+ if (p_from_index < terrain_peering_bits[i]) {
+ terrain_peering_bits[i] -= 1;
+ }
+ if (p_to_pos <= terrain_peering_bits[i]) {
+ terrain_peering_bits[i] += 1;
+ }
+ }
+ }
+ }
+}
+
+void TileData::remove_terrain(int p_terrain_set, int p_index) {
+ if (terrain_set == p_terrain_set) {
+ for (int i = 0; i < 16; i++) {
+ if (terrain_peering_bits[i] == p_index) {
+ terrain_peering_bits[i] = -1;
+ } else if (terrain_peering_bits[i] > p_index) {
+ terrain_peering_bits[i] -= 1;
+ }
+ }
+ }
+}
+
+void TileData::add_navigation_layer(int p_to_pos) {
+ if (p_to_pos < 0) {
+ p_to_pos = navigation.size();
+ }
+ ERR_FAIL_INDEX(p_to_pos, navigation.size() + 1);
+ navigation.insert(p_to_pos, Ref<NavigationPolygon>());
+}
+
+void TileData::move_navigation_layer(int p_from_index, int p_to_pos) {
+ ERR_FAIL_INDEX(p_from_index, navigation.size());
+ ERR_FAIL_INDEX(p_to_pos, navigation.size() + 1);
+ navigation.insert(p_to_pos, navigation[p_from_index]);
+ navigation.remove(p_to_pos < p_from_index ? p_from_index + 1 : p_from_index);
+}
+
+void TileData::remove_navigation_layer(int p_index) {
+ ERR_FAIL_INDEX(p_index, navigation.size());
+ navigation.remove(p_index);
+}
+
+void TileData::add_custom_data_layer(int p_to_pos) {
+ if (p_to_pos < 0) {
+ p_to_pos = custom_data.size();
+ }
+ ERR_FAIL_INDEX(p_to_pos, custom_data.size() + 1);
+ custom_data.insert(p_to_pos, Variant());
+}
+
+void TileData::move_custom_data_layer(int p_from_index, int p_to_pos) {
+ ERR_FAIL_INDEX(p_from_index, custom_data.size());
+ ERR_FAIL_INDEX(p_to_pos, custom_data.size() + 1);
+ custom_data.insert(p_to_pos, navigation[p_from_index]);
+ custom_data.remove(p_to_pos < p_from_index ? p_from_index + 1 : p_from_index);
+}
+
+void TileData::remove_custom_data_layer(int p_index) {
+ ERR_FAIL_INDEX(p_index, custom_data.size());
+ custom_data.remove(p_index);
+}
+
void TileData::reset_state() {
occluders.clear();
physics.clear();
@@ -3628,11 +4047,11 @@ Vector2i TileData::get_texture_offset() const {
return tex_offset;
}
-void TileData::tile_set_material(Ref<ShaderMaterial> p_material) {
+void TileData::set_material(Ref<ShaderMaterial> p_material) {
material = p_material;
emit_signal(SNAME("changed"));
}
-Ref<ShaderMaterial> TileData::tile_get_material() const {
+Ref<ShaderMaterial> TileData::get_material() const {
return material;
}
@@ -4148,8 +4567,8 @@ void TileData::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_flip_v"), &TileData::get_flip_v);
ClassDB::bind_method(D_METHOD("set_transpose", "transpose"), &TileData::set_transpose);
ClassDB::bind_method(D_METHOD("get_transpose"), &TileData::get_transpose);
- ClassDB::bind_method(D_METHOD("tile_set_material", "material"), &TileData::tile_set_material);
- ClassDB::bind_method(D_METHOD("tile_get_material"), &TileData::tile_get_material);
+ ClassDB::bind_method(D_METHOD("set_material", "material"), &TileData::set_material);
+ ClassDB::bind_method(D_METHOD("get_material"), &TileData::get_material);
ClassDB::bind_method(D_METHOD("set_texture_offset", "texture_offset"), &TileData::set_texture_offset);
ClassDB::bind_method(D_METHOD("get_texture_offset"), &TileData::get_texture_offset);
ClassDB::bind_method(D_METHOD("set_modulate", "modulate"), &TileData::set_modulate);
@@ -4200,6 +4619,7 @@ void TileData::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "transpose"), "set_transpose", "get_transpose");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "texture_offset"), "set_texture_offset", "get_texture_offset");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "modulate"), "set_modulate", "get_modulate");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial"), "set_material", "get_material");
ADD_PROPERTY(PropertyInfo(Variant::INT, "z_index"), "set_z_index", "get_z_index");
ADD_PROPERTY(PropertyInfo(Variant::INT, "y_sort_origin"), "set_y_sort_origin", "get_y_sort_origin");
diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h
index 35e6999d13..ba7207241a 100644
--- a/scene/resources/tile_set.h
+++ b/scene/resources/tile_set.h
@@ -225,10 +225,10 @@ private:
bool terrain_bits_meshes_dirty = true;
// Navigation
- struct Navigationlayer {
+ struct NavigationLayer {
uint32_t layers = 1;
};
- Vector<Navigationlayer> navigation_layers;
+ Vector<NavigationLayer> navigation_layers;
// CustomData
struct CustomDataLayer {
@@ -298,16 +298,20 @@ public:
void set_uv_clipping(bool p_uv_clipping);
bool is_uv_clipping() const;
- void set_occlusion_layers_count(int p_occlusion_layers_count);
int get_occlusion_layers_count() const;
+ void add_occlusion_layer(int p_index = -1);
+ void move_occlusion_layer(int p_from_index, int p_to_pos);
+ void remove_occlusion_layer(int p_index);
void set_occlusion_layer_light_mask(int p_layer_index, int p_light_mask);
int get_occlusion_layer_light_mask(int p_layer_index) const;
- void set_occlusion_layer_sdf_collision(int p_layer_index, int p_sdf_collision);
+ void set_occlusion_layer_sdf_collision(int p_layer_index, bool p_sdf_collision);
bool get_occlusion_layer_sdf_collision(int p_layer_index) const;
// Physics
- void set_physics_layers_count(int p_physics_layers_count);
int get_physics_layers_count() const;
+ void add_physics_layer(int p_index = -1);
+ void move_physics_layer(int p_from_index, int p_to_pos);
+ void remove_physics_layer(int p_index);
void set_physics_layer_collision_layer(int p_layer_index, uint32_t p_layer);
uint32_t get_physics_layer_collision_layer(int p_layer_index) const;
void set_physics_layer_collision_mask(int p_layer_index, uint32_t p_mask);
@@ -315,13 +319,19 @@ public:
void set_physics_layer_physics_material(int p_layer_index, Ref<PhysicsMaterial> p_physics_material);
Ref<PhysicsMaterial> get_physics_layer_physics_material(int p_layer_index) const;
- // Terrains
- void set_terrain_sets_count(int p_terrains_sets_count);
+ // Terrain sets
int get_terrain_sets_count() const;
+ void add_terrain_set(int p_index = -1);
+ void move_terrain_set(int p_from_index, int p_to_pos);
+ void remove_terrain_set(int p_index);
void set_terrain_set_mode(int p_terrain_set, TerrainMode p_terrain_mode);
TerrainMode get_terrain_set_mode(int p_terrain_set) const;
- void set_terrains_count(int p_terrain_set, int p_terrains_count);
+
+ // Terrains
int get_terrains_count(int p_terrain_set) const;
+ void add_terrain(int p_terrain_set, int p_index = -1);
+ void move_terrain(int p_terrain_set, int p_from_index, int p_to_pos);
+ void remove_terrain(int p_terrain_set, int p_index);
void set_terrain_name(int p_terrain_set, int p_terrain_index, String p_name);
String get_terrain_name(int p_terrain_set, int p_terrain_index) const;
void set_terrain_color(int p_terrain_set, int p_terrain_index, Color p_color);
@@ -330,14 +340,18 @@ public:
bool is_valid_peering_bit_terrain(int p_terrain_set, TileSet::CellNeighbor p_peering_bit) const;
// Navigation
- void set_navigation_layers_count(int p_navigation_layers_count);
int get_navigation_layers_count() const;
+ void add_navigation_layer(int p_index = -1);
+ void move_navigation_layer(int p_from_index, int p_to_pos);
+ void remove_navigation_layer(int p_index);
void set_navigation_layer_layers(int p_layer_index, uint32_t p_layers);
uint32_t get_navigation_layer_layers(int p_layer_index) const;
// Custom data
- void set_custom_data_layers_count(int p_custom_data_layers_count);
int get_custom_data_layers_count() const;
+ void add_custom_data_layer(int p_index = -1);
+ void move_custom_data_layer(int p_from_index, int p_to_pos);
+ void remove_custom_data_layer(int p_index);
int get_custom_data_layer_by_name(String p_value) const;
void set_custom_data_name(int p_layer_id, String p_value);
String get_custom_data_name(int p_layer_id) const;
@@ -371,7 +385,7 @@ public:
// Helpers
Vector<Vector2> get_tile_shape_polygon();
- void draw_tile_shape(CanvasItem *p_canvas_item, Rect2 p_region, Color p_color, bool p_filled = false, Ref<Texture2D> p_texture = Ref<Texture2D>());
+ void draw_tile_shape(CanvasItem *p_canvas_item, Transform2D p_transform, Color p_color, bool p_filled = false, Ref<Texture2D> p_texture = Ref<Texture2D>());
Vector<Point2> get_terrain_bit_polygon(int p_terrain_set, TileSet::CellNeighbor p_bit);
void draw_terrains(CanvasItem *p_canvas_item, Transform2D p_transform, const TileData *p_tile_data);
@@ -390,6 +404,8 @@ class TileSetSource : public Resource {
protected:
const TileSet *tile_set = nullptr;
+ static void _bind_methods();
+
public:
static const Vector2i INVALID_ATLAS_COORDS; // Vector2i(-1, -1);
static const int INVALID_TILE_ALTERNATIVE; // -1;
@@ -397,6 +413,24 @@ public:
// Not exposed.
virtual void set_tile_set(const TileSet *p_tile_set);
virtual void notify_tile_data_properties_should_change(){};
+ virtual void add_occlusion_layer(int p_index){};
+ virtual void move_occlusion_layer(int p_from_index, int p_to_pos){};
+ virtual void remove_occlusion_layer(int p_index){};
+ virtual void add_physics_layer(int p_index){};
+ virtual void move_physics_layer(int p_from_index, int p_to_pos){};
+ virtual void remove_physics_layer(int p_index){};
+ virtual void add_terrain_set(int p_index){};
+ virtual void move_terrain_set(int p_from_index, int p_to_pos){};
+ virtual void remove_terrain_set(int p_index){};
+ virtual void add_terrain(int p_terrain_set, int p_index){};
+ virtual void move_terrain(int p_terrain_set, int p_from_index, int p_to_pos){};
+ virtual void remove_terrain(int p_terrain_set, int p_index){};
+ virtual void add_navigation_layer(int p_index){};
+ virtual void move_navigation_layer(int p_from_index, int p_to_pos){};
+ virtual void remove_navigation_layer(int p_index){};
+ virtual void add_custom_data_layer(int p_index){};
+ virtual void move_custom_data_layer(int p_from_index, int p_to_pos){};
+ virtual void remove_custom_data_layer(int p_index){};
virtual void reset_state() override{};
// Tiles.
@@ -448,6 +482,24 @@ public:
// Not exposed.
virtual void set_tile_set(const TileSet *p_tile_set) override;
virtual void notify_tile_data_properties_should_change() override;
+ virtual void add_occlusion_layer(int p_index) override;
+ virtual void move_occlusion_layer(int p_from_index, int p_to_pos) override;
+ virtual void remove_occlusion_layer(int p_index) override;
+ virtual void add_physics_layer(int p_index) override;
+ virtual void move_physics_layer(int p_from_index, int p_to_pos) override;
+ virtual void remove_physics_layer(int p_index) override;
+ virtual void add_terrain_set(int p_index) override;
+ virtual void move_terrain_set(int p_from_index, int p_to_pos) override;
+ virtual void remove_terrain_set(int p_index) override;
+ virtual void add_terrain(int p_terrain_set, int p_index) override;
+ virtual void move_terrain(int p_terrain_set, int p_from_index, int p_to_pos) override;
+ virtual void remove_terrain(int p_terrain_set, int p_index) override;
+ virtual void add_navigation_layer(int p_index) override;
+ virtual void move_navigation_layer(int p_from_index, int p_to_pos) override;
+ virtual void remove_navigation_layer(int p_index) override;
+ virtual void add_custom_data_layer(int p_index) override;
+ virtual void move_custom_data_layer(int p_from_index, int p_to_pos) override;
+ virtual void remove_custom_data_layer(int p_index) override;
virtual void reset_state() override;
// Base properties.
@@ -528,7 +580,7 @@ public:
int get_alternative_tile_id(const Vector2i p_atlas_coords, int p_index) const override;
bool has_alternative_tile(const Vector2i p_atlas_coords, int p_alternative_tile) const override;
- // Scenes sccessors. Lot are similar to "Alternative tiles".
+ // Scenes accessors. Lot are similar to "Alternative tiles".
int get_scene_tiles_count() { return get_alternative_tiles_count(Vector2i()); }
int get_scene_tile_id(int p_index) { return get_alternative_tile_id(Vector2i(), p_index); };
bool has_scene_tile_id(int p_id) { return has_alternative_tile(Vector2i(), p_id); };
@@ -597,6 +649,24 @@ public:
// Not exposed.
void set_tile_set(const TileSet *p_tile_set);
void notify_tile_data_properties_should_change();
+ void add_occlusion_layer(int p_index);
+ void move_occlusion_layer(int p_from_index, int p_to_pos);
+ void remove_occlusion_layer(int p_index);
+ void add_physics_layer(int p_index);
+ void move_physics_layer(int p_from_index, int p_to_pos);
+ void remove_physics_layer(int p_index);
+ void add_terrain_set(int p_index);
+ void move_terrain_set(int p_from_index, int p_to_pos);
+ void remove_terrain_set(int p_index);
+ void add_terrain(int p_terrain_set, int p_index);
+ void move_terrain(int p_terrain_set, int p_from_index, int p_to_pos);
+ void remove_terrain(int p_terrain_set, int p_index);
+ void add_navigation_layer(int p_index);
+ void move_navigation_layer(int p_from_index, int p_to_pos);
+ void remove_navigation_layer(int p_index);
+ void add_custom_data_layer(int p_index);
+ void move_custom_data_layer(int p_from_index, int p_to_pos);
+ void remove_custom_data_layer(int p_index);
void reset_state();
void set_allow_transform(bool p_allow_transform);
bool is_allowing_transform() const;
@@ -611,8 +681,8 @@ public:
void set_texture_offset(Vector2i p_texture_offset);
Vector2i get_texture_offset() const;
- void tile_set_material(Ref<ShaderMaterial> p_material);
- Ref<ShaderMaterial> tile_get_material() const;
+ void set_material(Ref<ShaderMaterial> p_material);
+ Ref<ShaderMaterial> get_material() const;
void set_modulate(Color p_modulate);
Color get_modulate() const;
void set_z_index(int p_z_index);
diff --git a/scene/resources/world_margin_shape_2d.cpp b/scene/resources/world_boundary_shape_2d.cpp
index 3b43681528..39af92793f 100644
--- a/scene/resources/world_margin_shape_2d.cpp
+++ b/scene/resources/world_boundary_shape_2d.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* world_margin_shape_2d.cpp */
+/* world_boundary_shape_2d.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,13 +28,13 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "world_margin_shape_2d.h"
+#include "world_boundary_shape_2d.h"
#include "core/math/geometry_2d.h"
#include "servers/physics_server_2d.h"
#include "servers/rendering_server.h"
-bool WorldMarginShape2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
+bool WorldBoundaryShape2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
Vector2 point = get_distance() * get_normal();
Vector2 l[2][2] = { { point - get_normal().orthogonal() * 100, point + get_normal().orthogonal() * 100 }, { point, point + get_normal() * 30 } };
@@ -48,7 +48,7 @@ bool WorldMarginShape2D::_edit_is_selected_on_click(const Point2 &p_point, doubl
return false;
}
-void WorldMarginShape2D::_update_shape() {
+void WorldBoundaryShape2D::_update_shape() {
Array arr;
arr.push_back(normal);
arr.push_back(distance);
@@ -56,25 +56,25 @@ void WorldMarginShape2D::_update_shape() {
emit_changed();
}
-void WorldMarginShape2D::set_normal(const Vector2 &p_normal) {
+void WorldBoundaryShape2D::set_normal(const Vector2 &p_normal) {
normal = p_normal;
_update_shape();
}
-void WorldMarginShape2D::set_distance(real_t p_distance) {
+void WorldBoundaryShape2D::set_distance(real_t p_distance) {
distance = p_distance;
_update_shape();
}
-Vector2 WorldMarginShape2D::get_normal() const {
+Vector2 WorldBoundaryShape2D::get_normal() const {
return normal;
}
-real_t WorldMarginShape2D::get_distance() const {
+real_t WorldBoundaryShape2D::get_distance() const {
return distance;
}
-void WorldMarginShape2D::draw(const RID &p_to_rid, const Color &p_color) {
+void WorldBoundaryShape2D::draw(const RID &p_to_rid, const Color &p_color) {
Vector2 point = get_distance() * get_normal();
Vector2 l1[2] = { point - get_normal().orthogonal() * 100, point + get_normal().orthogonal() * 100 };
@@ -83,7 +83,7 @@ void WorldMarginShape2D::draw(const RID &p_to_rid, const Color &p_color) {
RS::get_singleton()->canvas_item_add_line(p_to_rid, l2[0], l2[1], p_color, 3);
}
-Rect2 WorldMarginShape2D::get_rect() const {
+Rect2 WorldBoundaryShape2D::get_rect() const {
Vector2 point = get_distance() * get_normal();
Vector2 l1[2] = { point - get_normal().orthogonal() * 100, point + get_normal().orthogonal() * 100 };
@@ -96,22 +96,22 @@ Rect2 WorldMarginShape2D::get_rect() const {
return rect;
}
-real_t WorldMarginShape2D::get_enclosing_radius() const {
+real_t WorldBoundaryShape2D::get_enclosing_radius() const {
return distance;
}
-void WorldMarginShape2D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_normal", "normal"), &WorldMarginShape2D::set_normal);
- ClassDB::bind_method(D_METHOD("get_normal"), &WorldMarginShape2D::get_normal);
+void WorldBoundaryShape2D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_normal", "normal"), &WorldBoundaryShape2D::set_normal);
+ ClassDB::bind_method(D_METHOD("get_normal"), &WorldBoundaryShape2D::get_normal);
- ClassDB::bind_method(D_METHOD("set_distance", "distance"), &WorldMarginShape2D::set_distance);
- ClassDB::bind_method(D_METHOD("get_distance"), &WorldMarginShape2D::get_distance);
+ ClassDB::bind_method(D_METHOD("set_distance", "distance"), &WorldBoundaryShape2D::set_distance);
+ ClassDB::bind_method(D_METHOD("get_distance"), &WorldBoundaryShape2D::get_distance);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "normal"), "set_normal", "get_normal");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "distance"), "set_distance", "get_distance");
}
-WorldMarginShape2D::WorldMarginShape2D() :
- Shape2D(PhysicsServer2D::get_singleton()->world_margin_shape_create()) {
+WorldBoundaryShape2D::WorldBoundaryShape2D() :
+ Shape2D(PhysicsServer2D::get_singleton()->world_boundary_shape_create()) {
_update_shape();
}
diff --git a/scene/resources/world_margin_shape_2d.h b/scene/resources/world_boundary_shape_2d.h
index 3c1d593ffe..4cc60f5985 100644
--- a/scene/resources/world_margin_shape_2d.h
+++ b/scene/resources/world_boundary_shape_2d.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* world_margin_shape_2d.h */
+/* world_boundary_shape_2d.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,15 +28,15 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef WORLD_MARGIN_SHAPE_2D_H
-#define WORLD_MARGIN_SHAPE_2D_H
+#ifndef WORLD_BOUNDARY_SHAPE_2D_H
+#define WORLD_BOUNDARY_SHAPE_2D_H
#include "scene/resources/shape_2d.h"
-class WorldMarginShape2D : public Shape2D {
- GDCLASS(WorldMarginShape2D, Shape2D);
+class WorldBoundaryShape2D : public Shape2D {
+ GDCLASS(WorldBoundaryShape2D, Shape2D);
- // WorldMarginShape2D is often used for one-way platforms, where the normal pointing up makes sense.
+ // WorldBoundaryShape2D is often used for one-way platforms, where the normal pointing up makes sense.
Vector2 normal = Vector2(0, -1);
real_t distance = 0.0;
@@ -58,7 +58,7 @@ public:
virtual Rect2 get_rect() const override;
virtual real_t get_enclosing_radius() const override;
- WorldMarginShape2D();
+ WorldBoundaryShape2D();
};
-#endif // WORLD_MARGIN_SHAPE_2D_H
+#endif // WORLD_BOUNDARY_SHAPE_2D_H
diff --git a/scene/resources/world_margin_shape_3d.cpp b/scene/resources/world_boundary_shape_3d.cpp
index 28d50e1921..8cde537164 100644
--- a/scene/resources/world_margin_shape_3d.cpp
+++ b/scene/resources/world_boundary_shape_3d.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* world_margin_shape_3d.cpp */
+/* world_boundary_shape_3d.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,11 +28,11 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "world_margin_shape_3d.h"
+#include "world_boundary_shape_3d.h"
#include "servers/physics_server_3d.h"
-Vector<Vector3> WorldMarginShape3D::get_debug_mesh_lines() const {
+Vector<Vector3> WorldBoundaryShape3D::get_debug_mesh_lines() const {
Plane p = get_plane();
Vector<Vector3> points;
@@ -60,29 +60,29 @@ Vector<Vector3> WorldMarginShape3D::get_debug_mesh_lines() const {
return points;
}
-void WorldMarginShape3D::_update_shape() {
+void WorldBoundaryShape3D::_update_shape() {
PhysicsServer3D::get_singleton()->shape_set_data(get_shape(), plane);
Shape3D::_update_shape();
}
-void WorldMarginShape3D::set_plane(Plane p_plane) {
+void WorldBoundaryShape3D::set_plane(const Plane &p_plane) {
plane = p_plane;
_update_shape();
notify_change_to_owners();
}
-Plane WorldMarginShape3D::get_plane() const {
+const Plane &WorldBoundaryShape3D::get_plane() const {
return plane;
}
-void WorldMarginShape3D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_plane", "plane"), &WorldMarginShape3D::set_plane);
- ClassDB::bind_method(D_METHOD("get_plane"), &WorldMarginShape3D::get_plane);
+void WorldBoundaryShape3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_plane", "plane"), &WorldBoundaryShape3D::set_plane);
+ ClassDB::bind_method(D_METHOD("get_plane"), &WorldBoundaryShape3D::get_plane);
ADD_PROPERTY(PropertyInfo(Variant::PLANE, "plane"), "set_plane", "get_plane");
}
-WorldMarginShape3D::WorldMarginShape3D() :
- Shape3D(PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_PLANE)) {
+WorldBoundaryShape3D::WorldBoundaryShape3D() :
+ Shape3D(PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_WORLD_BOUNDARY)) {
set_plane(Plane(0, 1, 0, 0));
}
diff --git a/scene/resources/world_margin_shape_3d.h b/scene/resources/world_boundary_shape_3d.h
index 00417c4408..853f555ebc 100644
--- a/scene/resources/world_margin_shape_3d.h
+++ b/scene/resources/world_boundary_shape_3d.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* world_margin_shape_3d.h */
+/* world_boundary_shape_3d.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,13 +28,13 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef WORLD_MARGIN_SHAPE_3D_H
-#define WORLD_MARGIN_SHAPE_3D_H
+#ifndef WORLD_BOUNDARY_SHAPE_3D_H
+#define WORLD_BOUNDARY_SHAPE_3D_H
#include "scene/resources/shape_3d.h"
-class WorldMarginShape3D : public Shape3D {
- GDCLASS(WorldMarginShape3D, Shape3D);
+class WorldBoundaryShape3D : public Shape3D {
+ GDCLASS(WorldBoundaryShape3D, Shape3D);
Plane plane;
protected:
@@ -42,8 +42,8 @@ protected:
virtual void _update_shape() override;
public:
- void set_plane(Plane p_plane);
- Plane get_plane() const;
+ void set_plane(const Plane &p_plane);
+ const Plane &get_plane() const;
virtual Vector<Vector3> get_debug_mesh_lines() const override;
virtual real_t get_enclosing_radius() const override {
@@ -51,6 +51,6 @@ public:
return 0;
}
- WorldMarginShape3D();
+ WorldBoundaryShape3D();
};
-#endif // WORLD_MARGIN_SHAPE_H
+#endif // WORLD_BOUNDARY_SHAPE_H