diff options
-rw-r--r-- | core/math/transform_2d.cpp | 12 | ||||
-rw-r--r-- | core/math/transform_2d.h | 11 | ||||
-rw-r--r-- | doc/classes/@GlobalScope.xml | 4 | ||||
-rw-r--r-- | editor/scene_tree_dock.cpp | 13 | ||||
-rw-r--r-- | scene/2d/node_2d.cpp | 42 | ||||
-rw-r--r-- | scene/2d/node_2d.h | 5 | ||||
-rw-r--r-- | scene/2d/tile_map.cpp | 7 | ||||
-rw-r--r-- | servers/register_server_types.cpp | 1 | ||||
-rw-r--r-- | servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp | 22 |
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++; } |