summaryrefslogtreecommitdiff
path: root/scene/resources
diff options
context:
space:
mode:
Diffstat (limited to 'scene/resources')
-rw-r--r--scene/resources/packed_scene.cpp16
-rw-r--r--scene/resources/primitive_meshes.cpp8
-rw-r--r--scene/resources/primitive_meshes.h2
-rw-r--r--scene/resources/skeleton_modification_2d.cpp42
-rw-r--r--scene/resources/skeleton_modification_2d_fabrik.cpp4
-rw-r--r--scene/resources/skeleton_modification_2d_twoboneik.cpp2
-rw-r--r--scene/resources/skeleton_modification_3d.cpp40
-rw-r--r--scene/resources/skeleton_modification_3d_fabrik.cpp4
-rw-r--r--scene/resources/surface_tool.cpp1
-rw-r--r--scene/resources/texture.cpp8
-rw-r--r--scene/resources/texture.h2
-rw-r--r--scene/resources/tile_set.cpp106
-rw-r--r--scene/resources/tile_set.h8
13 files changed, 151 insertions, 92 deletions
diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp
index 59faa50114..9722570060 100644
--- a/scene/resources/packed_scene.cpp
+++ b/scene/resources/packed_scene.cpp
@@ -384,7 +384,7 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map
// save the child instantiated scenes that are chosen as editable, so they can be restored
// upon load back
- if (p_node != p_owner && p_node->get_filename() != String() && p_owner->is_editable_instance(p_node)) {
+ if (p_node != p_owner && p_node->get_scene_file_path() != String() && p_owner->is_editable_instance(p_node)) {
editable_instances.push_back(p_owner->get_path_to(p_node));
// Node is the root of an editable instance.
is_editable_instance = true;
@@ -437,14 +437,14 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map
}
}
- if (p_node->get_filename() != String() && p_node->get_owner() == p_owner && instantiated_by_owner) {
+ if (p_node->get_scene_file_path() != String() && p_node->get_owner() == p_owner && instantiated_by_owner) {
if (p_node->get_scene_instance_load_placeholder()) {
//it's a placeholder, use the placeholder path
- nd.instance = _vm_get_variant(p_node->get_filename(), variant_map);
+ nd.instance = _vm_get_variant(p_node->get_scene_file_path(), variant_map);
nd.instance |= FLAG_INSTANCE_IS_PLACEHOLDER;
} else {
//must instance ourselves
- Ref<PackedScene> instance = ResourceLoader::load(p_node->get_filename());
+ Ref<PackedScene> instance = ResourceLoader::load(p_node->get_scene_file_path());
if (!instance.is_valid()) {
return ERR_CANT_OPEN;
}
@@ -454,7 +454,7 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map
}
n = nullptr;
} else {
- if (n->get_filename() != String()) {
+ if (n->get_scene_file_path() != String()) {
//is an instance
Ref<SceneState> state = n->get_scene_instance_state();
if (state.is_valid()) {
@@ -714,7 +714,7 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName
ERR_CONTINUE(!common_parent);
- if (common_parent != p_owner && common_parent->get_filename() == String()) {
+ if (common_parent != p_owner && common_parent->get_scene_file_path() == String()) {
common_parent = common_parent->get_owner();
}
@@ -774,7 +774,7 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName
nl = nullptr;
} else {
- if (nl->get_filename() != String()) {
+ if (nl->get_scene_file_path() != String()) {
//is an instance
Ref<SceneState> state = nl->get_scene_instance_state();
if (state.is_valid()) {
@@ -1652,7 +1652,7 @@ Node *PackedScene::instantiate(GenEditState p_edit_state) const {
}
if (get_path() != "" && get_path().find("::") == -1) {
- s->set_filename(get_path());
+ s->set_scene_file_path(get_path());
}
s->notification(Node::NOTIFICATION_INSTANCED);
diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp
index e7da41db9d..f8be00f5fb 100644
--- a/scene/resources/primitive_meshes.cpp
+++ b/scene/resources/primitive_meshes.cpp
@@ -1390,6 +1390,12 @@ void QuadMesh::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "center_offset"), "set_center_offset", "get_center_offset");
}
+uint32_t QuadMesh::surface_get_format(int p_idx) const {
+ ERR_FAIL_INDEX_V(p_idx, 1, 0);
+
+ return RS::ARRAY_FORMAT_VERTEX | RS::ARRAY_FORMAT_NORMAL | RS::ARRAY_FORMAT_TANGENT | RS::ARRAY_FORMAT_TEX_UV;
+}
+
QuadMesh::QuadMesh() {
primitive_type = PRIMITIVE_TRIANGLES;
}
@@ -1460,7 +1466,7 @@ void SphereMesh::_create_mesh_array(Array &p_arr) const {
} else {
Vector3 p = Vector3(x * radius * w, y, z * radius * w);
points.push_back(p);
- Vector3 normal = Vector3(x * radius * w * scale, y / scale, z * radius * w * scale);
+ Vector3 normal = Vector3(x * w * scale, radius * (y / scale), z * w * scale);
normals.push_back(normal.normalized());
};
ADD_TANGENT(z, 0.0, -x, 1.0)
diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h
index 7915cb0028..d447dad97a 100644
--- a/scene/resources/primitive_meshes.h
+++ b/scene/resources/primitive_meshes.h
@@ -285,6 +285,8 @@ protected:
virtual void _create_mesh_array(Array &p_arr) const override;
public:
+ virtual uint32_t surface_get_format(int p_idx) const override;
+
QuadMesh();
void set_size(const Size2 &p_size);
diff --git a/scene/resources/skeleton_modification_2d.cpp b/scene/resources/skeleton_modification_2d.cpp
index e533fb054a..7ac40b497d 100644
--- a/scene/resources/skeleton_modification_2d.cpp
+++ b/scene/resources/skeleton_modification_2d.cpp
@@ -96,37 +96,25 @@ float SkeletonModification2D::clamp_angle(float p_angle, float p_min_bound, floa
p_max_bound = Math_TAU + p_max_bound;
}
if (p_min_bound > p_max_bound) {
- float tmp = p_min_bound;
- p_min_bound = p_max_bound;
- p_max_bound = tmp;
+ SWAP(p_min_bound, p_max_bound);
}
+ bool is_beyond_bounds = (p_angle < p_min_bound || p_angle > p_max_bound);
+ bool is_within_bounds = (p_angle > p_min_bound && p_angle < p_max_bound);
+
// Note: May not be the most optimal way to clamp, but it always constraints to the nearest angle.
- if (p_invert == false) {
- if (p_angle < p_min_bound || p_angle > p_max_bound) {
- Vector2 min_bound_vec = Vector2(Math::cos(p_min_bound), Math::sin(p_min_bound));
- Vector2 max_bound_vec = Vector2(Math::cos(p_max_bound), Math::sin(p_max_bound));
- Vector2 angle_vec = Vector2(Math::cos(p_angle), Math::sin(p_angle));
-
- if (angle_vec.distance_squared_to(min_bound_vec) <= angle_vec.distance_squared_to(max_bound_vec)) {
- p_angle = p_min_bound;
- } else {
- p_angle = p_max_bound;
- }
- }
- } else {
- if (p_angle > p_min_bound && p_angle < p_max_bound) {
- Vector2 min_bound_vec = Vector2(Math::cos(p_min_bound), Math::sin(p_min_bound));
- Vector2 max_bound_vec = Vector2(Math::cos(p_max_bound), Math::sin(p_max_bound));
- Vector2 angle_vec = Vector2(Math::cos(p_angle), Math::sin(p_angle));
+ if ((!p_invert && is_beyond_bounds) || (p_invert && is_within_bounds)) {
+ Vector2 min_bound_vec = Vector2(Math::cos(p_min_bound), Math::sin(p_min_bound));
+ Vector2 max_bound_vec = Vector2(Math::cos(p_max_bound), Math::sin(p_max_bound));
+ Vector2 angle_vec = Vector2(Math::cos(p_angle), Math::sin(p_angle));
- if (angle_vec.distance_squared_to(min_bound_vec) <= angle_vec.distance_squared_to(max_bound_vec)) {
- p_angle = p_min_bound;
- } else {
- p_angle = p_max_bound;
- }
+ if (angle_vec.distance_squared_to(min_bound_vec) <= angle_vec.distance_squared_to(max_bound_vec)) {
+ p_angle = p_min_bound;
+ } else {
+ p_angle = p_max_bound;
}
}
+
return p_angle;
}
@@ -152,9 +140,7 @@ void SkeletonModification2D::editor_draw_angle_constraints(Bone2D *p_operation_b
arc_angle_max = (Math_PI * 2) + arc_angle_max;
}
if (arc_angle_min > arc_angle_max) {
- float tmp = arc_angle_min;
- arc_angle_min = arc_angle_max;
- arc_angle_max = tmp;
+ SWAP(arc_angle_min, arc_angle_max);
}
arc_angle_min += p_operation_bone->get_bone_angle();
arc_angle_max += p_operation_bone->get_bone_angle();
diff --git a/scene/resources/skeleton_modification_2d_fabrik.cpp b/scene/resources/skeleton_modification_2d_fabrik.cpp
index 6e9429034f..3b5c555f89 100644
--- a/scene/resources/skeleton_modification_2d_fabrik.cpp
+++ b/scene/resources/skeleton_modification_2d_fabrik.cpp
@@ -247,7 +247,7 @@ void SkeletonModification2DFABRIK::chain_backwards() {
}
float current_bone2d_node_length = current_bone2d_node->get_length() * MIN(current_bone2d_node->get_global_scale().x, current_bone2d_node->get_global_scale().y);
- float length = current_bone2d_node_length / (previous_pose.get_origin() - current_pose.get_origin()).length();
+ float length = current_bone2d_node_length / (current_pose.get_origin().distance_to(previous_pose.get_origin()));
Vector2 finish_position = previous_pose.get_origin().lerp(current_pose.get_origin(), length);
current_pose.set_origin(finish_position);
@@ -268,7 +268,7 @@ void SkeletonModification2DFABRIK::chain_forwards() {
Transform2D next_pose = fabrik_transform_chain[i + 1];
float current_bone2d_node_length = current_bone2d_node->get_length() * MIN(current_bone2d_node->get_global_scale().x, current_bone2d_node->get_global_scale().y);
- float length = current_bone2d_node_length / (current_pose.get_origin() - next_pose.get_origin()).length();
+ float length = current_bone2d_node_length / (next_pose.get_origin().distance_to(current_pose.get_origin()));
Vector2 finish_position = current_pose.get_origin().lerp(next_pose.get_origin(), length);
current_pose.set_origin(finish_position);
diff --git a/scene/resources/skeleton_modification_2d_twoboneik.cpp b/scene/resources/skeleton_modification_2d_twoboneik.cpp
index 88d80a501f..4f752896a9 100644
--- a/scene/resources/skeleton_modification_2d_twoboneik.cpp
+++ b/scene/resources/skeleton_modification_2d_twoboneik.cpp
@@ -144,7 +144,7 @@ void SkeletonModification2DTwoBoneIK::_execute(float p_delta) {
// With modifications by TwistedTwigleg
Vector2 target_difference = target->get_global_position() - joint_one_bone->get_global_position();
float joint_one_to_target = target_difference.length();
- float angle_atan = Math::atan2(target_difference.y, target_difference.x);
+ float angle_atan = target_difference.angle();
float bone_one_length = joint_one_bone->get_length() * MIN(joint_one_bone->get_global_scale().x, joint_one_bone->get_global_scale().y);
float bone_two_length = joint_two_bone->get_length() * MIN(joint_two_bone->get_global_scale().x, joint_two_bone->get_global_scale().y);
diff --git a/scene/resources/skeleton_modification_3d.cpp b/scene/resources/skeleton_modification_3d.cpp
index ee02ede2d5..b476952d86 100644
--- a/scene/resources/skeleton_modification_3d.cpp
+++ b/scene/resources/skeleton_modification_3d.cpp
@@ -72,37 +72,25 @@ real_t SkeletonModification3D::clamp_angle(real_t p_angle, real_t p_min_bound, r
p_max_bound = Math_TAU + p_max_bound;
}
if (p_min_bound > p_max_bound) {
- real_t tmp = p_min_bound;
- p_min_bound = p_max_bound;
- p_max_bound = tmp;
+ SWAP(p_min_bound, p_max_bound);
}
+ bool is_beyond_bounds = (p_angle < p_min_bound || p_angle > p_max_bound);
+ bool is_within_bounds = (p_angle > p_min_bound && p_angle < p_max_bound);
+
// Note: May not be the most optimal way to clamp, but it always constraints to the nearest angle.
- if (p_invert == false) {
- if (p_angle < p_min_bound || p_angle > p_max_bound) {
- Vector2 min_bound_vec = Vector2(Math::cos(p_min_bound), Math::sin(p_min_bound));
- Vector2 max_bound_vec = Vector2(Math::cos(p_max_bound), Math::sin(p_max_bound));
- Vector2 angle_vec = Vector2(Math::cos(p_angle), Math::sin(p_angle));
-
- if (angle_vec.distance_squared_to(min_bound_vec) <= angle_vec.distance_squared_to(max_bound_vec)) {
- p_angle = p_min_bound;
- } else {
- p_angle = p_max_bound;
- }
- }
- } else {
- if (p_angle > p_min_bound && p_angle < p_max_bound) {
- Vector2 min_bound_vec = Vector2(Math::cos(p_min_bound), Math::sin(p_min_bound));
- Vector2 max_bound_vec = Vector2(Math::cos(p_max_bound), Math::sin(p_max_bound));
- Vector2 angle_vec = Vector2(Math::cos(p_angle), Math::sin(p_angle));
-
- if (angle_vec.distance_squared_to(min_bound_vec) <= angle_vec.distance_squared_to(max_bound_vec)) {
- p_angle = p_min_bound;
- } else {
- p_angle = p_max_bound;
- }
+ if ((!p_invert && is_beyond_bounds) || (p_invert && is_within_bounds)) {
+ Vector2 min_bound_vec = Vector2(Math::cos(p_min_bound), Math::sin(p_min_bound));
+ Vector2 max_bound_vec = Vector2(Math::cos(p_max_bound), Math::sin(p_max_bound));
+ Vector2 angle_vec = Vector2(Math::cos(p_angle), Math::sin(p_angle));
+
+ if (angle_vec.distance_squared_to(min_bound_vec) <= angle_vec.distance_squared_to(max_bound_vec)) {
+ p_angle = p_min_bound;
+ } else {
+ p_angle = p_max_bound;
}
}
+
return p_angle;
}
diff --git a/scene/resources/skeleton_modification_3d_fabrik.cpp b/scene/resources/skeleton_modification_3d_fabrik.cpp
index 69f75eb7b5..e615615924 100644
--- a/scene/resources/skeleton_modification_3d_fabrik.cpp
+++ b/scene/resources/skeleton_modification_3d_fabrik.cpp
@@ -232,7 +232,7 @@ void SkeletonModification3DFABRIK::chain_backwards() {
int current_bone_idx = fabrik_data_chain[i].bone_idx;
Transform3D current_trans = stack->skeleton->local_pose_to_global_pose(current_bone_idx, stack->skeleton->get_bone_local_pose_override(current_bone_idx));
- real_t length = fabrik_data_chain[i].length / (next_bone_trans.origin - current_trans.origin).length();
+ real_t length = fabrik_data_chain[i].length / (current_trans.origin.distance_to(next_bone_trans.origin));
current_trans.origin = next_bone_trans.origin.lerp(current_trans.origin, length);
// Apply it back to the skeleton
@@ -253,7 +253,7 @@ void SkeletonModification3DFABRIK::chain_forwards() {
int next_bone_idx = fabrik_data_chain[i + 1].bone_idx;
Transform3D next_bone_trans = stack->skeleton->local_pose_to_global_pose(next_bone_idx, stack->skeleton->get_bone_local_pose_override(next_bone_idx));
- real_t length = fabrik_data_chain[i].length / (current_trans.origin - next_bone_trans.origin).length();
+ real_t length = fabrik_data_chain[i].length / (next_bone_trans.origin.distance_to(current_trans.origin));
next_bone_trans.origin = current_trans.origin.lerp(next_bone_trans.origin, length);
// Apply it back to the skeleton
diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp
index d5e370568d..a8cd872408 100644
--- a/scene/resources/surface_tool.cpp
+++ b/scene/resources/surface_tool.cpp
@@ -1176,6 +1176,7 @@ Vector<int> SurfaceTool::generate_lod(float p_threshold, int p_target_index_coun
ERR_FAIL_COND_V(simplify_func == nullptr, lod);
ERR_FAIL_COND_V(vertex_array.size() == 0, lod);
ERR_FAIL_COND_V(index_array.size() == 0, lod);
+ ERR_FAIL_COND_V(index_array.size() % 3 != 0, lod);
lod.resize(index_array.size());
LocalVector<float> vertices; //uses floats
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 3dc32632cc..1b3a7a5f2a 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -1248,6 +1248,14 @@ bool AtlasTexture::is_pixel_opaque(int p_x, int p_y) const {
return atlas->is_pixel_opaque(x, y);
}
+Ref<Image> AtlasTexture::get_image() const {
+ if (!atlas.is_valid() || !atlas->get_image().is_valid()) {
+ return Ref<Image>();
+ }
+
+ return atlas->get_image()->get_rect(region);
+}
+
AtlasTexture::AtlasTexture() {}
/////////////////////////////////////////
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index 93f4e2de5a..862b9a47a6 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -250,6 +250,8 @@ public:
bool is_pixel_opaque(int p_x, int p_y) const override;
+ virtual Ref<Image> get_image() const override;
+
AtlasTexture();
};
diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp
index 67cbd0e094..15e622c9d6 100644
--- a/scene/resources/tile_set.cpp
+++ b/scene/resources/tile_set.cpp
@@ -1019,20 +1019,25 @@ Vector<Vector2> TileSet::get_tile_shape_polygon() {
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();
+ Vector<Vector2> shape = get_tile_shape_polygon();
+ Vector<Vector2> uvs;
+ uvs.resize(shape.size());
+ for (int i = 0; i < shape.size(); i++) {
+ uvs.write[i] = shape[i] + Vector2(0.5, 0.5);
+ }
Vector<Color> colors;
- colors.resize(uvs.size());
+ colors.resize(shape.size());
colors.fill(Color(1.0, 1.0, 1.0, 1.0));
// Filled mesh.
tile_filled_mesh->clear_surfaces();
Array a;
a.resize(Mesh::ARRAY_MAX);
- a[Mesh::ARRAY_VERTEX] = uvs;
+ a[Mesh::ARRAY_VERTEX] = shape;
a[Mesh::ARRAY_TEX_UV] = uvs;
a[Mesh::ARRAY_COLOR] = colors;
- a[Mesh::ARRAY_INDEX] = Geometry2D::triangulate_polygon(uvs);
+ a[Mesh::ARRAY_INDEX] = Geometry2D::triangulate_polygon(shape);
tile_filled_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, a, Array(), Dictionary(), Mesh::ARRAY_FLAG_USE_2D_VERTICES);
// Lines mesh.
@@ -1040,9 +1045,9 @@ void TileSet::draw_tile_shape(CanvasItem *p_canvas_item, Transform2D p_transform
a.clear();
a.resize(Mesh::ARRAY_MAX);
// Add the first point again when drawing lines.
- uvs.push_back(uvs[0]);
+ shape.push_back(shape[0]);
colors.push_back(colors[0]);
- a[Mesh::ARRAY_VERTEX] = uvs;
+ a[Mesh::ARRAY_VERTEX] = shape;
a[Mesh::ARRAY_COLOR] = colors;
tile_lines_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINE_STRIP, a, Array(), Dictionary(), Mesh::ARRAY_FLAG_USE_2D_VERTICES);
@@ -3119,7 +3124,7 @@ Vector2i TileSetAtlasSource::get_atlas_grid_size() const {
}
bool TileSetAtlasSource::_set(const StringName &p_name, const Variant &p_value) {
- Vector<String> components = String(p_name).split("/", true, 3);
+ Vector<String> components = String(p_name).split("/", true, 2);
// Compute the vector2i if we have coordinates.
Vector<String> coords_split = components[0].split(":");
@@ -3520,6 +3525,13 @@ Vector2i TileSetAtlasSource::get_tile_id(int p_index) const {
}
bool TileSetAtlasSource::has_room_for_tile(Vector2i p_atlas_coords, Vector2i p_size, int p_animation_columns, Vector2i p_animation_separation, int p_frames_count, Vector2i p_ignored_tile) const {
+ if (p_atlas_coords.x < 0 || p_atlas_coords.y < 0) {
+ return false;
+ }
+ if (p_size.x <= 0 || p_size.y <= 0) {
+ return false;
+ }
+ Size2i atlas_grid_size = get_atlas_grid_size();
for (int frame = 0; frame < p_frames_count; frame++) {
Vector2i frame_coords = p_atlas_coords + (p_size + p_animation_separation) * ((p_animation_columns > 0) ? Vector2i(frame % p_animation_columns, frame / p_animation_columns) : Vector2i(frame, 0));
for (int x = 0; x < p_size.x; x++) {
@@ -3528,6 +3540,11 @@ bool TileSetAtlasSource::has_room_for_tile(Vector2i p_atlas_coords, Vector2i p_s
if (_coords_mapping_cache.has(coords) && _coords_mapping_cache[coords] != p_ignored_tile) {
return false;
}
+ if (coords.x >= atlas_grid_size.x || coords.y >= atlas_grid_size.y) {
+ if (!(_coords_mapping_cache.has(coords) && _coords_mapping_cache[coords] == p_ignored_tile)) {
+ return false; // Only accept tiles outside the atlas if they are part of the ignored tile.
+ }
+ }
}
}
}
@@ -3558,8 +3575,7 @@ Vector2i TileSetAtlasSource::get_tile_effective_texture_offset(Vector2i p_atlas_
margin = Vector2i(MAX(0, margin.x), MAX(0, margin.y));
Vector2i effective_texture_offset = Object::cast_to<TileData>(get_tile_data(p_atlas_coords, p_alternative_tile))->get_texture_offset();
if (ABS(effective_texture_offset.x) > margin.x || ABS(effective_texture_offset.y) > margin.y) {
- effective_texture_offset.x = CLAMP(effective_texture_offset.x, -margin.x, margin.x);
- effective_texture_offset.y = CLAMP(effective_texture_offset.y, -margin.y, margin.y);
+ effective_texture_offset = effective_texture_offset.clamp(-margin, margin);
}
return effective_texture_offset;
@@ -4300,9 +4316,26 @@ Ref<OccluderPolygon2D> TileData::get_occluder(int p_layer_id) const {
}
// Physics
-int TileData::get_collision_polygons_count(int p_layer_id) const {
- ERR_FAIL_INDEX_V(p_layer_id, physics.size(), 0);
- return physics[p_layer_id].polygons.size();
+void TileData::set_constant_linear_velocity(int p_layer_id, const Vector2 &p_velocity) {
+ ERR_FAIL_INDEX(p_layer_id, physics.size());
+ physics.write[p_layer_id].linear_velocity = p_velocity;
+ emit_signal(SNAME("changed"));
+}
+
+Vector2 TileData::get_constant_linear_velocity(int p_layer_id) const {
+ ERR_FAIL_INDEX_V(p_layer_id, physics.size(), Vector2());
+ return physics[p_layer_id].linear_velocity;
+}
+
+void TileData::set_constant_angular_velocity(int p_layer_id, real_t p_velocity) {
+ ERR_FAIL_INDEX(p_layer_id, physics.size());
+ physics.write[p_layer_id].angular_velocity = p_velocity;
+ emit_signal(SNAME("changed"));
+}
+
+real_t TileData::get_constant_angular_velocity(int p_layer_id) const {
+ ERR_FAIL_INDEX_V(p_layer_id, physics.size(), 0.0);
+ return physics[p_layer_id].angular_velocity;
}
void TileData::set_collision_polygons_count(int p_layer_id, int p_polygons_count) {
@@ -4313,6 +4346,11 @@ void TileData::set_collision_polygons_count(int p_layer_id, int p_polygons_count
emit_signal(SNAME("changed"));
}
+int TileData::get_collision_polygons_count(int p_layer_id) const {
+ ERR_FAIL_INDEX_V(p_layer_id, physics.size(), 0);
+ return physics[p_layer_id].polygons.size();
+}
+
void TileData::add_collision_polygon(int p_layer_id) {
ERR_FAIL_INDEX(p_layer_id, physics.size());
physics.write[p_layer_id].polygons.push_back(PhysicsLayerTileData::PolygonShapeTileData());
@@ -4514,11 +4552,7 @@ bool TileData::_set(const StringName &p_name, const Variant &p_value) {
// Physics layers.
int layer_index = components[0].trim_prefix("physics_layer_").to_int();
ERR_FAIL_COND_V(layer_index < 0, false);
- if (components.size() == 2 && components[1] == "polygons_count") {
- if (p_value.get_type() != Variant::INT) {
- return false;
- }
-
+ if (components.size() == 2) {
if (layer_index >= physics.size()) {
if (tile_set) {
return false;
@@ -4526,8 +4560,19 @@ bool TileData::_set(const StringName &p_name, const Variant &p_value) {
physics.resize(layer_index + 1);
}
}
- set_collision_polygons_count(layer_index, p_value);
- return true;
+ if (components[1] == "linear_velocity") {
+ set_constant_linear_velocity(layer_index, p_value);
+ return true;
+ } else if (components[1] == "angular_velocity") {
+ set_constant_angular_velocity(layer_index, p_value);
+ return true;
+ } else if (components[1] == "polygons_count") {
+ if (p_value.get_type() != Variant::INT) {
+ return false;
+ }
+ set_collision_polygons_count(layer_index, p_value);
+ return true;
+ }
} else if (components.size() == 3 && components[1].begins_with("polygon_") && components[1].trim_prefix("polygon_").is_valid_int()) {
int polygon_index = components[1].trim_prefix("polygon_").to_int();
ERR_FAIL_COND_V(polygon_index < 0, false);
@@ -4629,9 +4674,18 @@ bool TileData::_get(const StringName &p_name, Variant &r_ret) const {
if (layer_index >= physics.size()) {
return false;
}
- if (components.size() == 2 && components[1] == "polygons_count") {
- r_ret = get_collision_polygons_count(layer_index);
- return true;
+
+ if (components.size() == 2) {
+ if (components[1] == "linear_velocity") {
+ r_ret = get_constant_linear_velocity(layer_index);
+ return true;
+ } else if (components[1] == "angular_velocity") {
+ r_ret = get_constant_angular_velocity(layer_index);
+ return true;
+ } else if (components[1] == "polygons_count") {
+ r_ret = get_collision_polygons_count(layer_index);
+ return true;
+ }
} else if (components.size() == 3 && components[1].begins_with("polygon_") && components[1].trim_prefix("polygon_").is_valid_int()) {
int polygon_index = components[1].trim_prefix("polygon_").to_int();
ERR_FAIL_COND_V(polygon_index < 0, false);
@@ -4702,6 +4756,8 @@ void TileData::_get_property_list(List<PropertyInfo> *p_list) const {
// Physics layers.
p_list->push_back(PropertyInfo(Variant::NIL, "Physics", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP));
for (int i = 0; i < physics.size(); i++) {
+ p_list->push_back(PropertyInfo(Variant::VECTOR2, vformat("physics_layer_%d/linear_velocity", i), PROPERTY_HINT_NONE));
+ p_list->push_back(PropertyInfo(Variant::FLOAT, vformat("physics_layer_%d/angular_velocity", i), PROPERTY_HINT_NONE));
p_list->push_back(PropertyInfo(Variant::INT, vformat("physics_layer_%d/polygons_count", i), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
for (int j = 0; j < physics[i].polygons.size(); j++) {
@@ -4791,8 +4847,12 @@ void TileData::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_occluder", "layer_id"), &TileData::get_occluder);
// Physics.
- ClassDB::bind_method(D_METHOD("get_collision_polygons_count", "layer_id"), &TileData::get_collision_polygons_count);
+ ClassDB::bind_method(D_METHOD("set_constant_linear_velocity", "layer_id", "velocity"), &TileData::set_constant_linear_velocity);
+ ClassDB::bind_method(D_METHOD("get_constant_linear_velocity", "layer_id"), &TileData::get_constant_linear_velocity);
+ ClassDB::bind_method(D_METHOD("set_constant_angular_velocity", "layer_id", "velocity"), &TileData::set_constant_angular_velocity);
+ ClassDB::bind_method(D_METHOD("get_constant_angular_velocity", "layer_id"), &TileData::get_constant_angular_velocity);
ClassDB::bind_method(D_METHOD("set_collision_polygons_count", "layer_id", "polygons_count"), &TileData::set_collision_polygons_count);
+ ClassDB::bind_method(D_METHOD("get_collision_polygons_count", "layer_id"), &TileData::get_collision_polygons_count);
ClassDB::bind_method(D_METHOD("add_collision_polygon", "layer_id"), &TileData::add_collision_polygon);
ClassDB::bind_method(D_METHOD("remove_collision_polygon", "layer_id", "polygon_index"), &TileData::remove_collision_polygon);
ClassDB::bind_method(D_METHOD("set_collision_polygon_points", "layer_id", "polygon_index", "polygon"), &TileData::set_collision_polygon_points);
diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h
index 46cb1fb36d..42b82957fb 100644
--- a/scene/resources/tile_set.h
+++ b/scene/resources/tile_set.h
@@ -645,6 +645,8 @@ private:
float one_way_margin = 1.0;
};
+ Vector2 linear_velocity;
+ float angular_velocity;
Vector<PolygonShapeTileData> polygons;
};
Vector<PhysicsLayerTileData> physics;
@@ -718,8 +720,12 @@ public:
Ref<OccluderPolygon2D> get_occluder(int p_layer_id) const;
// Physics
- int get_collision_polygons_count(int p_layer_id) const;
+ void set_constant_linear_velocity(int p_layer_id, const Vector2 &p_velocity);
+ Vector2 get_constant_linear_velocity(int p_layer_id) const;
+ void set_constant_angular_velocity(int p_layer_id, real_t p_velocity);
+ real_t get_constant_angular_velocity(int p_layer_id) const;
void set_collision_polygons_count(int p_layer_id, int p_shapes_count);
+ int get_collision_polygons_count(int p_layer_id) const;
void add_collision_polygon(int p_layer_id);
void remove_collision_polygon(int p_layer_id, int p_polygon_index);
void set_collision_polygon_points(int p_layer_id, int p_polygon_index, Vector<Vector2> p_polygon);