summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/math/transform_2d.cpp12
-rw-r--r--core/math/transform_2d.h11
-rw-r--r--doc/classes/@GlobalScope.xml4
-rw-r--r--editor/scene_tree_dock.cpp13
-rw-r--r--scene/2d/node_2d.cpp42
-rw-r--r--scene/2d/node_2d.h5
-rw-r--r--scene/2d/tile_map.cpp7
-rw-r--r--servers/register_server_types.cpp1
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp22
9 files changed, 94 insertions, 23 deletions
diff --git a/core/math/transform_2d.cpp b/core/math/transform_2d.cpp
index 97a9216a5a..ed95baa233 100644
--- a/core/math/transform_2d.cpp
+++ b/core/math/transform_2d.cpp
@@ -70,6 +70,18 @@ void Transform2D::rotate(real_t p_phi) {
*this = Transform2D(p_phi, Vector2()) * (*this);
}
+real_t Transform2D::get_skew() const {
+
+ real_t det = basis_determinant();
+ return Math::acos(elements[0].normalized().dot(SGN(det) * elements[1].normalized())) - Math_PI * 0.5;
+}
+
+void Transform2D::set_skew(float p_angle) {
+
+ real_t det = basis_determinant();
+ elements[1] = SGN(det) * elements[0].rotated((Math_PI * 0.5 + p_angle)).normalized() * elements[1].length();
+}
+
real_t Transform2D::get_rotation() const {
real_t det = basis_determinant();
Transform2D m = orthonormalized();
diff --git a/core/math/transform_2d.h b/core/math/transform_2d.h
index fa43762aa4..459ceed7a9 100644
--- a/core/math/transform_2d.h
+++ b/core/math/transform_2d.h
@@ -70,7 +70,10 @@ struct Transform2D {
void set_rotation(real_t p_rot);
real_t get_rotation() const;
+ real_t get_skew() const;
+ void set_skew(float p_angle);
_FORCE_INLINE_ void set_rotation_and_scale(real_t p_rot, const Size2 &p_scale);
+ _FORCE_INLINE_ void set_rotation_scale_and_skew(real_t p_rot, const Size2 &p_scale, float p_skew);
void rotate(real_t p_phi);
void scale(const Size2 &p_scale);
@@ -184,6 +187,14 @@ void Transform2D::set_rotation_and_scale(real_t p_rot, const Size2 &p_scale) {
elements[0][1] = Math::sin(p_rot) * p_scale.x;
}
+void Transform2D::set_rotation_scale_and_skew(real_t p_rot, const Size2 &p_scale, float p_skew) {
+
+ elements[0][0] = Math::cos(p_rot) * p_scale.x;
+ elements[1][1] = Math::cos(p_rot + p_skew) * p_scale.y;
+ elements[1][0] = -Math::sin(p_rot + p_skew) * p_scale.y;
+ elements[0][1] = Math::sin(p_rot) * p_scale.x;
+}
+
Rect2 Transform2D::xform_inv(const Rect2 &p_rect) const {
Vector2 ends[4] = {
diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml
index b3cd1c1af7..602ad43103 100644
--- a/doc/classes/@GlobalScope.xml
+++ b/doc/classes/@GlobalScope.xml
@@ -1177,10 +1177,10 @@
[codeblock]
var err = method_that_returns_error()
if err != OK:
- print("Failure!)
+ print("Failure!")
# Or, equivalent:
if err:
- print("Still failing!)
+ print("Still failing!")
[/codeblock]
</constant>
<constant name="FAILED" value="1" enum="Error">
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 92f899a35d..a8aeb05150 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -553,11 +553,12 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
selection.sort_custom<Node::Comparator>();
- for (List<Node *>::Element *E = selection.back(); E; E = E->prev()) {
+ Node *add_below_node = selection.back()->get();
+
+ for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
Node *node = E->get();
Node *parent = node->get_parent();
- Node *selection_tail = _get_selection_group_tail(node, selection);
List<Node *> owned;
node->get_owned_by(node->get_owner(), &owned);
@@ -575,7 +576,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
dup->set_name(parent->validate_child_name(dup));
- editor_data->get_undo_redo().add_do_method(parent, "add_child_below_node", selection_tail, dup);
+ editor_data->get_undo_redo().add_do_method(parent, "add_child_below_node", add_below_node, dup);
for (List<Node *>::Element *F = owned.front(); F; F = F->next()) {
if (!duplimap.has(F->get())) {
@@ -583,7 +584,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
continue;
}
Node *d = duplimap[F->get()];
- editor_data->get_undo_redo().add_do_method(d, "set_owner", selection_tail->get_owner());
+ editor_data->get_undo_redo().add_do_method(d, "set_owner", node->get_owner());
}
editor_data->get_undo_redo().add_do_method(editor_selection, "add_node", dup);
editor_data->get_undo_redo().add_undo_method(parent, "remove_child", dup);
@@ -593,6 +594,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
editor_data->get_undo_redo().add_do_method(ed, "live_debug_duplicate_node", edited_scene->get_path_to(node), dup->get_name());
editor_data->get_undo_redo().add_undo_method(ed, "live_debug_remove_node", NodePath(String(edited_scene->get_path_to(parent)).plus_file(dup->get_name())));
+
+ add_below_node = dup;
}
editor_data->get_undo_redo().commit_action();
@@ -600,7 +603,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
if (dupsingle)
editor->push_item(dupsingle);
- for (List<Node *>::Element *E = editable_children.front(); E; E = E->next())
+ for (List<Node *>::Element *E = editable_children.back(); E; E = E->prev())
_toggle_editable_children(E->get());
} break;
diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp
index ac8a77b6cb..1ea51be148 100644
--- a/scene/2d/node_2d.cpp
+++ b/scene/2d/node_2d.cpp
@@ -42,6 +42,7 @@ Dictionary Node2D::_edit_get_state() const {
state["position"] = get_position();
state["rotation"] = get_rotation();
state["scale"] = get_scale();
+ state["skew"] = get_skew();
return state;
}
@@ -51,11 +52,14 @@ void Node2D::_edit_set_state(const Dictionary &p_state) {
pos = p_state["position"];
angle = p_state["rotation"];
_scale = p_state["scale"];
+ skew = p_state["skew"];
_update_transform();
_change_notify("rotation");
_change_notify("rotation_degrees");
_change_notify("scale");
+ _change_notify("skew");
+ _change_notify("skew_degrees");
_change_notify("position");
}
@@ -111,7 +115,7 @@ void Node2D::_edit_set_rect(const Rect2 &p_edit_rect) {
Point2 new_pos = p_edit_rect.position + p_edit_rect.size * zero_offset;
Transform2D postxf;
- postxf.set_rotation_and_scale(angle, _scale);
+ postxf.set_rotation_scale_and_skew(angle, _scale, skew);
new_pos = postxf.xform(new_pos);
pos += new_pos;
@@ -128,12 +132,13 @@ void Node2D::_update_xform_values() {
pos = _mat.elements[2];
angle = _mat.get_rotation();
_scale = _mat.get_scale();
+ skew = _mat.get_skew();
_xform_dirty = false;
}
void Node2D::_update_transform() {
- _mat.set_rotation_and_scale(angle, _scale);
+ _mat.set_rotation_scale_and_skew(angle, _scale, skew);
_mat.elements[2] = pos;
RenderingServer::get_singleton()->canvas_item_set_transform(get_canvas_item(), _mat);
@@ -163,11 +168,26 @@ void Node2D::set_rotation(float p_radians) {
_change_notify("rotation_degrees");
}
+void Node2D::set_skew(float p_radians) {
+
+ if (_xform_dirty)
+ ((Node2D *)this)->_update_xform_values();
+ skew = p_radians;
+ _update_transform();
+ _change_notify("skew");
+ _change_notify("skew_degrees");
+}
+
void Node2D::set_rotation_degrees(float p_degrees) {
set_rotation(Math::deg2rad(p_degrees));
}
+void Node2D::set_skew_degrees(float p_degrees) {
+
+ set_skew(Math::deg2rad(p_degrees));
+}
+
void Node2D::set_scale(const Size2 &p_scale) {
if (_xform_dirty)
@@ -196,11 +216,22 @@ float Node2D::get_rotation() const {
return angle;
}
+float Node2D::get_skew() const {
+ if (_xform_dirty)
+ ((Node2D *)this)->_update_xform_values();
+
+ return skew;
+}
+
float Node2D::get_rotation_degrees() const {
return Math::rad2deg(get_rotation());
}
+float Node2D::get_skew_degrees() const {
+
+ return Math::rad2deg(get_skew());
+}
Size2 Node2D::get_scale() const {
if (_xform_dirty)
((Node2D *)this)->_update_xform_values();
@@ -398,11 +429,15 @@ void Node2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_position", "position"), &Node2D::set_position);
ClassDB::bind_method(D_METHOD("set_rotation", "radians"), &Node2D::set_rotation);
ClassDB::bind_method(D_METHOD("set_rotation_degrees", "degrees"), &Node2D::set_rotation_degrees);
+ ClassDB::bind_method(D_METHOD("set_skew", "radians"), &Node2D::set_skew);
+ ClassDB::bind_method(D_METHOD("set_skew_degrees", "degrees"), &Node2D::set_skew_degrees);
ClassDB::bind_method(D_METHOD("set_scale", "scale"), &Node2D::set_scale);
ClassDB::bind_method(D_METHOD("get_position"), &Node2D::get_position);
ClassDB::bind_method(D_METHOD("get_rotation"), &Node2D::get_rotation);
ClassDB::bind_method(D_METHOD("get_rotation_degrees"), &Node2D::get_rotation_degrees);
+ ClassDB::bind_method(D_METHOD("get_skew"), &Node2D::get_skew);
+ ClassDB::bind_method(D_METHOD("get_skew_degrees"), &Node2D::get_skew_degrees);
ClassDB::bind_method(D_METHOD("get_scale"), &Node2D::get_scale);
ClassDB::bind_method(D_METHOD("rotate", "radians"), &Node2D::rotate);
@@ -443,6 +478,8 @@ void Node2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rotation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_rotation", "get_rotation");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rotation_degrees", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater", PROPERTY_USAGE_EDITOR), "set_rotation_degrees", "get_rotation_degrees");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scale"), "set_scale", "get_scale");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "skew", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_skew", "get_skew");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "skew_degrees", PROPERTY_HINT_RANGE, "-89.9,89.9,0.1", PROPERTY_USAGE_EDITOR), "set_skew_degrees", "get_skew_degrees");
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "transform", PROPERTY_HINT_NONE, "", 0), "set_transform", "get_transform");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "global_position", PROPERTY_HINT_NONE, "", 0), "set_global_position", "get_global_position");
@@ -460,6 +497,7 @@ Node2D::Node2D() {
angle = 0;
_scale = Vector2(1, 1);
+ skew = 0;
_xform_dirty = false;
z_index = 0;
z_relative = true;
diff --git a/scene/2d/node_2d.h b/scene/2d/node_2d.h
index abed05ed0c..0afec36254 100644
--- a/scene/2d/node_2d.h
+++ b/scene/2d/node_2d.h
@@ -40,6 +40,7 @@ class Node2D : public CanvasItem {
Point2 pos;
float angle;
Size2 _scale;
+ float skew;
int z_index;
bool z_relative;
@@ -75,6 +76,8 @@ public:
void set_position(const Point2 &p_pos);
void set_rotation(float p_radians);
void set_rotation_degrees(float p_degrees);
+ void set_skew(float p_radians);
+ void set_skew_degrees(float p_radians);
void set_scale(const Size2 &p_scale);
void rotate(float p_radians);
@@ -86,7 +89,9 @@ public:
Point2 get_position() const;
float get_rotation() const;
+ float get_skew() const;
float get_rotation_degrees() const;
+ float get_skew_degrees() const;
Size2 get_scale() const;
Point2 get_global_position() const;
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 9628c01718..86e61fe878 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -940,13 +940,10 @@ void TileMap::update_bitmask_area(const Vector2 &p_pos) {
void TileMap::update_bitmask_region(const Vector2 &p_start, const Vector2 &p_end) {
if ((p_end.x < p_start.x || p_end.y < p_start.y) || (p_end.x == p_start.x && p_end.y == p_start.y)) {
- int i;
Array a = get_used_cells();
- for (i = 0; i < a.size(); i++) {
- // update_bitmask_area() in order to update cells adjacent to the
- // current cell, since ordering in array may not be reliable
+ for (int i = 0; i < a.size(); i++) {
Vector2 vector = (Vector2)a[i];
- update_bitmask_area(Vector2(vector.x, vector.y));
+ update_cell_bitmask(vector.x, vector.y);
}
return;
}
diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp
index 60217002fb..eb92cf55e3 100644
--- a/servers/register_server_types.cpp
+++ b/servers/register_server_types.cpp
@@ -218,6 +218,7 @@ void register_server_singletons() {
Engine::get_singleton()->add_singleton(Engine::Singleton("DisplayServer", DisplayServer::get_singleton()));
Engine::get_singleton()->add_singleton(Engine::Singleton("RenderingServer", RenderingServer::get_singleton()));
+ Engine::get_singleton()->add_singleton(Engine::Singleton("RenderingDevice", RenderingDevice::get_singleton()));
Engine::get_singleton()->add_singleton(Engine::Singleton("AudioServer", AudioServer::get_singleton()));
Engine::get_singleton()->add_singleton(Engine::Singleton("PhysicsServer2D", PhysicsServer2D::get_singleton()));
Engine::get_singleton()->add_singleton(Engine::Singleton("PhysicsServer3D", PhysicsServer3D::get_singleton()));
diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp
index b3cf40f166..6986f82065 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp
+++ b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp
@@ -1720,6 +1720,16 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig
light_data.shadow_enabled = p_using_shadows && storage->light_has_shadow(base);
+ float angular_diameter = storage->light_get_param(base, RS::LIGHT_PARAM_SIZE);
+ if (angular_diameter > 0.0) {
+ // I know tan(0) is 0, but let's not risk it with numerical precision.
+ // technically this will keep expanding until reaching the sun, but all we care
+ // is expand until we reach the radius of the near plane (there can't be more occluders than that)
+ angular_diameter = Math::tan(Math::deg2rad(angular_diameter));
+ } else {
+ angular_diameter = 0.0;
+ }
+
if (light_data.shadow_enabled) {
RS::LightDirectionalShadowMode smode = storage->light_directional_get_shadow_mode(base);
@@ -1775,15 +1785,9 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig
light_data.fade_to = -light_data.shadow_split_offsets[3];
light_data.soft_shadow_scale = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BLUR);
+ light_data.softshadow_angle = angular_diameter;
- float softshadow_angle = storage->light_get_param(base, RS::LIGHT_PARAM_SIZE);
- if (softshadow_angle > 0.0) {
- // I know tan(0) is 0, but let's not risk it with numerical precision.
- // technically this will keep expanding until reaching the sun, but all we care
- // is expand until we reach the radius of the near plane (there can't be more occluders than that)
- light_data.softshadow_angle = Math::tan(Math::deg2rad(softshadow_angle));
- } else {
- light_data.softshadow_angle = 0;
+ if (angular_diameter <= 0.0) {
light_data.soft_shadow_scale *= directional_shadow_quality_radius_get(); // Only use quality radius for PCF
}
}
@@ -1806,7 +1810,7 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig
sky_light_data.color[2] = light_data.color[2];
sky_light_data.enabled = true;
- sky_light_data.size = light_data.softshadow_angle;
+ sky_light_data.size = angular_diameter;
sky_scene_state.directional_light_count++;
}