summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/2d/animated_sprite.cpp2
-rw-r--r--scene/2d/animated_sprite.h2
-rw-r--r--scene/2d/back_buffer_copy.cpp2
-rw-r--r--scene/2d/back_buffer_copy.h2
-rw-r--r--scene/2d/canvas_item.cpp7
-rw-r--r--scene/2d/canvas_item.h3
-rw-r--r--scene/2d/collision_polygon_2d.cpp2
-rw-r--r--scene/2d/collision_polygon_2d.h10
-rw-r--r--scene/2d/cpu_particles_2d.cpp21
-rw-r--r--scene/2d/cpu_particles_2d.h5
-rw-r--r--scene/2d/light_2d.cpp6
-rw-r--r--scene/2d/light_2d.h2
-rw-r--r--scene/2d/light_occluder_2d.cpp5
-rw-r--r--scene/2d/light_occluder_2d.h4
-rw-r--r--scene/2d/line_2d.cpp2
-rw-r--r--scene/2d/line_2d.h6
-rw-r--r--scene/2d/mesh_instance_2d.cpp2
-rw-r--r--scene/2d/mesh_instance_2d.h6
-rw-r--r--scene/2d/multimesh_instance_2d.cpp2
-rw-r--r--scene/2d/multimesh_instance_2d.h6
-rw-r--r--scene/2d/navigation_polygon.cpp5
-rw-r--r--scene/2d/navigation_polygon.h4
-rw-r--r--scene/2d/node_2d.cpp4
-rw-r--r--scene/2d/node_2d.h2
-rw-r--r--scene/2d/path_2d.cpp8
-rw-r--r--scene/2d/path_2d.h2
-rw-r--r--scene/2d/physics_body_2d.cpp35
-rw-r--r--scene/2d/physics_body_2d.h6
-rw-r--r--scene/2d/polygon_2d.cpp191
-rw-r--r--scene/2d/polygon_2d.h2
-rw-r--r--scene/2d/position_2d.cpp2
-rw-r--r--scene/2d/position_2d.h2
-rw-r--r--scene/2d/sprite.cpp12
-rw-r--r--scene/2d/sprite.h6
-rw-r--r--scene/2d/tile_map.cpp2
-rw-r--r--scene/2d/tile_map.h2
-rw-r--r--scene/2d/touch_screen_button.cpp12
-rw-r--r--scene/2d/touch_screen_button.h7
-rw-r--r--scene/2d/visibility_notifier_2d.cpp19
-rw-r--r--scene/2d/visibility_notifier_2d.h2
-rw-r--r--scene/3d/arvr_nodes.cpp13
-rw-r--r--scene/3d/camera.cpp14
-rw-r--r--scene/3d/cpu_particles.cpp6
-rw-r--r--scene/3d/cpu_particles.h1
-rw-r--r--scene/3d/path.cpp6
-rw-r--r--scene/3d/physics_body.cpp35
-rw-r--r--scene/3d/physics_body.h6
-rw-r--r--scene/3d/portal.cpp232
-rw-r--r--scene/3d/portal.h88
-rw-r--r--scene/3d/room_instance.cpp164
-rw-r--r--scene/3d/room_instance.h81
-rw-r--r--scene/3d/spatial.cpp1
-rw-r--r--scene/3d/voxel_light_baker.cpp4
-rw-r--r--scene/animation/animation_blend_tree.cpp20
-rw-r--r--scene/animation/skeleton_ik.cpp15
-rw-r--r--scene/animation/skeleton_ik.h1
-rw-r--r--scene/animation/tween.cpp1
-rw-r--r--scene/gui/base_button.cpp2
-rw-r--r--scene/gui/center_container.cpp6
-rw-r--r--scene/gui/control.cpp22
-rw-r--r--scene/gui/control.h2
-rw-r--r--scene/gui/graph_edit.cpp28
-rw-r--r--scene/gui/item_list.cpp2
-rw-r--r--scene/gui/label.cpp19
-rw-r--r--scene/gui/line_edit.cpp30
-rw-r--r--scene/gui/option_button.cpp9
-rw-r--r--scene/gui/rich_text_label.cpp51
-rw-r--r--scene/gui/scroll_container.cpp38
-rw-r--r--scene/gui/spin_box.cpp5
-rw-r--r--scene/gui/spin_box.h2
-rw-r--r--scene/gui/tab_container.cpp16
-rw-r--r--scene/gui/tab_container.h2
-rw-r--r--scene/gui/text_edit.cpp6
-rw-r--r--scene/gui/video_player.cpp4
-rw-r--r--scene/main/node.cpp3
-rw-r--r--scene/main/scene_tree.cpp20
-rw-r--r--scene/register_scene_types.cpp46
-rw-r--r--scene/resources/audio_stream_sample.cpp3
-rw-r--r--scene/resources/audio_stream_sample.h6
-rw-r--r--scene/resources/default_theme/default_theme.cpp2
-rw-r--r--scene/resources/dynamic_font.cpp17
-rw-r--r--scene/resources/font.cpp4
-rw-r--r--scene/resources/material.h4
-rw-r--r--scene/resources/mesh.cpp4
-rw-r--r--scene/resources/packed_scene.cpp4
-rw-r--r--scene/resources/particles_material.cpp13
-rw-r--r--scene/resources/particles_material.h1
-rw-r--r--scene/resources/room.cpp70
-rw-r--r--scene/resources/room.h62
-rw-r--r--scene/resources/texture.h3
-rw-r--r--scene/resources/tile_set.cpp2
-rw-r--r--scene/resources/video_stream.cpp39
-rw-r--r--scene/resources/video_stream.h11
-rw-r--r--scene/resources/visual_shader.cpp54
-rw-r--r--scene/resources/visual_shader.h10
-rw-r--r--scene/resources/visual_shader_nodes.cpp61
-rw-r--r--scene/resources/visual_shader_nodes.h11
97 files changed, 567 insertions, 1237 deletions
diff --git a/scene/2d/animated_sprite.cpp b/scene/2d/animated_sprite.cpp
index 28a8c4d658..917ced5feb 100644
--- a/scene/2d/animated_sprite.cpp
+++ b/scene/2d/animated_sprite.cpp
@@ -35,6 +35,7 @@
#define NORMAL_SUFFIX "_normal"
+#ifdef TOOLS_ENABLED
Dictionary AnimatedSprite::_edit_get_state() const {
Dictionary state = Node2D::_edit_get_state();
state["offset"] = offset;
@@ -72,6 +73,7 @@ bool AnimatedSprite::_edit_use_rect() const {
t = frames->get_frame(animation, frame);
return t.is_valid();
}
+#endif
Rect2 AnimatedSprite::get_anchorable_rect() const {
return _get_rect();
diff --git a/scene/2d/animated_sprite.h b/scene/2d/animated_sprite.h
index 2017c62a48..cd00a4e181 100644
--- a/scene/2d/animated_sprite.h
+++ b/scene/2d/animated_sprite.h
@@ -156,6 +156,7 @@ protected:
virtual void _validate_property(PropertyInfo &property) const;
public:
+#ifdef TOOLS_ENABLED
virtual Dictionary _edit_get_state() const;
virtual void _edit_set_state(const Dictionary &p_state);
@@ -164,6 +165,7 @@ public:
virtual bool _edit_use_pivot() const;
virtual Rect2 _edit_get_rect() const;
virtual bool _edit_use_rect() const;
+#endif
virtual Rect2 get_anchorable_rect() const;
diff --git a/scene/2d/back_buffer_copy.cpp b/scene/2d/back_buffer_copy.cpp
index 1a6f30e0fd..faeb6b7169 100644
--- a/scene/2d/back_buffer_copy.cpp
+++ b/scene/2d/back_buffer_copy.cpp
@@ -50,6 +50,7 @@ void BackBufferCopy::_update_copy_mode() {
}
}
+#ifdef TOOLS_ENABLED
Rect2 BackBufferCopy::_edit_get_rect() const {
return rect;
@@ -58,6 +59,7 @@ Rect2 BackBufferCopy::_edit_get_rect() const {
bool BackBufferCopy::_edit_use_rect() const {
return true;
}
+#endif
Rect2 BackBufferCopy::get_anchorable_rect() const {
diff --git a/scene/2d/back_buffer_copy.h b/scene/2d/back_buffer_copy.h
index 91acd81e00..4b26bf1bdc 100644
--- a/scene/2d/back_buffer_copy.h
+++ b/scene/2d/back_buffer_copy.h
@@ -53,8 +53,10 @@ protected:
static void _bind_methods();
public:
+#ifdef TOOLS_ENABLED
Rect2 _edit_get_rect() const;
virtual bool _edit_use_rect() const;
+#endif
void set_rect(const Rect2 &p_rect);
Rect2 get_rect() const;
diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp
index 9895dba027..5631aa3355 100644
--- a/scene/2d/canvas_item.cpp
+++ b/scene/2d/canvas_item.cpp
@@ -351,7 +351,7 @@ CanvasItemMaterial::~CanvasItemMaterial() {
}
///////////////////////////////////////////////////////////////////
-
+#ifdef TOOLS_ENABLED
bool CanvasItem::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
if (_edit_use_rect()) {
return _edit_get_rect().has_point(p_point);
@@ -363,6 +363,7 @@ bool CanvasItem::_edit_is_selected_on_click(const Point2 &p_point, double p_tole
Transform2D CanvasItem::_edit_get_transform() const {
return Transform2D(_edit_get_rotation(), _edit_get_position() + _edit_get_pivot());
}
+#endif
bool CanvasItem::is_visible_in_tree() const {
@@ -1121,9 +1122,10 @@ void CanvasItem::_bind_methods() {
ClassDB::bind_method(D_METHOD("_toplevel_raise_self"), &CanvasItem::_toplevel_raise_self);
ClassDB::bind_method(D_METHOD("_update_callback"), &CanvasItem::_update_callback);
+
+#ifdef TOOLS_ENABLED
ClassDB::bind_method(D_METHOD("_edit_set_state", "state"), &CanvasItem::_edit_set_state);
ClassDB::bind_method(D_METHOD("_edit_get_state"), &CanvasItem::_edit_get_state);
-
ClassDB::bind_method(D_METHOD("_edit_set_position", "position"), &CanvasItem::_edit_set_position);
ClassDB::bind_method(D_METHOD("_edit_get_position"), &CanvasItem::_edit_get_position);
ClassDB::bind_method(D_METHOD("_edit_set_scale", "scale"), &CanvasItem::_edit_set_scale);
@@ -1138,6 +1140,7 @@ void CanvasItem::_bind_methods() {
ClassDB::bind_method(D_METHOD("_edit_get_pivot"), &CanvasItem::_edit_get_pivot);
ClassDB::bind_method(D_METHOD("_edit_use_pivot"), &CanvasItem::_edit_use_pivot);
ClassDB::bind_method(D_METHOD("_edit_get_transform"), &CanvasItem::_edit_get_transform);
+#endif
ClassDB::bind_method(D_METHOD("get_canvas_item"), &CanvasItem::get_canvas_item);
diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h
index 82645051e8..8814d99edd 100644
--- a/scene/2d/canvas_item.h
+++ b/scene/2d/canvas_item.h
@@ -249,7 +249,7 @@ public:
};
/* EDITOR */
-
+#ifdef TOOLS_ENABLED
// Select the node
virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
@@ -282,6 +282,7 @@ public:
virtual Point2 _edit_get_pivot() const { return Point2(); };
virtual Transform2D _edit_get_transform() const;
+#endif
/* VISIBILITY */
diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp
index 3090c9956e..d9cc94c6eb 100644
--- a/scene/2d/collision_polygon_2d.cpp
+++ b/scene/2d/collision_polygon_2d.cpp
@@ -227,6 +227,7 @@ CollisionPolygon2D::BuildMode CollisionPolygon2D::get_build_mode() const {
return build_mode;
}
+#ifdef TOOLS_ENABLED
Rect2 CollisionPolygon2D::_edit_get_rect() const {
return aabb;
@@ -240,6 +241,7 @@ bool CollisionPolygon2D::_edit_is_selected_on_click(const Point2 &p_point, doubl
return Geometry::is_point_in_polygon(p_point, Variant(polygon));
}
+#endif
String CollisionPolygon2D::get_configuration_warning() const {
diff --git a/scene/2d/collision_polygon_2d.h b/scene/2d/collision_polygon_2d.h
index e5e18b2674..d8dfec8fd2 100644
--- a/scene/2d/collision_polygon_2d.h
+++ b/scene/2d/collision_polygon_2d.h
@@ -67,16 +67,18 @@ protected:
static void _bind_methods();
public:
+#ifdef TOOLS_ENABLED
+ virtual Rect2 _edit_get_rect() const;
+ virtual bool _edit_use_rect() const;
+ virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
+#endif
+
void set_build_mode(BuildMode p_mode);
BuildMode get_build_mode() const;
void set_polygon(const Vector<Point2> &p_polygon);
Vector<Point2> get_polygon() const;
- virtual Rect2 _edit_get_rect() const;
- virtual bool _edit_use_rect() const;
- virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
-
virtual String get_configuration_warning() const;
void set_disabled(bool p_disabled);
diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp
index 8296f35739..f59e3461b1 100644
--- a/scene/2d/cpu_particles_2d.cpp
+++ b/scene/2d/cpu_particles_2d.cpp
@@ -294,15 +294,6 @@ float CPUParticles2D::get_spread() const {
return spread;
}
-void CPUParticles2D::set_flatness(float p_flatness) {
-
- flatness = p_flatness;
-}
-float CPUParticles2D::get_flatness() const {
-
- return flatness;
-}
-
void CPUParticles2D::set_param(Parameter p_param, float p_value) {
ERR_FAIL_INDEX(p_param, PARAM_MAX);
@@ -422,7 +413,7 @@ bool CPUParticles2D::get_particle_flag(Flags p_flag) const {
}
void CPUParticles2D::set_emission_shape(EmissionShape p_shape) {
-
+ ERR_FAIL_INDEX(p_shape, EMISSION_SHAPE_MAX);
emission_shape = p_shape;
_change_notify();
}
@@ -772,6 +763,9 @@ void CPUParticles2D::_particles_process(float p_delta) {
p.base_color = emission_colors.get(random_idx);
}
} break;
+ case EMISSION_SHAPE_MAX: { // Max value for validity check.
+ break;
+ }
}
if (!local_coords) {
@@ -1166,7 +1160,6 @@ void CPUParticles2D::convert_from_particles(Node *p_particles) {
Vector3 dir = material->get_direction();
set_direction(Vector2(dir.x, dir.y));
set_spread(material->get_spread());
- set_flatness(material->get_flatness());
set_color(material->get_color());
@@ -1280,9 +1273,6 @@ void CPUParticles2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_spread", "degrees"), &CPUParticles2D::set_spread);
ClassDB::bind_method(D_METHOD("get_spread"), &CPUParticles2D::get_spread);
- ClassDB::bind_method(D_METHOD("set_flatness", "amount"), &CPUParticles2D::set_flatness);
- ClassDB::bind_method(D_METHOD("get_flatness"), &CPUParticles2D::get_flatness);
-
ClassDB::bind_method(D_METHOD("set_param", "param", "value"), &CPUParticles2D::set_param);
ClassDB::bind_method(D_METHOD("get_param", "param"), &CPUParticles2D::get_param);
@@ -1338,7 +1328,6 @@ void CPUParticles2D::_bind_methods() {
ADD_GROUP("Direction", "");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "direction"), "set_direction", "get_direction");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "spread", PROPERTY_HINT_RANGE, "0,180,0.01"), "set_spread", "get_spread");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "flatness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_flatness", "get_flatness");
ADD_GROUP("Gravity", "");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "gravity"), "set_gravity", "get_gravity");
ADD_GROUP("Initial Velocity", "initial_");
@@ -1416,6 +1405,7 @@ void CPUParticles2D::_bind_methods() {
BIND_ENUM_CONSTANT(EMISSION_SHAPE_RECTANGLE);
BIND_ENUM_CONSTANT(EMISSION_SHAPE_POINTS);
BIND_ENUM_CONSTANT(EMISSION_SHAPE_DIRECTED_POINTS);
+ BIND_ENUM_CONSTANT(EMISSION_SHAPE_MAX);
}
CPUParticles2D::CPUParticles2D() {
@@ -1448,7 +1438,6 @@ CPUParticles2D::CPUParticles2D() {
set_direction(Vector2(1, 0));
set_spread(45);
- set_flatness(0);
set_param(PARAM_INITIAL_LINEAR_VELOCITY, 0);
set_param(PARAM_ANGULAR_VELOCITY, 0);
set_param(PARAM_ORBIT_VELOCITY, 0);
diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h
index 6ffa1f0e97..085ec99ea0 100644
--- a/scene/2d/cpu_particles_2d.h
+++ b/scene/2d/cpu_particles_2d.h
@@ -75,6 +75,7 @@ public:
EMISSION_SHAPE_RECTANGLE,
EMISSION_SHAPE_POINTS,
EMISSION_SHAPE_DIRECTED_POINTS,
+ EMISSION_SHAPE_MAX
};
private:
@@ -153,7 +154,6 @@ private:
Vector2 direction;
float spread;
- float flatness;
float parameters[PARAM_MAX];
float randomness[PARAM_MAX];
@@ -242,9 +242,6 @@ public:
void set_spread(float p_spread);
float get_spread() const;
- void set_flatness(float p_flatness);
- float get_flatness() const;
-
void set_param(Parameter p_param, float p_value);
float get_param(Parameter p_param) const;
diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp
index 1843cbed67..1bffaf8084 100644
--- a/scene/2d/light_2d.cpp
+++ b/scene/2d/light_2d.cpp
@@ -33,6 +33,7 @@
#include "core/engine.h"
#include "servers/visual_server.h"
+#ifdef TOOLS_ENABLED
Dictionary Light2D::_edit_get_state() const {
Dictionary state = Node2D::_edit_get_state();
state["offset"] = get_texture_offset();
@@ -68,6 +69,7 @@ Rect2 Light2D::_edit_get_rect() const {
bool Light2D::_edit_use_rect() const {
return !texture.is_null();
}
+#endif
Rect2 Light2D::get_anchorable_rect() const {
if (texture.is_null())
@@ -187,6 +189,10 @@ float Light2D::get_energy() const {
void Light2D::set_texture_scale(float p_scale) {
_scale = p_scale;
+ // Avoid having 0 scale values, can lead to errors in physics and rendering.
+ if (_scale == 0) {
+ _scale = CMP_EPSILON;
+ }
VS::get_singleton()->canvas_light_set_scale(canvas_light, _scale);
item_rect_changed();
}
diff --git a/scene/2d/light_2d.h b/scene/2d/light_2d.h
index f8476e8389..65db5c6ee6 100644
--- a/scene/2d/light_2d.h
+++ b/scene/2d/light_2d.h
@@ -85,6 +85,7 @@ protected:
static void _bind_methods();
public:
+#ifdef TOOLS_ENABLED
virtual Dictionary _edit_get_state() const;
virtual void _edit_set_state(const Dictionary &p_state);
@@ -93,6 +94,7 @@ public:
virtual bool _edit_use_pivot() const;
virtual Rect2 _edit_get_rect() const;
virtual bool _edit_use_rect() const;
+#endif
virtual Rect2 get_anchorable_rect() const;
diff --git a/scene/2d/light_occluder_2d.cpp b/scene/2d/light_occluder_2d.cpp
index 6a930683d1..0e8e8f6679 100644
--- a/scene/2d/light_occluder_2d.cpp
+++ b/scene/2d/light_occluder_2d.cpp
@@ -33,6 +33,8 @@
#include "core/engine.h"
#define LINE_GRAB_WIDTH 8
+
+#ifdef TOOLS_ENABLED
Rect2 OccluderPolygon2D::_edit_get_rect() const {
if (rect_cache_dirty) {
@@ -80,6 +82,7 @@ bool OccluderPolygon2D::_edit_is_selected_on_click(const Point2 &p_point, double
return false;
}
}
+#endif
void OccluderPolygon2D::set_polygon(const PoolVector<Vector2> &p_polygon) {
@@ -215,6 +218,7 @@ void LightOccluder2D::_notification(int p_what) {
}
}
+#ifdef TOOLS_ENABLED
Rect2 LightOccluder2D::_edit_get_rect() const {
return occluder_polygon.is_valid() ? occluder_polygon->_edit_get_rect() : Rect2();
@@ -224,6 +228,7 @@ bool LightOccluder2D::_edit_is_selected_on_click(const Point2 &p_point, double p
return occluder_polygon.is_valid() ? occluder_polygon->_edit_is_selected_on_click(p_point, p_tolerance) : false;
}
+#endif
void LightOccluder2D::set_occluder_polygon(const Ref<OccluderPolygon2D> &p_polygon) {
diff --git a/scene/2d/light_occluder_2d.h b/scene/2d/light_occluder_2d.h
index 32d527093d..b20e347c35 100644
--- a/scene/2d/light_occluder_2d.h
+++ b/scene/2d/light_occluder_2d.h
@@ -57,8 +57,10 @@ protected:
static void _bind_methods();
public:
+#ifdef TOOLS_ENABLED
virtual Rect2 _edit_get_rect() const;
virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
+#endif
void set_polygon(const PoolVector<Vector2> &p_polygon);
PoolVector<Vector2> get_polygon() const;
@@ -91,8 +93,10 @@ protected:
static void _bind_methods();
public:
+#ifdef TOOLS_ENABLED
virtual Rect2 _edit_get_rect() const;
virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
+#endif
void set_occluder_polygon(const Ref<OccluderPolygon2D> &p_polygon);
Ref<OccluderPolygon2D> get_occluder_polygon() const;
diff --git a/scene/2d/line_2d.cpp b/scene/2d/line_2d.cpp
index 4a022f0a9c..c31840c8e1 100644
--- a/scene/2d/line_2d.cpp
+++ b/scene/2d/line_2d.cpp
@@ -50,6 +50,7 @@ Line2D::Line2D() {
_antialiased = false;
}
+#ifdef TOOLS_ENABLED
Rect2 Line2D::_edit_get_rect() const {
if (_points.size() == 0)
@@ -79,6 +80,7 @@ bool Line2D::_edit_is_selected_on_click(const Point2 &p_point, double p_toleranc
return false;
}
+#endif
void Line2D::set_points(const PoolVector<Vector2> &p_points) {
_points = p_points;
diff --git a/scene/2d/line_2d.h b/scene/2d/line_2d.h
index bc2deba8c6..3c7239f67c 100644
--- a/scene/2d/line_2d.h
+++ b/scene/2d/line_2d.h
@@ -56,11 +56,13 @@ public:
LINE_TEXTURE_STRETCH
};
- Line2D();
-
+#ifdef TOOLS_ENABLED
virtual Rect2 _edit_get_rect() const;
virtual bool _edit_use_rect() const;
virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
+#endif
+
+ Line2D();
void set_points(const PoolVector<Vector2> &p_points);
PoolVector<Vector2> get_points() const;
diff --git a/scene/2d/mesh_instance_2d.cpp b/scene/2d/mesh_instance_2d.cpp
index 8f9c4e2a4d..93432ec40b 100644
--- a/scene/2d/mesh_instance_2d.cpp
+++ b/scene/2d/mesh_instance_2d.cpp
@@ -94,6 +94,7 @@ Ref<Texture> MeshInstance2D::get_texture() const {
return texture;
}
+#ifdef TOOLS_ENABLED
Rect2 MeshInstance2D::_edit_get_rect() const {
if (mesh.is_valid()) {
@@ -103,6 +104,7 @@ Rect2 MeshInstance2D::_edit_get_rect() const {
return Node2D::_edit_get_rect();
}
+#endif
MeshInstance2D::MeshInstance2D() {
}
diff --git a/scene/2d/mesh_instance_2d.h b/scene/2d/mesh_instance_2d.h
index e7f8b7c0c3..51f75a3ead 100644
--- a/scene/2d/mesh_instance_2d.h
+++ b/scene/2d/mesh_instance_2d.h
@@ -46,6 +46,10 @@ protected:
static void _bind_methods();
public:
+#ifdef TOOLS_ENABLED
+ virtual Rect2 _edit_get_rect() const;
+#endif
+
void set_mesh(const Ref<Mesh> &p_mesh);
Ref<Mesh> get_mesh() const;
@@ -55,8 +59,6 @@ public:
void set_normal_map(const Ref<Texture> &p_texture);
Ref<Texture> get_normal_map() const;
- virtual Rect2 _edit_get_rect() const;
-
MeshInstance2D();
};
diff --git a/scene/2d/multimesh_instance_2d.cpp b/scene/2d/multimesh_instance_2d.cpp
index 69d687229b..028459e778 100644
--- a/scene/2d/multimesh_instance_2d.cpp
+++ b/scene/2d/multimesh_instance_2d.cpp
@@ -94,6 +94,7 @@ Ref<Texture> MultiMeshInstance2D::get_normal_map() const {
return normal_map;
}
+#ifdef TOOLS_ENABLED
Rect2 MultiMeshInstance2D::_edit_get_rect() const {
if (multimesh.is_valid()) {
@@ -103,6 +104,7 @@ Rect2 MultiMeshInstance2D::_edit_get_rect() const {
return Node2D::_edit_get_rect();
}
+#endif
MultiMeshInstance2D::MultiMeshInstance2D() {
}
diff --git a/scene/2d/multimesh_instance_2d.h b/scene/2d/multimesh_instance_2d.h
index 253f4c77ca..c3f3e52920 100644
--- a/scene/2d/multimesh_instance_2d.h
+++ b/scene/2d/multimesh_instance_2d.h
@@ -47,6 +47,10 @@ protected:
static void _bind_methods();
public:
+#ifdef TOOLS_ENABLED
+ virtual Rect2 _edit_get_rect() const;
+#endif
+
void set_multimesh(const Ref<MultiMesh> &p_multimesh);
Ref<MultiMesh> get_multimesh() const;
@@ -56,8 +60,6 @@ public:
void set_normal_map(const Ref<Texture> &p_texture);
Ref<Texture> get_normal_map() const;
- virtual Rect2 _edit_get_rect() const;
-
MultiMeshInstance2D();
~MultiMeshInstance2D();
};
diff --git a/scene/2d/navigation_polygon.cpp b/scene/2d/navigation_polygon.cpp
index bd930bdda5..ea79f89dd9 100644
--- a/scene/2d/navigation_polygon.cpp
+++ b/scene/2d/navigation_polygon.cpp
@@ -36,6 +36,7 @@
#include "thirdparty/misc/triangulator.h"
+#ifdef TOOLS_ENABLED
Rect2 NavigationPolygon::_edit_get_rect() const {
if (rect_cache_dirty) {
@@ -75,6 +76,7 @@ bool NavigationPolygon::_edit_is_selected_on_click(const Point2 &p_point, double
}
return false;
}
+#endif
void NavigationPolygon::set_vertices(const PoolVector<Vector2> &p_vertices) {
@@ -357,7 +359,7 @@ bool NavigationPolygonInstance::is_enabled() const {
}
/////////////////////////////
-
+#ifdef TOOLS_ENABLED
Rect2 NavigationPolygonInstance::_edit_get_rect() const {
return navpoly.is_valid() ? navpoly->_edit_get_rect() : Rect2();
@@ -367,6 +369,7 @@ bool NavigationPolygonInstance::_edit_is_selected_on_click(const Point2 &p_point
return navpoly.is_valid() ? navpoly->_edit_is_selected_on_click(p_point, p_tolerance) : false;
}
+#endif
void NavigationPolygonInstance::_notification(int p_what) {
diff --git a/scene/2d/navigation_polygon.h b/scene/2d/navigation_polygon.h
index 9bbaa864f4..cbc1711a32 100644
--- a/scene/2d/navigation_polygon.h
+++ b/scene/2d/navigation_polygon.h
@@ -57,8 +57,10 @@ protected:
Array _get_outlines() const;
public:
+#ifdef TOOLS_ENABLED
Rect2 _edit_get_rect() const;
bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
+#endif
void set_vertices(const PoolVector<Vector2> &p_vertices);
PoolVector<Vector2> get_vertices() const;
@@ -100,8 +102,10 @@ protected:
static void _bind_methods();
public:
+#ifdef TOOLS_ENABLED
virtual Rect2 _edit_get_rect() const;
virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
+#endif
void set_enabled(bool p_enabled);
bool is_enabled() const;
diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp
index ad04dc8d9e..7deebe9b27 100644
--- a/scene/2d/node_2d.cpp
+++ b/scene/2d/node_2d.cpp
@@ -35,6 +35,7 @@
#include "scene/main/viewport.h"
#include "servers/visual_server.h"
+#ifdef TOOLS_ENABLED
Dictionary Node2D::_edit_get_state() const {
Dictionary state;
@@ -44,6 +45,7 @@ Dictionary Node2D::_edit_get_state() const {
return state;
}
+
void Node2D::_edit_set_state(const Dictionary &p_state) {
pos = p_state["position"];
@@ -119,6 +121,7 @@ void Node2D::_edit_set_rect(const Rect2 &p_edit_rect) {
_change_notify("scale");
_change_notify("position");
}
+#endif
void Node2D::_update_xform_values() {
@@ -170,6 +173,7 @@ void Node2D::set_scale(const Size2 &p_scale) {
if (_xform_dirty)
((Node2D *)this)->_update_xform_values();
_scale = p_scale;
+ // Avoid having 0 scale values, can lead to errors in physics and rendering.
if (_scale.x == 0)
_scale.x = CMP_EPSILON;
if (_scale.y == 0)
diff --git a/scene/2d/node_2d.h b/scene/2d/node_2d.h
index a03ccc5a80..00202481a6 100644
--- a/scene/2d/node_2d.h
+++ b/scene/2d/node_2d.h
@@ -55,6 +55,7 @@ protected:
static void _bind_methods();
public:
+#ifdef TOOLS_ENABLED
virtual Dictionary _edit_get_state() const;
virtual void _edit_set_state(const Dictionary &p_state);
@@ -69,6 +70,7 @@ public:
virtual bool _edit_use_rotation() const;
virtual void _edit_set_rect(const Rect2 &p_edit_rect);
+#endif
void set_position(const Point2 &p_pos);
void set_rotation(float p_radians);
diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp
index e6ae95af89..6ae008548e 100644
--- a/scene/2d/path_2d.cpp
+++ b/scene/2d/path_2d.cpp
@@ -37,6 +37,7 @@
#include "editor/editor_scale.h"
#endif
+#ifdef TOOLS_ENABLED
Rect2 Path2D::_edit_get_rect() const {
if (!curve.is_valid() || curve->get_point_count() == 0)
@@ -85,6 +86,7 @@ bool Path2D::_edit_is_selected_on_click(const Point2 &p_point, double p_toleranc
return false;
}
+#endif
void Path2D::_notification(int p_what) {
@@ -258,7 +260,7 @@ void PathFollow2D::_validate_property(PropertyInfo &property) const {
if (path && path->get_curve().is_valid())
max = path->get_curve()->get_baked_length();
- property.hint_string = "0," + rtos(max) + ",0.01,or_lesser";
+ property.hint_string = "0," + rtos(max) + ",0.01,or_lesser,or_greater";
}
}
@@ -300,8 +302,8 @@ void PathFollow2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_lookahead", "lookahead"), &PathFollow2D::set_lookahead);
ClassDB::bind_method(D_METHOD("get_lookahead"), &PathFollow2D::get_lookahead);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "offset", PROPERTY_HINT_RANGE, "0,10000,0.01,or_lesser"), "set_offset", "get_offset");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "unit_offset", PROPERTY_HINT_RANGE, "0,1,0.0001,or_lesser", PROPERTY_USAGE_EDITOR), "set_unit_offset", "get_unit_offset");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "offset", PROPERTY_HINT_RANGE, "0,10000,0.01,or_lesser,or_greater"), "set_offset", "get_offset");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "unit_offset", PROPERTY_HINT_RANGE, "0,1,0.0001,or_lesser,or_greater", PROPERTY_USAGE_EDITOR), "set_unit_offset", "get_unit_offset");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "h_offset"), "set_h_offset", "get_h_offset");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "v_offset"), "set_v_offset", "get_v_offset");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "rotate"), "set_rotate", "is_rotating");
diff --git a/scene/2d/path_2d.h b/scene/2d/path_2d.h
index 21cb4374bd..35cf8211f4 100644
--- a/scene/2d/path_2d.h
+++ b/scene/2d/path_2d.h
@@ -47,9 +47,11 @@ protected:
static void _bind_methods();
public:
+#ifdef TOOLS_ENABLED
virtual Rect2 _edit_get_rect() const;
virtual bool _edit_use_rect() const;
virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
+#endif
void set_curve(const Ref<Curve2D> &p_curve);
Ref<Curve2D> get_curve() const;
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index 3fd0bef7e9..d42bd6adaf 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -1212,7 +1212,7 @@ bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_
//so, if you pass 45 as limit, avoid numerical precision errors when angle is 45.
#define FLOOR_ANGLE_THRESHOLD 0.01
-Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) {
+Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) {
Vector2 body_velocity = p_linear_velocity;
Vector2 body_velocity_normal = body_velocity.normalized();
@@ -1234,6 +1234,7 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const
on_ceiling = false;
on_wall = false;
colliders.clear();
+ floor_normal = Vector2();
floor_velocity = Vector2();
while (p_max_slides) {
@@ -1262,25 +1263,26 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const
colliders.push_back(collision);
motion = collision.remainder;
- if (p_floor_direction == Vector2()) {
+ if (p_up_direction == Vector2()) {
//all is a wall
on_wall = true;
} else {
- if (Math::acos(collision.normal.dot(p_floor_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor
+ if (Math::acos(collision.normal.dot(p_up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor
on_floor = true;
+ floor_normal = collision.normal;
on_floor_body = collision.collider_rid;
floor_velocity = collision.collider_vel;
if (p_stop_on_slope) {
- if ((body_velocity_normal + p_floor_direction).length() < 0.01 && collision.travel.length() < 1) {
+ if ((body_velocity_normal + p_up_direction).length() < 0.01 && collision.travel.length() < 1) {
Transform2D gt = get_global_transform();
- gt.elements[2] -= collision.travel.slide(p_floor_direction);
+ gt.elements[2] -= collision.travel.slide(p_up_direction);
set_global_transform(gt);
return Vector2();
}
}
- } else if (Math::acos(collision.normal.dot(-p_floor_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling
+ } else if (Math::acos(collision.normal.dot(-p_up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling
on_ceiling = true;
} else {
on_wall = true;
@@ -1301,11 +1303,11 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const
return body_velocity;
}
-Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_floor_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) {
+Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) {
bool was_on_floor = on_floor;
- Vector2 ret = move_and_slide(p_linear_velocity, p_floor_direction, p_stop_on_slope, p_max_slides, p_floor_max_angle, p_infinite_inertia);
+ Vector2 ret = move_and_slide(p_linear_velocity, p_up_direction, p_stop_on_slope, p_max_slides, p_floor_max_angle, p_infinite_inertia);
if (!was_on_floor || p_snap == Vector2()) {
return ret;
}
@@ -1315,15 +1317,16 @@ Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_veloci
if (move_and_collide(p_snap, p_infinite_inertia, col, false, true)) {
bool apply = true;
- if (p_floor_direction != Vector2()) {
- if (Math::acos(p_floor_direction.normalized().dot(col.normal)) < p_floor_max_angle) {
+ if (p_up_direction != Vector2()) {
+ if (Math::acos(p_up_direction.normalized().dot(col.normal)) < p_floor_max_angle) {
on_floor = true;
+ floor_normal = col.normal;
on_floor_body = col.collider_rid;
floor_velocity = col.collider_vel;
if (p_stop_on_slope) {
// move and collide may stray the object a bit because of pre un-stucking,
// so only ensure that motion happens on floor direction in this case.
- col.travel = p_floor_direction * p_floor_direction.dot(col.travel);
+ col.travel = p_up_direction * p_up_direction.dot(col.travel);
}
} else {
@@ -1353,6 +1356,11 @@ bool KinematicBody2D::is_on_ceiling() const {
return on_ceiling;
}
+Vector2 KinematicBody2D::get_floor_normal() const {
+
+ return floor_normal;
+}
+
Vector2 KinematicBody2D::get_floor_velocity() const {
return floor_velocity;
@@ -1465,14 +1473,15 @@ void KinematicBody2D::_notification(int p_what) {
void KinematicBody2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only"), &KinematicBody2D::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false));
- ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody2D::move_and_slide, DEFVAL(Vector2(0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true));
- ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "floor_normal", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody2D::move_and_slide_with_snap, DEFVAL(Vector2(0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody2D::move_and_slide, DEFVAL(Vector2(0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody2D::move_and_slide_with_snap, DEFVAL(Vector2(0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true));
ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "infinite_inertia"), &KinematicBody2D::test_move, DEFVAL(true));
ClassDB::bind_method(D_METHOD("is_on_floor"), &KinematicBody2D::is_on_floor);
ClassDB::bind_method(D_METHOD("is_on_ceiling"), &KinematicBody2D::is_on_ceiling);
ClassDB::bind_method(D_METHOD("is_on_wall"), &KinematicBody2D::is_on_wall);
+ ClassDB::bind_method(D_METHOD("get_floor_normal"), &KinematicBody2D::get_floor_normal);
ClassDB::bind_method(D_METHOD("get_floor_velocity"), &KinematicBody2D::get_floor_velocity);
ClassDB::bind_method(D_METHOD("set_safe_margin", "pixels"), &KinematicBody2D::set_safe_margin);
diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h
index 7f2b42b554..6766bafde3 100644
--- a/scene/2d/physics_body_2d.h
+++ b/scene/2d/physics_body_2d.h
@@ -306,6 +306,7 @@ public:
private:
float margin;
+ Vector2 floor_normal;
Vector2 floor_velocity;
RID on_floor_body;
bool on_floor;
@@ -339,11 +340,12 @@ public:
void set_safe_margin(float p_margin);
float get_safe_margin() const;
- Vector2 move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction = Vector2(0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true);
- Vector2 move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_floor_direction = Vector2(0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true);
+ Vector2 move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_up_direction = Vector2(0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true);
+ Vector2 move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_up_direction = Vector2(0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true);
bool is_on_floor() const;
bool is_on_wall() const;
bool is_on_ceiling() const;
+ Vector2 get_floor_normal() const;
Vector2 get_floor_velocity() const;
int get_slide_count() const;
diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp
index 7b03193fe0..a6da027e0a 100644
--- a/scene/2d/polygon_2d.cpp
+++ b/scene/2d/polygon_2d.cpp
@@ -33,6 +33,7 @@
#include "core/math/geometry.h"
#include "skeleton_2d.h"
+#ifdef TOOLS_ENABLED
Dictionary Polygon2D::_edit_get_state() const {
Dictionary state = Node2D::_edit_get_state();
state["offset"] = offset;
@@ -87,6 +88,7 @@ bool Polygon2D::_edit_is_selected_on_click(const Point2 &p_point, double p_toler
}
return Geometry::is_point_in_polygon(p_point - get_offset(), polygon2d);
}
+#endif
void Polygon2D::_skeleton_bone_setup_changed() {
update();
@@ -344,195 +346,6 @@ void Polygon2D::_notification(int p_what) {
if (total_indices.size()) {
VS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), total_indices, points, colors, uvs, bones, weights, texture.is_valid() ? texture->get_rid() : RID(), -1, RID(), antialiased);
}
-
-#if 0
- //use splits
- Vector<int> loop;
- int sc = splits.size();
- PoolVector<int>::Read r = splits.read();
-
-
- print_line("has splits, amount " + itos(splits.size()));
- Vector<Vector<int> > loops;
-
- // find a point that can be used to begin, must not be in a split, and have to the left and right the same one
- // like this one -> x---o
- // \ / \ .
- // o---o
- int base_point = -1;
- {
- int current_point = -1;
- int base_point_prev_split = -1;
-
-
- for (int i = 0; i < points.size(); i++) {
-
- //find if this point is in a split
- int split_index = -1;
- bool has_prev_split = false;
- int min_dist_to_end = 0x7FFFFFFF;
-
- for (int j = 0; j < sc; j += 2) {
-
- int split_pos = -1;
- int split_end = -1;
-
- if (r[j + 0] == i) { //found split in first point
- split_pos = r[j + 0];
- split_end = r[j + 1];
- } else if (r[j + 1] == i) { //found split in second point
- split_pos = r[j + 1];
- split_end = r[j + 0];
- }
-
- if (split_pos == split_end) {
- continue; //either nothing found or begin == end, this not a split in either case
- }
-
- if (j == base_point_prev_split) {
- has_prev_split = true;
- }
-
- //compute distance from split pos to split end in current traversal direction
- int dist_to_end = split_end > split_pos ? split_end - split_pos : (last - split_pos + split_end);
-
- if (dist_to_end < min_dist_to_end) {
- //always keep the valid split with the least distance to the loop
- min_dist_to_end = dist_to_end;
- split_index = j;
- }
- }
-
- if (split_index == -1) {
- current_point = i; //no split here, we are testing this point
- } else if (has_prev_split) {
- base_point = current_point; // there is a split and it contains the previous visited split, success
- break;
- } else {
- //invalidate current point and keep split
- current_point = -1;
- base_point_prev_split = split_index;
- }
- }
- }
-
- print_line("found base point: " + itos(base_point));
-
- if (base_point != -1) {
-
- int point = base_point;
- int last = base_point;
- //go through all the points, find splits
- do {
-
- int split;
- int last_dist_to_end = -1; //maximum valid distance to end
-
- do {
-
- loop.push_back(point); //push current point
-
- split = -1;
- int end = -1;
-
- int max_dist_to_end = 0;
-
- //find if this point is in a split
- for (int j = 0; j < sc; j += 2) {
-
- int split_pos = -1;
- int split_end = -1;
-
- if (r[j + 0] == point) { //match first split index
- split_pos = r[j + 0];
- split_end = r[j + 1];
- } else if (r[j + 1] == point) { //match second split index
- split_pos = r[j + 1];
- split_end = r[j + 0];
- }
-
- if (split_pos == split_end) {
- continue; //either nothing found or begin == end, this not a split in either case
- }
-
- //compute distance from split pos to split end
- int dist_to_end = split_end > split_pos ? split_end - split_pos : (points.size() - split_pos + split_end);
-
- if (last_dist_to_end != -1 && dist_to_end >= last_dist_to_end) {
- //distance must be shorter than in last iteration, means we've tested this before so ignore
- continue;
- } else if (dist_to_end > max_dist_to_end) {
- //always keep the valid point with the most distance (as long as it's valid)
- max_dist_to_end = dist_to_end;
- split = split_pos;
- end = split_end;
- }
- }
-
- if (split != -1) {
- //found a split!
- int from = end;
-
- //add points until last is reached
- while (true) {
- //find if point is in a split
- loop.push_back(from);
-
- if (from == last) {
- break;
- }
-
- from++;
- if (from >= points.size()) { //wrap if reached end
- from = 0;
- }
-
- if (from == loop[0]) {
- break; //end because we reached split source
- }
- }
-
- loops.push_back(loop); //done with this loop
- loop.clear();
-
- last_dist_to_end = max_dist_to_end;
- last = end; //algorithm can safely finish in this split point
- }
-
- } while (split != -1);
-
- } while (point != last);
- }
-
- if (loop.size() >=2 ) { //points remained
- //points remain
- loop.push_back(last); //no splits found, use last
- loops.push_back(loop);
- }
-
- print_line("total loops: " + itos(loops.size()));
-
- if (loops.size()) { //loops found
- Vector<int> indices;
-
- for (int i = 0; i < loops.size(); i++) {
- Vector<int> loop = loops[i];
- Vector<Vector2> vertices;
- vertices.resize(loop.size());
- for (int j = 0; j < vertices.size(); j++) {
- vertices.write[j] = points[loop[j]];
- }
- Vector<int> sub_indices = Geometry::triangulate_polygon(vertices);
- int from = indices.size();
- indices.resize(from + sub_indices.size());
- for (int j = 0; j < sub_indices.size(); j++) {
- indices.write[from + j] = loop[sub_indices[j]];
- }
- }
-
- VS::get_singleton()->canvas_item_add_triangle_array(get_canvas_item(), indices, points, colors, uvs, bones, weights, texture.is_valid() ? texture->get_rid() : RID());
- }
-#endif
}
} break;
diff --git a/scene/2d/polygon_2d.h b/scene/2d/polygon_2d.h
index 84ad221760..07b8828532 100644
--- a/scene/2d/polygon_2d.h
+++ b/scene/2d/polygon_2d.h
@@ -77,6 +77,7 @@ protected:
static void _bind_methods();
public:
+#ifdef TOOLS_ENABLED
virtual Dictionary _edit_get_state() const;
virtual void _edit_set_state(const Dictionary &p_state);
@@ -87,6 +88,7 @@ public:
virtual bool _edit_use_rect() const;
virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
+#endif
void set_polygon(const PoolVector<Vector2> &p_polygon);
PoolVector<Vector2> get_polygon() const;
diff --git a/scene/2d/position_2d.cpp b/scene/2d/position_2d.cpp
index 49ef92b861..cdeb905c0c 100644
--- a/scene/2d/position_2d.cpp
+++ b/scene/2d/position_2d.cpp
@@ -43,6 +43,7 @@ void Position2D::_draw_cross() {
draw_line(Point2(0, -extents), Point2(0, +extents), Color(0.53, 0.84, 0.01));
}
+#ifdef TOOLS_ENABLED
Rect2 Position2D::_edit_get_rect() const {
float extents = get_gizmo_extents();
@@ -52,6 +53,7 @@ Rect2 Position2D::_edit_get_rect() const {
bool Position2D::_edit_use_rect() const {
return false;
}
+#endif
void Position2D::_notification(int p_what) {
diff --git a/scene/2d/position_2d.h b/scene/2d/position_2d.h
index 711c4ec02f..3ea636171d 100644
--- a/scene/2d/position_2d.h
+++ b/scene/2d/position_2d.h
@@ -44,8 +44,10 @@ protected:
static void _bind_methods();
public:
+#ifdef TOOLS_ENABLED
virtual Rect2 _edit_get_rect() const;
virtual bool _edit_use_rect() const;
+#endif
void set_gizmo_extents(float p_extents);
float get_gizmo_extents() const;
diff --git a/scene/2d/sprite.cpp b/scene/2d/sprite.cpp
index 837444532c..55daed0585 100644
--- a/scene/2d/sprite.cpp
+++ b/scene/2d/sprite.cpp
@@ -34,6 +34,7 @@
#include "scene/main/viewport.h"
#include "scene/scene_string_names.h"
+#ifdef TOOLS_ENABLED
Dictionary Sprite::_edit_get_state() const {
Dictionary state = Node2D::_edit_get_state();
state["offset"] = offset;
@@ -58,6 +59,11 @@ bool Sprite::_edit_use_pivot() const {
return true;
}
+bool Sprite::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
+
+ return is_pixel_opaque(p_point);
+}
+
Rect2 Sprite::_edit_get_rect() const {
return get_rect();
}
@@ -65,6 +71,7 @@ Rect2 Sprite::_edit_get_rect() const {
bool Sprite::_edit_use_rect() const {
return texture.is_valid();
}
+#endif
Rect2 Sprite::get_anchorable_rect() const {
return get_rect();
@@ -305,11 +312,6 @@ int Sprite::get_hframes() const {
return hframes;
}
-bool Sprite::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
-
- return is_pixel_opaque(p_point);
-}
-
bool Sprite::is_pixel_opaque(const Point2 &p_point) const {
if (texture.is_null())
diff --git a/scene/2d/sprite.h b/scene/2d/sprite.h
index 2fd97f6611..d72bf3168d 100644
--- a/scene/2d/sprite.h
+++ b/scene/2d/sprite.h
@@ -67,6 +67,7 @@ protected:
virtual void _validate_property(PropertyInfo &property) const;
public:
+#ifdef TOOLS_ENABLED
virtual Dictionary _edit_get_state() const;
virtual void _edit_set_state(const Dictionary &p_state);
@@ -75,10 +76,11 @@ public:
virtual bool _edit_use_pivot() const;
virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
- bool is_pixel_opaque(const Point2 &p_point) const;
-
virtual Rect2 _edit_get_rect() const;
virtual bool _edit_use_rect() const;
+#endif
+
+ bool is_pixel_opaque(const Point2 &p_point) const;
void set_texture(const Ref<Texture> &p_texture);
Ref<Texture> get_texture() const;
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 04ec13e415..b6db025d44 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -1282,6 +1282,7 @@ PoolVector<int> TileMap::_get_tile_data() const {
return data;
}
+#ifdef TOOLS_ENABLED
Rect2 TileMap::_edit_get_rect() const {
if (pending_update) {
const_cast<TileMap *>(this)->update_dirty_quadrants();
@@ -1290,6 +1291,7 @@ Rect2 TileMap::_edit_get_rect() const {
}
return rect_cache;
}
+#endif
void TileMap::set_collision_layer(uint32_t p_layer) {
diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h
index 53bb696ba2..0875d197eb 100644
--- a/scene/2d/tile_map.h
+++ b/scene/2d/tile_map.h
@@ -244,7 +244,9 @@ public:
INVALID_CELL = -1
};
+#ifdef TOOLS_ENABLED
virtual Rect2 _edit_get_rect() const;
+#endif
void set_tileset(const Ref<TileSet> &p_tileset);
Ref<TileSet> get_tileset() const;
diff --git a/scene/2d/touch_screen_button.cpp b/scene/2d/touch_screen_button.cpp
index f6a888fa09..42d9f88a60 100644
--- a/scene/2d/touch_screen_button.cpp
+++ b/scene/2d/touch_screen_button.cpp
@@ -135,7 +135,9 @@ void TouchScreenButton::_notification(int p_what) {
return;
if (shape.is_valid()) {
Color draw_col = get_tree()->get_debug_collisions_color();
- Vector2 pos = shape_centered ? _edit_get_rect().size * 0.5f : Vector2();
+
+ Vector2 size = texture.is_null() ? shape->get_rect().size : texture->get_size();
+ Vector2 pos = shape_centered ? size * 0.5f : Vector2();
draw_set_transform_matrix(get_canvas_transform().translated(pos));
shape->draw(get_canvas_item(), draw_col);
}
@@ -251,9 +253,7 @@ void TouchScreenButton::_input(const Ref<InputEvent> &p_event) {
}
bool TouchScreenButton::_is_point_inside(const Point2 &p_point) {
-
Point2 coord = (get_global_transform_with_canvas()).affine_inverse().xform(p_point);
- Rect2 item_rect = _edit_get_rect();
bool touched = false;
bool check_rect = true;
@@ -261,7 +261,7 @@ bool TouchScreenButton::_is_point_inside(const Point2 &p_point) {
if (shape.is_valid()) {
check_rect = false;
- Transform2D xform = shape_centered ? Transform2D().translated(item_rect.size * 0.5f) : Transform2D();
+ Transform2D xform = shape_centered ? Transform2D().translated(shape->get_rect().size * 0.5f) : Transform2D();
touched = shape->collide(xform, unit_rect, Transform2D(0, coord + Vector2(0.5, 0.5)));
}
@@ -277,7 +277,7 @@ bool TouchScreenButton::_is_point_inside(const Point2 &p_point) {
if (!touched && check_rect) {
if (texture.is_valid())
- touched = item_rect.has_point(coord);
+ touched = Rect2(Size2(), texture->get_size()).has_point(coord);
}
return touched;
@@ -324,6 +324,7 @@ void TouchScreenButton::_release(bool p_exiting_tree) {
}
}
+#ifdef TOOLS_ENABLED
Rect2 TouchScreenButton::_edit_get_rect() const {
if (texture.is_null())
return CanvasItem::_edit_get_rect();
@@ -334,6 +335,7 @@ Rect2 TouchScreenButton::_edit_get_rect() const {
bool TouchScreenButton::_edit_use_rect() const {
return !texture.is_null();
}
+#endif
Rect2 TouchScreenButton::get_anchorable_rect() const {
if (texture.is_null())
diff --git a/scene/2d/touch_screen_button.h b/scene/2d/touch_screen_button.h
index 9c9fc6125a..28dba59402 100644
--- a/scene/2d/touch_screen_button.h
+++ b/scene/2d/touch_screen_button.h
@@ -74,6 +74,11 @@ protected:
static void _bind_methods();
public:
+#ifdef TOOLS_ENABLED
+ virtual Rect2 _edit_get_rect() const;
+ virtual bool _edit_use_rect() const;
+#endif
+
void set_texture(const Ref<Texture> &p_texture);
Ref<Texture> get_texture() const;
@@ -103,8 +108,6 @@ public:
bool is_pressed() const;
- virtual Rect2 _edit_get_rect() const;
- virtual bool _edit_use_rect() const;
virtual Rect2 get_anchorable_rect() const;
TouchScreenButton();
diff --git a/scene/2d/visibility_notifier_2d.cpp b/scene/2d/visibility_notifier_2d.cpp
index 223e57f39f..0ac725b7dd 100644
--- a/scene/2d/visibility_notifier_2d.cpp
+++ b/scene/2d/visibility_notifier_2d.cpp
@@ -38,6 +38,16 @@
#include "scene/main/viewport.h"
#include "scene/scene_string_names.h"
+#ifdef TOOLS_ENABLED
+Rect2 VisibilityNotifier2D::_edit_get_rect() const {
+ return rect;
+}
+
+bool VisibilityNotifier2D::_edit_use_rect() const {
+ return true;
+}
+#endif
+
void VisibilityNotifier2D::_enter_viewport(Viewport *p_viewport) {
ERR_FAIL_COND(viewports.has(p_viewport));
@@ -84,15 +94,6 @@ void VisibilityNotifier2D::set_rect(const Rect2 &p_rect) {
_change_notify("rect");
}
-Rect2 VisibilityNotifier2D::_edit_get_rect() const {
-
- return rect;
-}
-
-bool VisibilityNotifier2D::_edit_use_rect() const {
- return true;
-}
-
Rect2 VisibilityNotifier2D::get_rect() const {
return rect;
diff --git a/scene/2d/visibility_notifier_2d.h b/scene/2d/visibility_notifier_2d.h
index f9d4c238eb..a3b79d29e9 100644
--- a/scene/2d/visibility_notifier_2d.h
+++ b/scene/2d/visibility_notifier_2d.h
@@ -55,8 +55,10 @@ protected:
static void _bind_methods();
public:
+#ifdef TOOLS_ENABLED
virtual Rect2 _edit_get_rect() const;
virtual bool _edit_use_rect() const;
+#endif
void set_rect(const Rect2 &p_rect);
Rect2 get_rect() const;
diff --git a/scene/3d/arvr_nodes.cpp b/scene/3d/arvr_nodes.cpp
index 82293268b9..8d1556ef1c 100644
--- a/scene/3d/arvr_nodes.cpp
+++ b/scene/3d/arvr_nodes.cpp
@@ -85,9 +85,8 @@ Vector3 ARVRCamera::project_local_ray_normal(const Point2 &p_pos) const {
Vector3 ray;
CameraMatrix cm = arvr_interface->get_projection_for_eye(ARVRInterface::EYE_MONO, viewport_size.aspect(), get_znear(), get_zfar());
- float screen_w, screen_h;
- cm.get_viewport_size(screen_w, screen_h);
- ray = Vector3(((cpos.x / viewport_size.width) * 2.0 - 1.0) * screen_w, ((1.0 - (cpos.y / viewport_size.height)) * 2.0 - 1.0) * screen_h, -get_znear()).normalized();
+ Vector2 screen_he = cm.get_viewport_half_extents();
+ ray = Vector3(((cpos.x / viewport_size.width) * 2.0 - 1.0) * screen_he.x, ((1.0 - (cpos.y / viewport_size.height)) * 2.0 - 1.0) * screen_he.y, -get_znear()).normalized();
return ray;
};
@@ -138,13 +137,12 @@ Vector3 ARVRCamera::project_position(const Point2 &p_point, float p_z_depth) con
CameraMatrix cm = arvr_interface->get_projection_for_eye(ARVRInterface::EYE_MONO, viewport_size.aspect(), get_znear(), get_zfar());
- Size2 vp_size;
- cm.get_viewport_size(vp_size.x, vp_size.y);
+ Vector2 vp_he = cm.get_viewport_half_extents();
Vector2 point;
point.x = (p_point.x / viewport_size.x) * 2.0 - 1.0;
point.y = (1.0 - (p_point.y / viewport_size.y)) * 2.0 - 1.0;
- point *= vp_size;
+ point *= vp_he;
Vector3 p(point.x, point.y, -p_z_depth);
@@ -295,7 +293,8 @@ int ARVRController::get_joystick_id() const {
ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, controller_id);
if (tracker == NULL) {
- return 0;
+ // No tracker? no joystick id... (0 is our first joystick)
+ return -1;
};
return tracker->get_joy_id();
diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp
index 289dc0ba07..640189a26e 100644
--- a/scene/3d/camera.cpp
+++ b/scene/3d/camera.cpp
@@ -291,9 +291,8 @@ Vector3 Camera::project_local_ray_normal(const Point2 &p_pos) const {
} else {
CameraMatrix cm;
cm.set_perspective(fov, viewport_size.aspect(), near, far, keep_aspect == KEEP_WIDTH);
- float screen_w, screen_h;
- cm.get_viewport_size(screen_w, screen_h);
- ray = Vector3(((cpos.x / viewport_size.width) * 2.0 - 1.0) * screen_w, ((1.0 - (cpos.y / viewport_size.height)) * 2.0 - 1.0) * screen_h, -near).normalized();
+ Vector2 screen_he = cm.get_viewport_half_extents();
+ ray = Vector3(((cpos.x / viewport_size.width) * 2.0 - 1.0) * screen_he.x, ((1.0 - (cpos.y / viewport_size.height)) * 2.0 - 1.0) * screen_he.y, -near).normalized();
}
return ray;
@@ -398,17 +397,16 @@ Vector3 Camera::project_position(const Point2 &p_point, float p_z_depth) const {
CameraMatrix cm;
if (mode == PROJECTION_ORTHOGONAL)
- cm.set_orthogonal(size, viewport_size.aspect(), near, far, keep_aspect == KEEP_WIDTH);
+ cm.set_orthogonal(size, viewport_size.aspect(), p_z_depth, far, keep_aspect == KEEP_WIDTH);
else
- cm.set_perspective(fov, viewport_size.aspect(), near, far, keep_aspect == KEEP_WIDTH);
+ cm.set_perspective(fov, viewport_size.aspect(), p_z_depth, far, keep_aspect == KEEP_WIDTH);
- Size2 vp_size;
- cm.get_viewport_size(vp_size.x, vp_size.y);
+ Vector2 vp_he = cm.get_viewport_half_extents();
Vector2 point;
point.x = (p_point.x / viewport_size.x) * 2.0 - 1.0;
point.y = (1.0 - (p_point.y / viewport_size.y)) * 2.0 - 1.0;
- point *= vp_size;
+ point *= vp_he;
Vector3 p(point.x, point.y, -p_z_depth);
diff --git a/scene/3d/cpu_particles.cpp b/scene/3d/cpu_particles.cpp
index 0ac424b09e..aa7a413548 100644
--- a/scene/3d/cpu_particles.cpp
+++ b/scene/3d/cpu_particles.cpp
@@ -405,7 +405,7 @@ bool CPUParticles::get_particle_flag(Flags p_flag) const {
}
void CPUParticles::set_emission_shape(EmissionShape p_shape) {
-
+ ERR_FAIL_INDEX(p_shape, EMISSION_SHAPE_MAX);
emission_shape = p_shape;
}
@@ -784,6 +784,9 @@ void CPUParticles::_particles_process(float p_delta) {
p.base_color = emission_colors.get(random_idx);
}
} break;
+ case EMISSION_SHAPE_MAX: { // Max value for validity check.
+ break;
+ }
}
if (!local_coords) {
@@ -1488,6 +1491,7 @@ void CPUParticles::_bind_methods() {
BIND_ENUM_CONSTANT(EMISSION_SHAPE_BOX);
BIND_ENUM_CONSTANT(EMISSION_SHAPE_POINTS);
BIND_ENUM_CONSTANT(EMISSION_SHAPE_DIRECTED_POINTS);
+ BIND_ENUM_CONSTANT(EMISSION_SHAPE_MAX);
}
CPUParticles::CPUParticles() {
diff --git a/scene/3d/cpu_particles.h b/scene/3d/cpu_particles.h
index 18f9718e70..d5a549b976 100644
--- a/scene/3d/cpu_particles.h
+++ b/scene/3d/cpu_particles.h
@@ -75,6 +75,7 @@ public:
EMISSION_SHAPE_BOX,
EMISSION_SHAPE_POINTS,
EMISSION_SHAPE_DIRECTED_POINTS,
+ EMISSION_SHAPE_MAX
};
private:
diff --git a/scene/3d/path.cpp b/scene/3d/path.cpp
index 3ed0677480..ac012de1ab 100644
--- a/scene/3d/path.cpp
+++ b/scene/3d/path.cpp
@@ -253,7 +253,7 @@ void PathFollow::_validate_property(PropertyInfo &property) const {
if (path && path->get_curve().is_valid())
max = path->get_curve()->get_baked_length();
- property.hint_string = "0," + rtos(max) + ",0.01,or_lesser";
+ property.hint_string = "0," + rtos(max) + ",0.01,or_lesser,or_greater";
}
}
@@ -297,8 +297,8 @@ void PathFollow::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_loop", "loop"), &PathFollow::set_loop);
ClassDB::bind_method(D_METHOD("has_loop"), &PathFollow::has_loop);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "offset", PROPERTY_HINT_RANGE, "0,10000,0.01,or_lesser"), "set_offset", "get_offset");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "unit_offset", PROPERTY_HINT_RANGE, "0,1,0.0001,or_lesser", PROPERTY_USAGE_EDITOR), "set_unit_offset", "get_unit_offset");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "offset", PROPERTY_HINT_RANGE, "0,10000,0.01,or_lesser,or_greater"), "set_offset", "get_offset");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "unit_offset", PROPERTY_HINT_RANGE, "0,1,0.0001,or_lesser,or_greater", PROPERTY_USAGE_EDITOR), "set_unit_offset", "get_unit_offset");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "h_offset"), "set_h_offset", "get_h_offset");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "v_offset"), "set_v_offset", "get_v_offset");
ADD_PROPERTY(PropertyInfo(Variant::INT, "rotation_mode", PROPERTY_HINT_ENUM, "None,Y,XY,XYZ,Oriented"), "set_rotation_mode", "get_rotation_mode");
diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp
index c2860c25d8..caeae90238 100644
--- a/scene/3d/physics_body.cpp
+++ b/scene/3d/physics_body.cpp
@@ -1140,7 +1140,7 @@ bool KinematicBody::move_and_collide(const Vector3 &p_motion, bool p_infinite_in
//so, if you pass 45 as limit, avoid numerical precision errors when angle is 45.
#define FLOOR_ANGLE_THRESHOLD 0.01
-Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) {
+Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) {
Vector3 body_velocity = p_linear_velocity;
Vector3 body_velocity_normal = body_velocity.normalized();
@@ -1159,6 +1159,7 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve
on_ceiling = false;
on_wall = false;
colliders.clear();
+ floor_normal = Vector3();
floor_velocity = Vector3();
while (p_max_slides) {
@@ -1187,25 +1188,26 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve
colliders.push_back(collision);
motion = collision.remainder;
- if (p_floor_direction == Vector3()) {
+ if (p_up_direction == Vector3()) {
//all is a wall
on_wall = true;
} else {
- if (Math::acos(collision.normal.dot(p_floor_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor
+ if (Math::acos(collision.normal.dot(p_up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor
on_floor = true;
+ floor_normal = collision.normal;
on_floor_body = collision.collider_rid;
floor_velocity = collision.collider_vel;
if (p_stop_on_slope) {
- if ((body_velocity_normal + p_floor_direction).length() < 0.01 && collision.travel.length() < 1) {
+ if ((body_velocity_normal + p_up_direction).length() < 0.01 && collision.travel.length() < 1) {
Transform gt = get_global_transform();
- gt.origin -= collision.travel.slide(p_floor_direction);
+ gt.origin -= collision.travel.slide(p_up_direction);
set_global_transform(gt);
return Vector3();
}
}
- } else if (Math::acos(collision.normal.dot(-p_floor_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling
+ } else if (Math::acos(collision.normal.dot(-p_up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling
on_ceiling = true;
} else {
on_wall = true;
@@ -1232,11 +1234,11 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve
return body_velocity;
}
-Vector3 KinematicBody::move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_floor_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) {
+Vector3 KinematicBody::move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) {
bool was_on_floor = on_floor;
- Vector3 ret = move_and_slide(p_linear_velocity, p_floor_direction, p_stop_on_slope, p_max_slides, p_floor_max_angle, p_infinite_inertia);
+ Vector3 ret = move_and_slide(p_linear_velocity, p_up_direction, p_stop_on_slope, p_max_slides, p_floor_max_angle, p_infinite_inertia);
if (!was_on_floor || p_snap == Vector3()) {
return ret;
}
@@ -1247,15 +1249,16 @@ Vector3 KinematicBody::move_and_slide_with_snap(const Vector3 &p_linear_velocity
if (move_and_collide(p_snap, p_infinite_inertia, col, false, true)) {
bool apply = true;
- if (p_floor_direction != Vector3()) {
- if (Math::acos(p_floor_direction.normalized().dot(col.normal)) < p_floor_max_angle) {
+ if (p_up_direction != Vector3()) {
+ if (Math::acos(p_up_direction.normalized().dot(col.normal)) < p_floor_max_angle) {
on_floor = true;
+ floor_normal = col.normal;
on_floor_body = col.collider_rid;
floor_velocity = col.collider_vel;
if (p_stop_on_slope) {
// move and collide may stray the object a bit because of pre un-stucking,
// so only ensure that motion happens on floor direction in this case.
- col.travel = col.travel.project(p_floor_direction);
+ col.travel = col.travel.project(p_up_direction);
}
} else {
apply = false; //snapped with floor direction, but did not snap to a floor, do not snap.
@@ -1284,6 +1287,11 @@ bool KinematicBody::is_on_ceiling() const {
return on_ceiling;
}
+Vector3 KinematicBody::get_floor_normal() const {
+
+ return floor_normal;
+}
+
Vector3 KinematicBody::get_floor_velocity() const {
return floor_velocity;
@@ -1392,14 +1400,15 @@ void KinematicBody::_notification(int p_what) {
void KinematicBody::_bind_methods() {
ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only"), &KinematicBody::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false));
- ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody::move_and_slide, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true));
- ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "floor_normal", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody::move_and_slide_with_snap, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody::move_and_slide, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody::move_and_slide_with_snap, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true));
ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "infinite_inertia"), &KinematicBody::test_move, DEFVAL(true));
ClassDB::bind_method(D_METHOD("is_on_floor"), &KinematicBody::is_on_floor);
ClassDB::bind_method(D_METHOD("is_on_ceiling"), &KinematicBody::is_on_ceiling);
ClassDB::bind_method(D_METHOD("is_on_wall"), &KinematicBody::is_on_wall);
+ ClassDB::bind_method(D_METHOD("get_floor_normal"), &KinematicBody::get_floor_normal);
ClassDB::bind_method(D_METHOD("get_floor_velocity"), &KinematicBody::get_floor_velocity);
ClassDB::bind_method(D_METHOD("set_axis_lock", "axis", "lock"), &KinematicBody::set_axis_lock);
diff --git a/scene/3d/physics_body.h b/scene/3d/physics_body.h
index 06b31804b2..05bcbe22f0 100644
--- a/scene/3d/physics_body.h
+++ b/scene/3d/physics_body.h
@@ -300,6 +300,7 @@ private:
float margin;
+ Vector3 floor_normal;
Vector3 floor_velocity;
RID on_floor_body;
bool on_floor;
@@ -330,11 +331,12 @@ public:
void set_safe_margin(float p_margin);
float get_safe_margin() const;
- Vector3 move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction = Vector3(0, 0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true);
- Vector3 move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_floor_direction = Vector3(0, 0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true);
+ Vector3 move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_up_direction = Vector3(0, 0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true);
+ Vector3 move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_up_direction = Vector3(0, 0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true);
bool is_on_floor() const;
bool is_on_wall() const;
bool is_on_ceiling() const;
+ Vector3 get_floor_normal() const;
Vector3 get_floor_velocity() const;
int get_slide_count() const;
diff --git a/scene/3d/portal.cpp b/scene/3d/portal.cpp
deleted file mode 100644
index e60ca619dd..0000000000
--- a/scene/3d/portal.cpp
+++ /dev/null
@@ -1,232 +0,0 @@
-/*************************************************************************/
-/* portal.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "portal.h"
-#include "core/project_settings.h"
-#include "scene/resources/surface_tool.h"
-#include "servers/visual_server.h"
-
-// FIXME: This will be removed, kept as reference for new implementation
-#if 0
-bool Portal::_set(const StringName &p_name, const Variant &p_value) {
-
- if (p_name == "shape") {
- PoolVector<float> src_coords = p_value;
- Vector<Point2> points;
- int src_coords_size = src_coords.size();
- ERR_FAIL_COND_V(src_coords_size % 2, false);
- points.resize(src_coords_size / 2);
- for (int i = 0; i < points.size(); i++) {
-
- points[i].x = src_coords[i * 2 + 0];
- points[i].y = src_coords[i * 2 + 1];
- set_shape(points);
- }
- } else if (p_name == "enabled") {
- set_enabled(p_value);
- } else if (p_name == "disable_distance") {
- set_disable_distance(p_value);
- } else if (p_name == "disabled_color") {
- set_disabled_color(p_value);
- } else if (p_name == "connect_range") {
- set_connect_range(p_value);
- } else
- return false;
-
- return true;
-}
-
-bool Portal::_get(const StringName &p_name, Variant &r_ret) const {
-
- if (p_name == "shape") {
- Vector<Point2> points = get_shape();
- PoolVector<float> dst_coords;
- dst_coords.resize(points.size() * 2);
-
- for (int i = 0; i < points.size(); i++) {
-
- dst_coords.set(i * 2 + 0, points[i].x);
- dst_coords.set(i * 2 + 1, points[i].y);
- }
-
- r_ret = dst_coords;
- } else if (p_name == "enabled") {
- r_ret = is_enabled();
- } else if (p_name == "disable_distance") {
- r_ret = get_disable_distance();
- } else if (p_name == "disabled_color") {
- r_ret = get_disabled_color();
- } else if (p_name == "connect_range") {
- r_ret = get_connect_range();
- } else
- return false;
- return true;
-}
-
-void Portal::_get_property_list(List<PropertyInfo> *p_list) const {
-
- p_list->push_back(PropertyInfo(Variant::POOL_REAL_ARRAY, "shape"));
- p_list->push_back(PropertyInfo(Variant::BOOL, "enabled"));
- p_list->push_back(PropertyInfo(Variant::REAL, "disable_distance", PROPERTY_HINT_RANGE, "0,4096,0.01"));
- p_list->push_back(PropertyInfo(Variant::COLOR, "disabled_color"));
- p_list->push_back(PropertyInfo(Variant::REAL, "connect_range", PROPERTY_HINT_RANGE, "0.1,4096,0.01"));
-}
-
-AABB Portal::get_aabb() const {
-
- return aabb;
-}
-PoolVector<Face3> Portal::get_faces(uint32_t p_usage_flags) const {
-
- if (!(p_usage_flags & FACES_ENCLOSING))
- return PoolVector<Face3>();
-
- Vector<Point2> shape = get_shape();
- if (shape.size() == 0)
- return PoolVector<Face3>();
-
- Vector2 center;
- for (int i = 0; i < shape.size(); i++) {
-
- center += shape[i];
- }
-
- PoolVector<Face3> ret;
- center /= shape.size();
-
- for (int i = 0; i < shape.size(); i++) {
-
- int n = (i + 1) % shape.size();
-
- Face3 f;
- f.vertex[0] = Vector3(center.x, center.y, 0);
- f.vertex[1] = Vector3(shape[i].x, shape[i].y, 0);
- f.vertex[2] = Vector3(shape[n].x, shape[n].y, 0);
- ret.push_back(f);
- }
-
- return ret;
-}
-
-void Portal::set_shape(const Vector<Point2> &p_shape) {
-
- VisualServer::get_singleton()->portal_set_shape(portal, p_shape);
- shape = p_shape;
- update_gizmo();
-}
-
-Vector<Point2> Portal::get_shape() const {
-
- return shape;
-}
-
-void Portal::set_connect_range(float p_range) {
-
- connect_range = p_range;
- //VisualServer::get_singleton()->portal_set_connect_range(portal,p_range);
-}
-
-float Portal::get_connect_range() const {
-
- return connect_range;
-}
-
-void Portal::set_enabled(bool p_enabled) {
-
- enabled = p_enabled;
- VisualServer::get_singleton()->portal_set_enabled(portal, enabled);
-}
-
-bool Portal::is_enabled() const {
-
- return enabled;
-}
-
-void Portal::set_disable_distance(float p_distance) {
-
- disable_distance = p_distance;
- VisualServer::get_singleton()->portal_set_disable_distance(portal, disable_distance);
-}
-float Portal::get_disable_distance() const {
-
- return disable_distance;
-}
-
-void Portal::set_disabled_color(const Color &p_disabled_color) {
-
- disabled_color = p_disabled_color;
- VisualServer::get_singleton()->portal_set_disabled_color(portal, disabled_color);
-}
-
-Color Portal::get_disabled_color() const {
-
- return disabled_color;
-}
-
-void Portal::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("set_shape", "points"), &Portal::set_shape);
- ClassDB::bind_method(D_METHOD("get_shape"), &Portal::get_shape);
-
- ClassDB::bind_method(D_METHOD("set_enabled", "enable"), &Portal::set_enabled);
- ClassDB::bind_method(D_METHOD("is_enabled"), &Portal::is_enabled);
-
- ClassDB::bind_method(D_METHOD("set_disable_distance", "distance"), &Portal::set_disable_distance);
- ClassDB::bind_method(D_METHOD("get_disable_distance"), &Portal::get_disable_distance);
-
- ClassDB::bind_method(D_METHOD("set_disabled_color", "color"), &Portal::set_disabled_color);
- ClassDB::bind_method(D_METHOD("get_disabled_color"), &Portal::get_disabled_color);
-
- ClassDB::bind_method(D_METHOD("set_connect_range", "range"), &Portal::set_connect_range);
- ClassDB::bind_method(D_METHOD("get_connect_range"), &Portal::get_connect_range);
-}
-
-Portal::Portal() {
-
- portal = VisualServer::get_singleton()->portal_create();
- Vector<Point2> points;
- points.push_back(Point2(-1, 1));
- points.push_back(Point2(1, 1));
- points.push_back(Point2(1, -1));
- points.push_back(Point2(-1, -1));
- set_shape(points); // default shape
-
- set_connect_range(0.8);
- set_disable_distance(50);
- set_enabled(true);
-
- set_base(portal);
-}
-
-Portal::~Portal() {
-
- VisualServer::get_singleton()->free(portal);
-}
-#endif
diff --git a/scene/3d/portal.h b/scene/3d/portal.h
deleted file mode 100644
index 7e8b016e79..0000000000
--- a/scene/3d/portal.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*************************************************************************/
-/* portal.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef PORTAL_H
-#define PORTAL_H
-
-#include "scene/3d/visual_instance.h"
-
-/* Portal Logic:
- If a portal is placed next (very close to) a similar, opposing portal, they automatically connect,
- otherwise, a portal connects to the parent room
-*/
-// FIXME: This will be redone and replaced by area portals, left for reference
-// since a new class with this name will have to exist and want to reuse the gizmos
-#if 0
-class Portal : public VisualInstance {
-
- GDCLASS(Portal, VisualInstance);
-
- RID portal;
- Vector<Point2> shape;
-
- bool enabled;
- float disable_distance;
- Color disabled_color;
- float connect_range;
-
- AABB aabb;
-
-protected:
- bool _set(const StringName &p_name, const Variant &p_value);
- bool _get(const StringName &p_name, Variant &r_ret) const;
- void _get_property_list(List<PropertyInfo> *p_list) const;
-
- static void _bind_methods();
-
-public:
- virtual AABB get_aabb() const;
- virtual PoolVector<Face3> get_faces(uint32_t p_usage_flags) const;
-
- void set_enabled(bool p_enabled);
- bool is_enabled() const;
-
- void set_disable_distance(float p_distance);
- float get_disable_distance() const;
-
- void set_disabled_color(const Color &p_disabled_color);
- Color get_disabled_color() const;
-
- void set_shape(const Vector<Point2> &p_shape);
- Vector<Point2> get_shape() const;
-
- void set_connect_range(float p_range);
- float get_connect_range() const;
-
- Portal();
- ~Portal();
-};
-
-#endif
-#endif
diff --git a/scene/3d/room_instance.cpp b/scene/3d/room_instance.cpp
deleted file mode 100644
index 61687360a6..0000000000
--- a/scene/3d/room_instance.cpp
+++ /dev/null
@@ -1,164 +0,0 @@
-/*************************************************************************/
-/* room_instance.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "room_instance.h"
-
-#include "servers/visual_server.h"
-
-// FIXME: Will be removed, kept as reference for new implementation
-#if 0
-#include "core/math/geometry.h"
-#include "core/project_settings.h"
-#include "scene/resources/surface_tool.h"
-
-void Room::_notification(int p_what) {
-
- switch (p_what) {
- case NOTIFICATION_ENTER_WORLD: {
- // go find parent level
- Node *parent_room = get_parent();
- level = 0;
-
- while (parent_room) {
-
- Room *r = Object::cast_to<Room>(parent_room);
- if (r) {
-
- level = r->level + 1;
- break;
- }
-
- parent_room = parent_room->get_parent();
- }
-
- } break;
- case NOTIFICATION_TRANSFORM_CHANGED: {
- } break;
- case NOTIFICATION_EXIT_WORLD: {
-
- } break;
- }
-}
-
-AABB Room::get_aabb() const {
-
- if (room.is_null())
- return AABB();
-
- return AABB();
-}
-
-PoolVector<Face3> Room::get_faces(uint32_t p_usage_flags) const {
-
- return PoolVector<Face3>();
-}
-
-void Room::set_room(const Ref<RoomBounds> &p_room) {
-
- room = p_room;
- update_gizmo();
-
- if (room.is_valid()) {
-
- set_base(room->get_rid());
- } else {
- set_base(RID());
- }
-
- if (!is_inside_tree())
- return;
-
- propagate_notification(NOTIFICATION_AREA_CHANGED);
- update_gizmo();
-}
-
-Ref<RoomBounds> Room::get_room() const {
-
- return room;
-}
-
-void Room::_parse_node_faces(PoolVector<Face3> &all_faces, const Node *p_node) const {
-
- const VisualInstance *vi = Object::cast_to<VisualInstance>(p_node);
-
- if (vi) {
- PoolVector<Face3> faces = vi->get_faces(FACES_ENCLOSING);
-
- if (faces.size()) {
- int old_len = all_faces.size();
- all_faces.resize(all_faces.size() + faces.size());
- int new_len = all_faces.size();
- PoolVector<Face3>::Write all_facesw = all_faces.write();
- Face3 *all_facesptr = all_facesw.ptr();
-
- PoolVector<Face3>::Read facesr = faces.read();
- const Face3 *facesptr = facesr.ptr();
-
- Transform tr = vi->get_relative_transform(this);
-
- for (int i = old_len; i < new_len; i++) {
-
- Face3 f = facesptr[i - old_len];
- for (int j = 0; j < 3; j++)
- f.vertex[j] = tr.xform(f.vertex[j]);
- all_facesptr[i] = f;
- }
- }
- }
-
- for (int i = 0; i < p_node->get_child_count(); i++) {
-
- _parse_node_faces(all_faces, p_node->get_child(i));
- }
-}
-
-void Room::_bounds_changed() {
-
- update_gizmo();
-}
-
-void Room::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("set_room", "room"), &Room::set_room);
- ClassDB::bind_method(D_METHOD("get_room"), &Room::get_room);
-
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "room/room", PROPERTY_HINT_RESOURCE_TYPE, "Area"), "set_room", "get_room");
-}
-
-Room::Room() {
-
- // sound_enabled=false;
-
- level = 0;
-}
-
-Room::~Room() {
-}
-#endif
diff --git a/scene/3d/room_instance.h b/scene/3d/room_instance.h
deleted file mode 100644
index 071d42cff2..0000000000
--- a/scene/3d/room_instance.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*************************************************************************/
-/* room_instance.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef ROOM_INSTANCE_H
-#define ROOM_INSTANCE_H
-
-#include "scene/3d/visual_instance.h"
-#include "scene/resources/room.h"
-
-/* RoomInstance Logic:
- a) Instances that belong to the room are drawn only if the room is visible (seen through portal, or player inside)
- b) Instances that don't belong to any room are considered to belong to the root room (RID empty)
- c) "dynamic" Instances are assigned to the rooms their AABB touch
-
-*/
-
-// FIXME: this will be removed, left for reference
-#if 0
-
-class Room : public VisualInstance {
-
- GDCLASS(Room, VisualInstance);
-
-public:
-private:
- Ref<RoomBounds> room;
-
- int level;
- void _parse_node_faces(PoolVector<Face3> &all_faces, const Node *p_node) const;
-
- void _bounds_changed();
-
-protected:
- void _notification(int p_what);
-
- static void _bind_methods();
-
-public:
- enum {
- // used to notify portals that the room in which they are has changed.
- NOTIFICATION_AREA_CHANGED = 60
- };
-
- virtual AABB get_aabb() const;
- virtual PoolVector<Face3> get_faces(uint32_t p_usage_flags) const;
-
- void set_room(const Ref<RoomBounds> &p_room);
- Ref<RoomBounds> get_room() const;
-
- Room();
- ~Room();
-};
-#endif
-#endif // ROOM_INSTANCE_H
diff --git a/scene/3d/spatial.cpp b/scene/3d/spatial.cpp
index b7cd2114db..f1911348ce 100644
--- a/scene/3d/spatial.cpp
+++ b/scene/3d/spatial.cpp
@@ -125,6 +125,7 @@ void Spatial::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
+ ERR_FAIL_COND(!get_tree());
Node *p = get_parent();
if (p)
diff --git a/scene/3d/voxel_light_baker.cpp b/scene/3d/voxel_light_baker.cpp
index 9970b9350f..c1ec59d49f 100644
--- a/scene/3d/voxel_light_baker.cpp
+++ b/scene/3d/voxel_light_baker.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "voxel_light_baker.h"
+
#include "core/os/os.h"
#include "core/os/threaded_array_processor.h"
@@ -2118,8 +2119,7 @@ Error VoxelLightBaker::make_lightmap(const Transform &p_xform, Ref<Mesh> &p_mesh
}
}
-// Enable for debugging
-#if 0
+#if 0 // Enable for debugging.
{
PoolVector<uint8_t> img;
int ls = lightmap.size();
diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp
index a604fb9604..5c284cb483 100644
--- a/scene/animation/animation_blend_tree.cpp
+++ b/scene/animation/animation_blend_tree.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "animation_blend_tree.h"
+
#include "scene/scene_string_names.h"
void AnimationNodeAnimation::set_animation(const StringName &p_name) {
@@ -718,21 +719,6 @@ String AnimationNodeTransition::get_input_caption(int p_input) const {
return inputs[p_input].name;
}
-#if 0
- Ref<AnimationNodeBlendTree> tree = get_parent();
-
- if (tree.is_valid() && current >= 0) {
- prev = current;
- prev_xfading = xfade;
- time = 0;
- current = p_current;
- switched = true;
- _change_notify("current");
- } else {
- current = p_current;
- }
-#endif
-
void AnimationNodeTransition::set_cross_fade_time(float p_fade) {
xfade = p_fade;
}
@@ -846,8 +832,8 @@ void AnimationNodeTransition::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "xfade_time", PROPERTY_HINT_RANGE, "0,120,0.01"), "set_cross_fade_time", "get_cross_fade_time");
for (int i = 0; i < MAX_INPUTS; i++) {
- ADD_PROPERTYI(PropertyInfo(Variant::STRING, "input_" + itos(i) + "/name"), "set_input_caption", "get_input_caption", i);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "input_" + itos(i) + "/auto_advance"), "set_input_as_auto_advance", "is_input_set_as_auto_advance", i);
+ ADD_PROPERTYI(PropertyInfo(Variant::STRING, "input_" + itos(i) + "/name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "set_input_caption", "get_input_caption", i);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "input_" + itos(i) + "/auto_advance", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "set_input_as_auto_advance", "is_input_set_as_auto_advance", i);
}
}
diff --git a/scene/animation/skeleton_ik.cpp b/scene/animation/skeleton_ik.cpp
index 99a266af0d..46028a9ce2 100644
--- a/scene/animation/skeleton_ik.cpp
+++ b/scene/animation/skeleton_ik.cpp
@@ -320,7 +320,7 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool ove
new_bone_pose.basis = new_bone_pose.basis * p_task->chain.tips[0].end_effector->goal_transform.basis;
}
- p_task->skeleton->set_bone_global_pose_override(ci->bone, new_bone_pose, 1.0);
+ p_task->skeleton->set_bone_global_pose_override(ci->bone, new_bone_pose, 1.0, true);
if (!ci->children.empty())
ci = &ci->children.write[0];
@@ -329,6 +329,17 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool ove
}
}
+void FabrikInverseKinematic::reset(Task *p_task) {
+ ChainItem *ci(&p_task->chain.chain_root);
+ while (ci) {
+ p_task->skeleton->set_bone_global_pose_override(ci->bone, Transform(), 0);
+ if (!ci->children.empty())
+ ci = &ci->children.write[0];
+ else
+ ci = NULL;
+ }
+}
+
void SkeletonIK::_validate_property(PropertyInfo &property) const {
if (property.name == "root_bone" || property.name == "tip_bone") {
@@ -531,6 +542,8 @@ void SkeletonIK::start(bool p_one_time) {
void SkeletonIK::stop() {
set_process_internal(false);
+ if (task)
+ FabrikInverseKinematic::reset(task);
}
Transform SkeletonIK::_get_target_transform() {
diff --git a/scene/animation/skeleton_ik.h b/scene/animation/skeleton_ik.h
index 9ae010dc4e..8fc8a58b99 100644
--- a/scene/animation/skeleton_ik.h
+++ b/scene/animation/skeleton_ik.h
@@ -139,6 +139,7 @@ public:
static void set_goal(Task *p_task, const Transform &p_goal);
static void make_goal(Task *p_task, const Transform &p_inverse_transf, real_t blending_delta);
static void solve(Task *p_task, real_t blending_delta, bool override_tip_basis, bool p_use_magnet, const Vector3 &p_magnet_position);
+ static void reset(Task *p_task);
};
class SkeletonIK : public Node {
diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp
index 58212335c2..331a6c769c 100644
--- a/scene/animation/tween.cpp
+++ b/scene/animation/tween.cpp
@@ -827,6 +827,7 @@ bool Tween::start() {
// Are there any pending updates?
if (pending_update != 0) {
// Start the tweens after deferring
+ call_deferred("start");
return true;
}
diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp
index 65912c1c07..b2020d44e8 100644
--- a/scene/gui/base_button.cpp
+++ b/scene/gui/base_button.cpp
@@ -165,7 +165,7 @@ void BaseButton::on_action_event(Ref<InputEvent> p_event) {
_pressed();
}
} else {
- if (!p_event->is_pressed()) {
+ if ((p_event->is_pressed() && action_mode == ACTION_MODE_BUTTON_PRESS) || (!p_event->is_pressed() && action_mode == ACTION_MODE_BUTTON_RELEASE)) {
_pressed();
}
}
diff --git a/scene/gui/center_container.cpp b/scene/gui/center_container.cpp
index 9f4353ceb6..64d6885bc8 100644
--- a/scene/gui/center_container.cpp
+++ b/scene/gui/center_container.cpp
@@ -54,7 +54,13 @@ Size2 CenterContainer::get_minimum_size() const {
void CenterContainer::set_use_top_left(bool p_enable) {
+ if (use_top_left == p_enable) {
+ return;
+ }
+
use_top_left = p_enable;
+
+ minimum_size_changed();
queue_sort();
}
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index 5e656eea70..ae48a1356e 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -47,6 +47,7 @@
#include "editor/plugins/canvas_item_editor_plugin.h"
#endif
+#ifdef TOOLS_ENABLED
Dictionary Control::_edit_get_state() const {
Dictionary s;
@@ -155,6 +156,11 @@ bool Control::_edit_use_pivot() const {
return true;
}
+Size2 Control::_edit_get_minimum_size() const {
+ return get_combined_minimum_size();
+}
+#endif
+
void Control::set_custom_minimum_size(const Size2 &p_custom) {
if (p_custom == data.custom_minimum_size)
@@ -193,11 +199,6 @@ Size2 Control::get_combined_minimum_size() const {
return data.minimum_size_cache;
}
-Size2 Control::_edit_get_minimum_size() const {
-
- return get_combined_minimum_size();
-}
-
Transform2D Control::_get_internal_transform() const {
Transform2D rot_scale;
@@ -2474,9 +2475,9 @@ void Control::_window_find_focus_neighbour(const Vector2 &p_dir, Node *p_at, con
Transform2D xform = c->get_global_transform();
points[0] = xform.xform(Point2());
- points[1] = xform.xform(Point2(get_size().x, 0));
- points[2] = xform.xform(get_size());
- points[3] = xform.xform(Point2(0, get_size().y));
+ points[1] = xform.xform(Point2(c->get_size().x, 0));
+ points[2] = xform.xform(c->get_size());
+ points[3] = xform.xform(Point2(0, c->get_size().y));
float min = 1e7;
@@ -2681,6 +2682,11 @@ Vector2 Control::get_pivot_offset() const {
void Control::set_scale(const Vector2 &p_scale) {
data.scale = p_scale;
+ // Avoid having 0 scale values, can lead to errors in physics and rendering.
+ if (data.scale.x == 0)
+ data.scale.x = CMP_EPSILON;
+ if (data.scale.y == 0)
+ data.scale.y = CMP_EPSILON;
update();
_notify_transform();
}
diff --git a/scene/gui/control.h b/scene/gui/control.h
index a9831b9793..357858beb6 100644
--- a/scene/gui/control.h
+++ b/scene/gui/control.h
@@ -279,6 +279,7 @@ public:
};
/* EDITOR */
+#ifdef TOOLS_ENABLED
virtual Dictionary _edit_get_state() const;
virtual void _edit_set_state(const Dictionary &p_state);
@@ -301,6 +302,7 @@ public:
virtual bool _edit_use_pivot() const;
virtual Size2 _edit_get_minimum_size() const;
+#endif
void accept_event();
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index d1650fea1e..00ce57eb04 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -200,6 +200,13 @@ void GraphEdit::_update_scroll() {
else
v_scroll->show();
+ Size2 hmin = h_scroll->get_combined_minimum_size();
+ Size2 vmin = v_scroll->get_combined_minimum_size();
+
+ // Avoid scrollbar overlapping.
+ h_scroll->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, v_scroll->is_visible() ? -vmin.width : 0);
+ v_scroll->set_anchor_and_margin(MARGIN_BOTTOM, ANCHOR_END, h_scroll->is_visible() ? -hmin.height : 0);
+
set_block_minimum_size_adjust(false);
if (!awaiting_scroll_offset_update) {
@@ -286,15 +293,15 @@ void GraphEdit::_notification(int p_what) {
Size2 hmin = h_scroll->get_combined_minimum_size();
Size2 vmin = v_scroll->get_combined_minimum_size();
- v_scroll->set_anchor_and_margin(MARGIN_LEFT, ANCHOR_END, -vmin.width);
- v_scroll->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, 0);
- v_scroll->set_anchor_and_margin(MARGIN_TOP, ANCHOR_BEGIN, 0);
- v_scroll->set_anchor_and_margin(MARGIN_BOTTOM, ANCHOR_END, 0);
-
h_scroll->set_anchor_and_margin(MARGIN_LEFT, ANCHOR_BEGIN, 0);
h_scroll->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, 0);
h_scroll->set_anchor_and_margin(MARGIN_TOP, ANCHOR_END, -hmin.height);
h_scroll->set_anchor_and_margin(MARGIN_BOTTOM, ANCHOR_END, 0);
+
+ v_scroll->set_anchor_and_margin(MARGIN_LEFT, ANCHOR_END, -vmin.width);
+ v_scroll->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, 0);
+ v_scroll->set_anchor_and_margin(MARGIN_TOP, ANCHOR_BEGIN, 0);
+ v_scroll->set_anchor_and_margin(MARGIN_BOTTOM, ANCHOR_END, 0);
}
if (p_what == NOTIFICATION_DRAW) {
@@ -777,14 +784,8 @@ void GraphEdit::_top_layer_draw() {
}
if (box_selecting) {
- top_layer->draw_rect(
- box_selecting_rect,
- get_color("box_selection_fill_color", "Editor"));
-
- top_layer->draw_rect(
- box_selecting_rect,
- get_color("box_selection_stroke_color", "Editor"),
- false);
+ top_layer->draw_rect(box_selecting_rect, get_color("selection_fill"));
+ top_layer->draw_rect(box_selecting_rect, get_color("selection_stroke"), false);
}
}
@@ -1358,6 +1359,7 @@ GraphEdit::GraphEdit() {
v_scroll = memnew(VScrollBar);
v_scroll->set_name("_v_scroll");
top_layer->add_child(v_scroll);
+
updating = false;
connecting = false;
right_disconnects = false;
diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp
index 2a812caf9a..526950dbb3 100644
--- a/scene/gui/item_list.cpp
+++ b/scene/gui/item_list.cpp
@@ -993,7 +993,7 @@ void ItemList::_notification(int p_what) {
}
//ensure_selected_visible needs to be checked before we draw the list.
- if (ensure_selected_visible && current >= 0 && current <= items.size()) {
+ if (ensure_selected_visible && current >= 0 && current < items.size()) {
Rect2 r = items[current].rect_cache;
int from = scroll_bar->get_value();
diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp
index fa795361a8..9b542cb179 100644
--- a/scene/gui/label.cpp
+++ b/scene/gui/label.cpp
@@ -35,9 +35,17 @@
void Label::set_autowrap(bool p_autowrap) {
+ if (autowrap == p_autowrap) {
+ return;
+ }
+
autowrap = p_autowrap;
word_cache_dirty = true;
update();
+
+ if (clip) {
+ minimum_size_changed();
+ }
}
bool Label::has_autowrap() const {
@@ -103,8 +111,7 @@ void Label::_notification(int p_what) {
int lines_visible = (size.y + line_spacing) / font_h;
- // ceiling to ensure autowrapping does not cut text
- int space_w = Math::ceil(font->get_char_size(' ').width);
+ real_t space_w = font->get_char_size(' ').width;
int chars_total = 0;
int vbegin = 0, vsep = 0;
@@ -390,10 +397,9 @@ void Label::regenerate_word_cache() {
real_t current_word_size = 0;
int word_pos = 0;
- int line_width = 0;
+ real_t line_width = 0;
int space_count = 0;
- // ceiling to ensure autowrapping does not cut text
- int space_width = Math::ceil(font->get_char_size(' ').width);
+ real_t space_width = font->get_char_size(' ').width;
int line_spacing = get_constant("line_spacing");
line_count = 1;
total_char_cache = 0;
@@ -454,10 +460,9 @@ void Label::regenerate_word_cache() {
if (current_word_size == 0) {
word_pos = i;
}
- // ceiling to ensure autowrapping does not cut text
char_width = font->get_char_size(current, xl_text[i + 1]).width;
current_word_size += char_width;
- line_width += Math::ceil(char_width);
+ line_width += char_width;
total_char_cache++;
// allow autowrap to cut words when they exceed line width
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index 8f5f6beac3..7afc3b0d00 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -128,7 +128,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
selection.doubleclick = false;
if (OS::get_singleton()->has_virtual_keyboard())
- OS::get_singleton()->show_virtual_keyboard(text, get_global_rect());
+ OS::get_singleton()->show_virtual_keyboard(text, get_global_rect(), max_length);
}
update();
@@ -557,8 +557,11 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
if (editable) {
selection_delete();
CharType ucodestr[2] = { (CharType)k->get_unicode(), 0 };
+ int prev_len = text.length();
append_at_cursor(ucodestr);
- _text_changed();
+ if (text.length() != prev_len) {
+ _text_changed();
+ }
accept_event();
}
@@ -910,7 +913,7 @@ void LineEdit::_notification(int p_what) {
OS::get_singleton()->set_ime_position(get_global_position() + cursor_pos);
if (OS::get_singleton()->has_virtual_keyboard())
- OS::get_singleton()->show_virtual_keyboard(text, get_global_rect());
+ OS::get_singleton()->show_virtual_keyboard(text, get_global_rect(), max_length);
} break;
case NOTIFICATION_FOCUS_EXIT: {
@@ -961,11 +964,12 @@ void LineEdit::paste_text() {
if (paste_buffer != "") {
+ int prev_len = text.length();
if (selection.enabled) selection_delete();
append_at_cursor(paste_buffer);
if (!text_changed_dirty) {
- if (is_inside_tree()) {
+ if (is_inside_tree() && text.length() != prev_len) {
MessageQueue::get_singleton()->push_call(this, "_text_changed");
}
text_changed_dirty = true;
@@ -1189,7 +1193,7 @@ void LineEdit::delete_char() {
set_cursor_position(get_cursor_position() - 1);
if (align == ALIGN_CENTER || align == ALIGN_RIGHT) {
- window_pos = CLAMP(window_pos - 1, 0, text.length() - 1);
+ window_pos = CLAMP(window_pos - 1, 0, MAX(text.length() - 1, 0));
}
_text_changed();
@@ -1220,7 +1224,7 @@ void LineEdit::delete_text(int p_from_column, int p_to_column) {
}
if (align == ALIGN_CENTER || align == ALIGN_RIGHT) {
- window_pos = CLAMP(window_pos - (p_to_column - p_from_column), 0, text.length() - 1);
+ window_pos = CLAMP(window_pos - (p_to_column - p_from_column), 0, MAX(text.length() - 1, 0));
}
if (!text_changed_dirty) {
@@ -1235,6 +1239,11 @@ void LineEdit::set_text(String p_text) {
clear_internal();
append_at_cursor(p_text);
+
+ if (expand_to_text_length) {
+ minimum_size_changed();
+ }
+
update();
cursor_pos = 0;
window_pos = 0;
@@ -1362,6 +1371,8 @@ void LineEdit::append_at_cursor(String p_text) {
String post = text.substr(cursor_pos, text.length() - cursor_pos);
text = pre + p_text + post;
set_cursor_position(cursor_pos + p_text.length());
+ } else {
+ emit_signal("text_change_rejected");
}
}
@@ -1476,6 +1487,7 @@ void LineEdit::set_editable(bool p_editable) {
editable = p_editable;
_generate_context_menu();
+ minimum_size_changed();
update();
}
@@ -1611,7 +1623,11 @@ bool LineEdit::get_expand_to_text_length() const {
}
void LineEdit::set_clear_button_enabled(bool p_enabled) {
+ if (clear_button_enabled == p_enabled) {
+ return;
+ }
clear_button_enabled = p_enabled;
+ minimum_size_changed();
update();
}
@@ -1647,6 +1663,7 @@ void LineEdit::set_right_icon(const Ref<Texture> &p_icon) {
return;
}
right_icon = p_icon;
+ minimum_size_changed();
update();
}
@@ -1781,6 +1798,7 @@ void LineEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_right_icon"), &LineEdit::get_right_icon);
ADD_SIGNAL(MethodInfo("text_changed", PropertyInfo(Variant::STRING, "new_text")));
+ ADD_SIGNAL(MethodInfo("text_change_rejected"));
ADD_SIGNAL(MethodInfo("text_entered", PropertyInfo(Variant::STRING, "new_text")));
BIND_ENUM_CONSTANT(ALIGN_LEFT);
diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp
index 8598a953b4..3f46afa8e8 100644
--- a/scene/gui/option_button.cpp
+++ b/scene/gui/option_button.cpp
@@ -36,7 +36,14 @@ Size2 OptionButton::get_minimum_size() const {
Size2 minsize = Button::get_minimum_size();
if (has_icon("arrow")) {
- minsize.width += Control::get_icon("arrow")->get_width() + get_constant("hseparation");
+ const Size2 padding = get_stylebox("normal")->get_minimum_size();
+ const Size2 arrow_size = Control::get_icon("arrow")->get_size();
+
+ Size2 content_size = minsize - padding;
+ content_size.width += arrow_size.width + get_constant("hseparation");
+ content_size.height = MAX(content_size.height, arrow_size.height);
+
+ minsize = content_size + padding;
}
return minsize;
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 5b7d7403ae..6c2928c65c 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -253,24 +253,25 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
} \
}
-#define ENSURE_WIDTH(m_width) \
- if (p_mode == PROCESS_CACHE) { \
- l.maximum_width = MAX(l.maximum_width, MIN(p_width, wofs + m_width)); \
- l.minimum_width = MAX(l.minimum_width, m_width); \
- } \
- if (wofs + m_width > p_width) { \
- line_wrapped = true; \
- if (p_mode == PROCESS_CACHE) { \
- if (spaces > 0) \
- spaces -= 1; \
- } \
- if (p_mode == PROCESS_POINTER && r_click_item && p_click_pos.y >= p_ofs.y + y && p_click_pos.y <= p_ofs.y + y + lh && p_click_pos.x > p_ofs.x + wofs) { \
- if (r_outside) *r_outside = true; \
- *r_click_item = it; \
- *r_click_char = rchar; \
- RETURN; \
- } \
- NEW_LINE \
+#define ENSURE_WIDTH(m_width) \
+ if (p_mode == PROCESS_CACHE) { \
+ l.maximum_width = MAX(l.maximum_width, MIN(p_width, wofs + m_width)); \
+ l.minimum_width = MAX(l.minimum_width, m_width); \
+ } \
+ if (wofs + m_width > p_width) { \
+ line_wrapped = true; \
+ if (p_mode == PROCESS_CACHE) { \
+ if (spaces > 0) \
+ spaces -= 1; \
+ } \
+ const bool x_in_range = (p_click_pos.x > p_ofs.x + wofs) && (!p_frame->cell || p_click_pos.x < p_ofs.x + p_width); \
+ if (p_mode == PROCESS_POINTER && r_click_item && p_click_pos.y >= p_ofs.y + y && p_click_pos.y <= p_ofs.y + y + lh && x_in_range) { \
+ if (r_outside) *r_outside = true; \
+ *r_click_item = it; \
+ *r_click_char = rchar; \
+ RETURN; \
+ } \
+ NEW_LINE \
}
#define ADVANCE(m_width) \
@@ -934,6 +935,14 @@ void RichTextLabel::_notification(int p_what) {
switch (p_what) {
+ case NOTIFICATION_MOUSE_EXIT: {
+ if (meta_hovering) {
+ meta_hovering = NULL;
+ emit_signal("meta_hover_ended", current_meta);
+ current_meta = false;
+ update();
+ }
+ } break;
case NOTIFICATION_RESIZED: {
main->first_invalid_line = 0; //invalidate ALL
@@ -1063,10 +1072,10 @@ Control::CursorShape RichTextLabel::get_cursor_shape(const Point2 &p_pos) const
int line = 0;
Item *item = NULL;
+ bool outside;
+ ((RichTextLabel *)(this))->_find_click(main, p_pos, &item, &line, &outside);
- ((RichTextLabel *)(this))->_find_click(main, p_pos, &item, &line);
-
- if (item && ((RichTextLabel *)(this))->_find_meta(item, NULL))
+ if (item && !outside && ((RichTextLabel *)(this))->_find_meta(item, NULL))
return CURSOR_POINTING_HAND;
return CURSOR_ARROW;
diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp
index dc1183df74..509e6d19f6 100644
--- a/scene/gui/scroll_container.cpp
+++ b/scene/gui/scroll_container.cpp
@@ -219,16 +219,16 @@ void ScrollContainer::_update_scrollbar_position() {
Size2 hmin = h_scroll->get_combined_minimum_size();
Size2 vmin = v_scroll->get_combined_minimum_size();
- v_scroll->set_anchor_and_margin(MARGIN_LEFT, ANCHOR_END, -vmin.width);
- v_scroll->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, 0);
- v_scroll->set_anchor_and_margin(MARGIN_TOP, ANCHOR_BEGIN, 0);
- v_scroll->set_anchor_and_margin(MARGIN_BOTTOM, ANCHOR_END, 0);
-
h_scroll->set_anchor_and_margin(MARGIN_LEFT, ANCHOR_BEGIN, 0);
h_scroll->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, 0);
h_scroll->set_anchor_and_margin(MARGIN_TOP, ANCHOR_END, -hmin.height);
h_scroll->set_anchor_and_margin(MARGIN_BOTTOM, ANCHOR_END, 0);
+ v_scroll->set_anchor_and_margin(MARGIN_LEFT, ANCHOR_END, -vmin.width);
+ v_scroll->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, 0);
+ v_scroll->set_anchor_and_margin(MARGIN_TOP, ANCHOR_BEGIN, 0);
+ v_scroll->set_anchor_and_margin(MARGIN_BOTTOM, ANCHOR_END, 0);
+
h_scroll->raise();
v_scroll->raise();
}
@@ -317,6 +317,7 @@ void ScrollContainer::_notification(int p_what) {
r.position += ofs;
fit_child_in_rect(c, r);
}
+
update();
};
@@ -408,13 +409,17 @@ void ScrollContainer::update_scrollbars() {
Size2 hmin;
Size2 vmin;
- if (scroll_h) hmin = h_scroll->get_combined_minimum_size();
- if (scroll_v) vmin = v_scroll->get_combined_minimum_size();
+ if (scroll_h) {
+ hmin = h_scroll->get_combined_minimum_size();
+ }
+ if (scroll_v) {
+ vmin = v_scroll->get_combined_minimum_size();
+ }
Size2 min = child_max_size;
- bool hide_scroll_v = !scroll_v || min.height <= size.height - hmin.height;
- bool hide_scroll_h = !scroll_h || min.width <= size.width - vmin.width;
+ bool hide_scroll_v = !scroll_v || min.height <= size.height;
+ bool hide_scroll_h = !scroll_h || min.width <= size.width;
if (hide_scroll_v) {
@@ -449,6 +454,10 @@ void ScrollContainer::update_scrollbars() {
scroll.x = h_scroll->get_value();
}
+
+ // Avoid scrollbar overlapping.
+ h_scroll->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, hide_scroll_v ? 0 : -vmin.width);
+ v_scroll->set_anchor_and_margin(MARGIN_BOTTOM, ANCHOR_END, hide_scroll_h ? 0 : -hmin.height);
}
void ScrollContainer::_scroll_moved(float) {
@@ -461,8 +470,12 @@ void ScrollContainer::_scroll_moved(float) {
};
void ScrollContainer::set_enable_h_scroll(bool p_enable) {
+ if (scroll_h == p_enable) {
+ return;
+ }
scroll_h = p_enable;
+ minimum_size_changed();
queue_sort();
}
@@ -472,8 +485,12 @@ bool ScrollContainer::is_h_scroll_enabled() const {
}
void ScrollContainer::set_enable_v_scroll(bool p_enable) {
+ if (scroll_v == p_enable) {
+ return;
+ }
scroll_v = p_enable;
+ minimum_size_changed();
queue_sort();
}
@@ -593,12 +610,11 @@ ScrollContainer::ScrollContainer() {
h_scroll = memnew(HScrollBar);
h_scroll->set_name("_h_scroll");
add_child(h_scroll);
+ h_scroll->connect("value_changed", this, "_scroll_moved");
v_scroll = memnew(VScrollBar);
v_scroll->set_name("_v_scroll");
add_child(v_scroll);
-
- h_scroll->connect("value_changed", this, "_scroll_moved");
v_scroll->connect("value_changed", this, "_scroll_moved");
drag_speed = Vector2();
diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp
index d5da35955c..92377949f8 100644
--- a/scene/gui/spin_box.cpp
+++ b/scene/gui/spin_box.cpp
@@ -259,6 +259,10 @@ bool SpinBox::is_editable() const {
return line_edit->is_editable();
}
+void SpinBox::apply() {
+ _text_entered(line_edit->get_text());
+}
+
void SpinBox::_bind_methods() {
//ClassDB::bind_method(D_METHOD("_value_changed"),&SpinBox::_value_changed);
@@ -272,6 +276,7 @@ void SpinBox::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_prefix"), &SpinBox::get_prefix);
ClassDB::bind_method(D_METHOD("set_editable", "editable"), &SpinBox::set_editable);
ClassDB::bind_method(D_METHOD("is_editable"), &SpinBox::is_editable);
+ ClassDB::bind_method(D_METHOD("apply"), &SpinBox::apply);
ClassDB::bind_method(D_METHOD("_line_edit_focus_exit"), &SpinBox::_line_edit_focus_exit);
ClassDB::bind_method(D_METHOD("get_line_edit"), &SpinBox::get_line_edit);
ClassDB::bind_method(D_METHOD("_line_edit_input"), &SpinBox::_line_edit_input);
diff --git a/scene/gui/spin_box.h b/scene/gui/spin_box.h
index 13ba168ef3..04491c8477 100644
--- a/scene/gui/spin_box.h
+++ b/scene/gui/spin_box.h
@@ -88,6 +88,8 @@ public:
void set_prefix(const String &p_prefix);
String get_prefix() const;
+ void apply();
+
SpinBox();
};
diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp
index c3ddc41813..b045ff4fe1 100644
--- a/scene/gui/tab_container.cpp
+++ b/scene/gui/tab_container.cpp
@@ -785,23 +785,25 @@ TabContainer::TabAlign TabContainer::get_tab_align() const {
return align;
}
-void TabContainer::set_tabs_visible(bool p_visibe) {
+void TabContainer::set_tabs_visible(bool p_visible) {
- if (p_visibe == tabs_visible)
+ if (p_visible == tabs_visible)
return;
- tabs_visible = p_visibe;
+ tabs_visible = p_visible;
Vector<Control *> tabs = _get_tabs();
for (int i = 0; i < tabs.size(); i++) {
Control *c = tabs[i];
- if (p_visibe)
+ if (p_visible)
c->set_margin(MARGIN_TOP, _get_top_margin());
else
c->set_margin(MARGIN_TOP, 0);
}
+
update();
+ minimum_size_changed();
}
bool TabContainer::are_tabs_visible() const {
@@ -936,8 +938,10 @@ Size2 TabContainer::get_minimum_size() const {
Ref<StyleBox> tab_disabled = get_stylebox("tab_disabled");
Ref<Font> font = get_font("font");
- ms.y += MAX(MAX(tab_bg->get_minimum_size().y, tab_fg->get_minimum_size().y), tab_disabled->get_minimum_size().y);
- ms.y += font->get_height();
+ if (tabs_visible) {
+ ms.y += MAX(MAX(tab_bg->get_minimum_size().y, tab_fg->get_minimum_size().y), tab_disabled->get_minimum_size().y);
+ ms.y += font->get_height();
+ }
Ref<StyleBox> sb = get_stylebox("panel");
ms += sb->get_minimum_size();
diff --git a/scene/gui/tab_container.h b/scene/gui/tab_container.h
index e69c2ae289..c5a9045ca6 100644
--- a/scene/gui/tab_container.h
+++ b/scene/gui/tab_container.h
@@ -87,7 +87,7 @@ public:
void set_tab_align(TabAlign p_align);
TabAlign get_tab_align() const;
- void set_tabs_visible(bool p_visibe);
+ void set_tabs_visible(bool p_visible);
bool are_tabs_visible() const;
void set_tab_title(int p_tab, const String &p_title);
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index d7e469ca26..6de2f0b570 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -7070,6 +7070,10 @@ void TextEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_smooth_scroll_enabled"), &TextEdit::is_smooth_scroll_enabled);
ClassDB::bind_method(D_METHOD("set_v_scroll_speed", "speed"), &TextEdit::set_v_scroll_speed);
ClassDB::bind_method(D_METHOD("get_v_scroll_speed"), &TextEdit::get_v_scroll_speed);
+ ClassDB::bind_method(D_METHOD("set_v_scroll", "value"), &TextEdit::set_v_scroll);
+ ClassDB::bind_method(D_METHOD("get_v_scroll"), &TextEdit::get_v_scroll);
+ ClassDB::bind_method(D_METHOD("set_h_scroll", "value"), &TextEdit::set_h_scroll);
+ ClassDB::bind_method(D_METHOD("get_h_scroll"), &TextEdit::get_h_scroll);
ClassDB::bind_method(D_METHOD("add_keyword_color", "keyword", "color"), &TextEdit::add_keyword_color);
ClassDB::bind_method(D_METHOD("has_keyword_color", "keyword"), &TextEdit::has_keyword_color);
@@ -7105,6 +7109,8 @@ void TextEdit::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "v_scroll_speed"), "set_v_scroll_speed", "get_v_scroll_speed");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hiding_enabled"), "set_hiding_enabled", "is_hiding_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "wrap_enabled"), "set_wrap_enabled", "is_wrap_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "scroll_vertical"), "set_v_scroll", "get_v_scroll");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "scroll_horizontal"), "set_h_scroll", "get_h_scroll");
ADD_GROUP("Minimap", "minimap_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "minimap_draw"), "draw_minimap", "is_drawing_minimap");
diff --git a/scene/gui/video_player.cpp b/scene/gui/video_player.cpp
index 071e8a8ac6..0a693d4023 100644
--- a/scene/gui/video_player.cpp
+++ b/scene/gui/video_player.cpp
@@ -249,6 +249,10 @@ void VideoPlayer::set_stream(const Ref<VideoStream> &p_stream) {
}
update();
+
+ if (!expand) {
+ minimum_size_changed();
+ }
};
Ref<VideoStream> VideoPlayer::get_stream() const {
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 1e2b7c094e..350959dcc3 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -2680,7 +2680,8 @@ void Node::clear_internal_tree_resource_paths() {
String Node::get_configuration_warning() const {
- if (get_script_instance() && get_script_instance()->has_method("_get_configuration_warning")) {
+ if (get_script_instance() && get_script_instance()->get_script().is_valid() &&
+ get_script_instance()->get_script()->is_tool() && get_script_instance()->has_method("_get_configuration_warning")) {
return get_script_instance()->call("_get_configuration_warning");
}
return String();
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index da147e7112..238d6c20cc 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -423,7 +423,8 @@ void SceneTree::input_event(const Ref<InputEvent> &p_event) {
input_handled = false;
- const Ref<InputEvent> &ev = p_event;
+ // Don't make const ref unless you can find and fix what caused GH-34691.
+ Ref<InputEvent> ev = p_event;
MainLoop::input_event(ev);
@@ -458,10 +459,7 @@ void SceneTree::input_event(const Ref<InputEvent> &p_event) {
}
void SceneTree::init() {
-
- //_quit=false;
initialized = true;
-
root->_set_tree(this);
MainLoop::init();
}
@@ -1284,6 +1282,14 @@ void SceneTree::_change_scene(Node *p_to) {
current_scene = NULL;
}
+ // If we're quitting, abort.
+ if (unlikely(_quit)) {
+ if (p_to) { // Prevent memory leak.
+ memdelete(p_to);
+ }
+ return;
+ }
+
if (p_to) {
current_scene = p_to;
root->add_child(p_to);
@@ -1291,15 +1297,14 @@ void SceneTree::_change_scene(Node *p_to) {
}
Error SceneTree::change_scene(const String &p_path) {
-
Ref<PackedScene> new_scene = ResourceLoader::load(p_path);
if (new_scene.is_null())
return ERR_CANT_OPEN;
return change_scene_to(new_scene);
}
-Error SceneTree::change_scene_to(const Ref<PackedScene> &p_scene) {
+Error SceneTree::change_scene_to(const Ref<PackedScene> &p_scene) {
Node *new_scene = NULL;
if (p_scene.is_valid()) {
new_scene = p_scene->instance();
@@ -1309,8 +1314,8 @@ Error SceneTree::change_scene_to(const Ref<PackedScene> &p_scene) {
call_deferred("_change_scene", new_scene);
return OK;
}
-Error SceneTree::reload_current_scene() {
+Error SceneTree::reload_current_scene() {
ERR_FAIL_COND_V(!current_scene, ERR_UNCONFIGURED);
String fname = current_scene->get_filename();
return change_scene(fname);
@@ -1321,6 +1326,7 @@ void SceneTree::add_current_scene(Node *p_current) {
current_scene = p_current;
root->add_child(p_current);
}
+
#ifdef DEBUG_ENABLED
static void _fill_array(Node *p_node, Array &array, int p_level) {
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 21fc9ccf6a..c0c6b864a5 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -194,13 +194,11 @@
#include "scene/3d/path.h"
#include "scene/3d/physics_body.h"
#include "scene/3d/physics_joint.h"
-#include "scene/3d/portal.h"
#include "scene/3d/position_3d.h"
#include "scene/3d/proximity_group.h"
#include "scene/3d/ray_cast.h"
#include "scene/3d/reflection_probe.h"
#include "scene/3d/remote_transform.h"
-#include "scene/3d/room_instance.h"
#include "scene/3d/skeleton.h"
#include "scene/3d/soft_body.h"
#include "scene/3d/spring_arm.h"
@@ -372,6 +370,28 @@ void register_scene_types() {
ClassDB::register_class<AnimationPlayer>();
ClassDB::register_class<Tween>();
+ ClassDB::register_class<AnimationTreePlayer>();
+ ClassDB::register_class<AnimationTree>();
+ ClassDB::register_class<AnimationNode>();
+ ClassDB::register_class<AnimationRootNode>();
+ ClassDB::register_class<AnimationNodeBlendTree>();
+ ClassDB::register_class<AnimationNodeBlendSpace1D>();
+ ClassDB::register_class<AnimationNodeBlendSpace2D>();
+ ClassDB::register_class<AnimationNodeStateMachine>();
+ ClassDB::register_class<AnimationNodeStateMachinePlayback>();
+
+ ClassDB::register_class<AnimationNodeStateMachineTransition>();
+ ClassDB::register_class<AnimationNodeOutput>();
+ ClassDB::register_class<AnimationNodeOneShot>();
+ ClassDB::register_class<AnimationNodeAnimation>();
+ ClassDB::register_class<AnimationNodeAdd2>();
+ ClassDB::register_class<AnimationNodeAdd3>();
+ ClassDB::register_class<AnimationNodeBlend2>();
+ ClassDB::register_class<AnimationNodeBlend3>();
+ ClassDB::register_class<AnimationNodeTimeScale>();
+ ClassDB::register_class<AnimationNodeTimeSeek>();
+ ClassDB::register_class<AnimationNodeTransition>();
+
OS::get_singleton()->yield(); //may take time to init
#ifndef _3D_DISABLED
@@ -399,7 +419,6 @@ void register_scene_types() {
ClassDB::register_class<GIProbeData>();
ClassDB::register_class<BakedLightmap>();
ClassDB::register_class<BakedLightmapData>();
- ClassDB::register_class<AnimationTreePlayer>();
ClassDB::register_class<Particles>();
ClassDB::register_class<CPUParticles>();
ClassDB::register_class<Position3D>();
@@ -410,27 +429,6 @@ void register_scene_types() {
ClassDB::register_class<RootMotionView>();
ClassDB::set_class_enabled("RootMotionView", false); //disabled by default, enabled by editor
- ClassDB::register_class<AnimationTree>();
- ClassDB::register_class<AnimationNode>();
- ClassDB::register_class<AnimationRootNode>();
- ClassDB::register_class<AnimationNodeBlendTree>();
- ClassDB::register_class<AnimationNodeBlendSpace1D>();
- ClassDB::register_class<AnimationNodeBlendSpace2D>();
- ClassDB::register_class<AnimationNodeStateMachine>();
- ClassDB::register_class<AnimationNodeStateMachinePlayback>();
-
- ClassDB::register_class<AnimationNodeStateMachineTransition>();
- ClassDB::register_class<AnimationNodeOutput>();
- ClassDB::register_class<AnimationNodeOneShot>();
- ClassDB::register_class<AnimationNodeAnimation>();
- ClassDB::register_class<AnimationNodeAdd2>();
- ClassDB::register_class<AnimationNodeAdd3>();
- ClassDB::register_class<AnimationNodeBlend2>();
- ClassDB::register_class<AnimationNodeBlend3>();
- ClassDB::register_class<AnimationNodeTimeScale>();
- ClassDB::register_class<AnimationNodeTimeSeek>();
- ClassDB::register_class<AnimationNodeTransition>();
-
OS::get_singleton()->yield(); //may take time to init
ClassDB::register_virtual_class<CollisionObject>();
diff --git a/scene/resources/audio_stream_sample.cpp b/scene/resources/audio_stream_sample.cpp
index bfc7f407eb..e8cb40154e 100644
--- a/scene/resources/audio_stream_sample.cpp
+++ b/scene/resources/audio_stream_sample.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "audio_stream_sample.h"
+
#include "core/io/marshalls.h"
#include "core/os/file_access.h"
@@ -656,8 +657,8 @@ AudioStreamSample::AudioStreamSample() {
data = NULL;
data_bytes = 0;
}
-AudioStreamSample::~AudioStreamSample() {
+AudioStreamSample::~AudioStreamSample() {
if (data) {
AudioServer::get_singleton()->audio_data_free(data);
data = NULL;
diff --git a/scene/resources/audio_stream_sample.h b/scene/resources/audio_stream_sample.h
index d5d8f073fb..adcac14ea8 100644
--- a/scene/resources/audio_stream_sample.h
+++ b/scene/resources/audio_stream_sample.h
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef AUDIOSTREAMSAMPLE_H
-#define AUDIOSTREAMSAMPLE_H
+#ifndef AUDIO_STREAM_SAMPLE_H
+#define AUDIO_STREAM_SAMPLE_H
#include "servers/audio/audio_stream.h"
@@ -153,4 +153,4 @@ public:
VARIANT_ENUM_CAST(AudioStreamSample::Format)
VARIANT_ENUM_CAST(AudioStreamSample::LoopMode)
-#endif // AUDIOSTREAMSample_H
+#endif // AUDIO_STREAM_SAMPLE_H
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index 67351f07d2..cc76df62e5 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -851,6 +851,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_stylebox("bg", "GraphEdit", make_stylebox(tree_bg_png, 4, 4, 4, 5));
theme->set_color("grid_minor", "GraphEdit", Color(1, 1, 1, 0.05));
theme->set_color("grid_major", "GraphEdit", Color(1, 1, 1, 0.2));
+ theme->set_color("selection_fill", "GraphEdit", Color(1, 1, 1, 0.3));
+ theme->set_color("selection_stroke", "GraphEdit", Color(1, 1, 1, 0.8));
theme->set_color("activity", "GraphEdit", Color(1, 1, 1));
theme->set_constant("bezier_len_pos", "GraphEdit", 80 * scale);
theme->set_constant("bezier_len_neg", "GraphEdit", 160 * scale);
diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp
index 10d871aa92..d19d82d252 100644
--- a/scene/resources/dynamic_font.cpp
+++ b/scene/resources/dynamic_font.cpp
@@ -130,7 +130,10 @@ Error DynamicFontAtSize::_load() {
} else {
FileAccess *f = FileAccess::open(font->font_path, FileAccess::READ);
- ERR_FAIL_COND_V_MSG(!f, ERR_CANT_OPEN, "Cannot open font file '" + font->font_path + "'.");
+ if (!f) {
+ FT_Done_FreeType(library);
+ ERR_FAIL_V_MSG(ERR_CANT_OPEN, "Cannot open font file '" + font->font_path + "'.");
+ }
size_t len = f->get_len();
_fontdata[font->font_path] = Vector<uint8_t>();
@@ -145,7 +148,10 @@ Error DynamicFontAtSize::_load() {
if (font->font_mem == NULL && font->font_path != String()) {
FileAccess *f = FileAccess::open(font->font_path, FileAccess::READ);
- ERR_FAIL_COND_V_MSG(!f, ERR_CANT_OPEN, "Cannot open font file '" + font->font_path + "'.");
+ if (!f) {
+ FT_Done_FreeType(library);
+ ERR_FAIL_V_MSG(ERR_CANT_OPEN, "Cannot open font file '" + font->font_path + "'.");
+ }
memset(&stream, 0, sizeof(FT_StreamRec));
stream.base = NULL;
@@ -176,6 +182,7 @@ Error DynamicFontAtSize::_load() {
error = FT_Open_Face(library, &fargs, 0, &face);
} else {
+ FT_Done_FreeType(library);
ERR_FAIL_V_MSG(ERR_UNCONFIGURED, "DynamicFont uninitialized.");
}
@@ -314,7 +321,7 @@ float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2 &p_pos, CharT
float advance = 0.0;
- // use normal character size if there's no outline charater
+ // use normal character size if there's no outline character
if (p_outline && !ch->found) {
FT_GlyphSlot slot = face->glyph;
int error = FT_Load_Char(face, p_char, FT_HAS_COLOR(face) ? FT_LOAD_COLOR : FT_LOAD_DEFAULT);
@@ -1011,8 +1018,8 @@ void DynamicFont::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_fallback_count"), &DynamicFont::get_fallback_count);
ADD_GROUP("Settings", "");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "size", PROPERTY_HINT_RANGE, "1,255,1"), "set_size", "get_size");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "outline_size", PROPERTY_HINT_RANGE, "0,255,1"), "set_outline_size", "get_outline_size");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "size", PROPERTY_HINT_RANGE, "1,1024,1"), "set_size", "get_size");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "outline_size", PROPERTY_HINT_RANGE, "0,1024,1"), "set_outline_size", "get_outline_size");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "outline_color"), "set_outline_color", "get_outline_color");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_mipmaps"), "set_use_mipmaps", "get_use_mipmaps");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_filter"), "set_use_filter", "get_use_filter");
diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp
index 960919df47..19c59b3817 100644
--- a/scene/resources/font.cpp
+++ b/scene/resources/font.cpp
@@ -628,8 +628,8 @@ void BitmapFont::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::POOL_INT_ARRAY, "chars", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_chars", "_get_chars");
ADD_PROPERTY(PropertyInfo(Variant::POOL_INT_ARRAY, "kernings", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_kernings", "_get_kernings");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "height", PROPERTY_HINT_RANGE, "-1024,1024,1"), "set_height", "get_height");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "ascent", PROPERTY_HINT_RANGE, "-1024,1024,1"), "set_ascent", "get_ascent");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "height", PROPERTY_HINT_RANGE, "1,1024,1"), "set_height", "get_height");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "ascent", PROPERTY_HINT_RANGE, "0,1024,1"), "set_ascent", "get_ascent");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "distance_field"), "set_distance_field_hint", "is_distance_field_hint");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "fallback", PROPERTY_HINT_RESOURCE_TYPE, "BitmapFont"), "set_fallback", "get_fallback");
}
diff --git a/scene/resources/material.h b/scene/resources/material.h
index 3c2a7c928a..8e66011bec 100644
--- a/scene/resources/material.h
+++ b/scene/resources/material.h
@@ -42,7 +42,7 @@ class Material : public Resource {
GDCLASS(Material, Resource);
RES_BASE_EXTENSION("material")
- OBJ_SAVE_TYPE(Material)
+ OBJ_SAVE_TYPE(Material);
RID material;
Ref<Material> next_pass;
@@ -249,7 +249,7 @@ private:
uint64_t blend_mode : 2;
uint64_t depth_draw_mode : 2;
uint64_t cull_mode : 2;
- uint64_t flags : 18;
+ uint64_t flags : 19;
uint64_t detail_blend_mode : 2;
uint64_t diffuse_mode : 3;
uint64_t specular_mode : 3;
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index 13721191c0..0599920303 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -75,6 +75,7 @@ Ref<TriangleMesh> Mesh::generate_triangle_mesh() const {
continue;
Array a = surface_get_arrays(i);
+ ERR_FAIL_COND_V(a.empty(), Ref<TriangleMesh>());
int vc = surface_get_array_len(i);
PoolVector<Vector3> vertices = a[ARRAY_VERTEX];
@@ -234,6 +235,7 @@ Ref<Shape> Mesh::create_convex_shape() const {
for (int i = 0; i < get_surface_count(); i++) {
Array a = surface_get_arrays(i);
+ ERR_FAIL_COND_V(a.empty(), Ref<ConvexPolygonShape>());
PoolVector<Vector3> v = a[ARRAY_VERTEX];
vertices.append_array(v);
}
@@ -273,6 +275,7 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const {
continue;
Array a = surface_get_arrays(i);
+ ERR_FAIL_COND_V(a.empty(), Ref<ArrayMesh>());
if (i == 0) {
arrays = a;
@@ -378,6 +381,7 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const {
PoolVector<Vector3>::Write r = vertices.write();
if (indices.size()) {
+ ERR_FAIL_COND_V(indices.size() % 3 != 0, Ref<ArrayMesh>());
vc = indices.size();
ir = indices.write();
has_indices = true;
diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp
index 978d81d5c2..3e7d350eec 100644
--- a/scene/resources/packed_scene.cpp
+++ b/scene/resources/packed_scene.cpp
@@ -1099,11 +1099,11 @@ void SceneState::set_bundled_scene(const Dictionary &p_dictionary) {
const int node_count = p_dictionary["node_count"];
const PoolVector<int> snodes = p_dictionary["nodes"];
- ERR_FAIL_COND(snodes.size() != node_count);
+ ERR_FAIL_COND(snodes.size() < node_count);
const int conn_count = p_dictionary["conn_count"];
const PoolVector<int> sconns = p_dictionary["conns"];
- ERR_FAIL_COND(sconns.size() != conn_count);
+ ERR_FAIL_COND(sconns.size() < conn_count);
PoolVector<String> snames = p_dictionary["names"];
if (snames.size()) {
diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp
index a058f42cb2..412b5c259c 100644
--- a/scene/resources/particles_material.cpp
+++ b/scene/resources/particles_material.cpp
@@ -198,6 +198,9 @@ void ParticlesMaterial::_update_shader() {
code += "uniform sampler2D emission_texture_color : hint_white;\n";
}
} break;
+ case EMISSION_SHAPE_MAX: { // Max value for validity check.
+ break;
+ }
}
code += "uniform vec4 color_value : hint_color;\n";
@@ -283,7 +286,7 @@ void ParticlesMaterial::_update_shader() {
code += " float degree_to_rad = pi / 180.0;\n";
code += "\n";
- if (emission_shape >= EMISSION_SHAPE_POINTS) {
+ if (emission_shape == EMISSION_SHAPE_POINTS || emission_shape == EMISSION_SHAPE_DIRECTED_POINTS) {
code += " int point = min(emission_texture_point_count - 1, int(rand_from_seed(alt_seed) * float(emission_texture_point_count)));\n";
code += " ivec2 emission_tex_size = textureSize(emission_texture_points, 0);\n";
code += " ivec2 emission_tex_ofs = ivec2(point % emission_tex_size.x, point / emission_tex_size.x);\n";
@@ -368,6 +371,9 @@ void ParticlesMaterial::_update_shader() {
}
}
} break;
+ case EMISSION_SHAPE_MAX: { // Max value for validity check.
+ break;
+ }
}
code += " VELOCITY = (EMISSION_TRANSFORM * vec4(VELOCITY, 0.0)).xyz;\n";
code += " TRANSFORM = EMISSION_TRANSFORM * TRANSFORM;\n";
@@ -515,7 +521,7 @@ void ParticlesMaterial::_update_shader() {
} else {
code += " COLOR = hue_rot_mat * color_value;\n";
}
- if (emission_color_texture.is_valid() && emission_shape >= EMISSION_SHAPE_POINTS) {
+ if (emission_color_texture.is_valid() && (emission_shape == EMISSION_SHAPE_POINTS || emission_shape == EMISSION_SHAPE_DIRECTED_POINTS)) {
code += " COLOR *= texelFetch(emission_texture_color, emission_tex_ofs, 0);\n";
}
if (trail_color_modifier.is_valid()) {
@@ -894,7 +900,7 @@ bool ParticlesMaterial::get_flag(Flags p_flag) const {
}
void ParticlesMaterial::set_emission_shape(EmissionShape p_shape) {
-
+ ERR_FAIL_INDEX(p_shape, EMISSION_SHAPE_MAX);
emission_shape = p_shape;
_change_notify();
_queue_shader_change();
@@ -1242,6 +1248,7 @@ void ParticlesMaterial::_bind_methods() {
BIND_ENUM_CONSTANT(EMISSION_SHAPE_BOX);
BIND_ENUM_CONSTANT(EMISSION_SHAPE_POINTS);
BIND_ENUM_CONSTANT(EMISSION_SHAPE_DIRECTED_POINTS);
+ BIND_ENUM_CONSTANT(EMISSION_SHAPE_MAX);
}
ParticlesMaterial::ParticlesMaterial() :
diff --git a/scene/resources/particles_material.h b/scene/resources/particles_material.h
index 643c2cb10e..cc860b3812 100644
--- a/scene/resources/particles_material.h
+++ b/scene/resources/particles_material.h
@@ -69,6 +69,7 @@ public:
EMISSION_SHAPE_BOX,
EMISSION_SHAPE_POINTS,
EMISSION_SHAPE_DIRECTED_POINTS,
+ EMISSION_SHAPE_MAX
};
private:
diff --git a/scene/resources/room.cpp b/scene/resources/room.cpp
deleted file mode 100644
index 51c4489ec3..0000000000
--- a/scene/resources/room.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/*************************************************************************/
-/* room.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "room.h"
-
-#include "servers/visual_server.h"
-
-// FIXME: Left for reference for reimplementation using Area
-#if 0
-RID RoomBounds::get_rid() const {
-
- return area;
-}
-
-void RoomBounds::set_geometry_hint(const PoolVector<Face3> &p_geometry_hint) {
-
- geometry_hint = p_geometry_hint;
-}
-
-PoolVector<Face3> RoomBounds::get_geometry_hint() const {
-
- return geometry_hint;
-}
-
-void RoomBounds::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("set_geometry_hint", "triangles"), &RoomBounds::set_geometry_hint);
- ClassDB::bind_method(D_METHOD("get_geometry_hint"), &RoomBounds::get_geometry_hint);
-
- //ADD_PROPERTY( PropertyInfo( Variant::DICTIONARY, "bounds"), "set_bounds","get_bounds") ;
- ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR3_ARRAY, "geometry_hint"), "set_geometry_hint", "get_geometry_hint");
-}
-
-RoomBounds::RoomBounds() {
-
- area = VisualServer::get_singleton()->room_create();
-}
-
-RoomBounds::~RoomBounds() {
-
- VisualServer::get_singleton()->free(area);
-}
-#endif
diff --git a/scene/resources/room.h b/scene/resources/room.h
deleted file mode 100644
index 809a9c1de8..0000000000
--- a/scene/resources/room.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*************************************************************************/
-/* room.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#ifndef ROOM_BOUNDS_H
-#define ROOM_BOUNDS_H
-
-#include "core/math/bsp_tree.h"
-#include "core/resource.h"
-
-// FIXME: left for reference but will be removed when portals are reimplemented using Area
-#if 0
-
-class RoomBounds : public Resource {
-
- GDCLASS(RoomBounds, Resource);
- RES_BASE_EXTENSION("room");
-
- RID area;
- PoolVector<Face3> geometry_hint;
-
-protected:
- static void _bind_methods();
-
-public:
- virtual RID get_rid() const;
-
- void set_geometry_hint(const PoolVector<Face3> &p_geometry_hint);
- PoolVector<Face3> get_geometry_hint() const;
-
- RoomBounds();
- ~RoomBounds();
-};
-
-#endif
-#endif // ROOM_H
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index fcd8547d07..fa698d387b 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -45,7 +45,8 @@
class Texture : public Resource {
GDCLASS(Texture, Resource);
- OBJ_SAVE_TYPE(Texture); //children are all saved as Texture, so they can be exchanged
+ OBJ_SAVE_TYPE(Texture); // Saves derived classes with common type so they can be interchanged.
+
protected:
static void _bind_methods();
diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp
index d9caf1d657..555e90ed3c 100644
--- a/scene/resources/tile_set.cpp
+++ b/scene/resources/tile_set.cpp
@@ -1038,6 +1038,7 @@ void TileSet::_tile_set_shapes(int p_id, const Array &p_shapes) {
}
tile_map[p_id].shapes_data = shapes_data;
+ emit_changed();
}
Array TileSet::_tile_get_shapes(int p_id) const {
@@ -1232,6 +1233,7 @@ void TileSet::_bind_methods() {
BIND_ENUM_CONSTANT(BIND_TOP);
BIND_ENUM_CONSTANT(BIND_TOPRIGHT);
BIND_ENUM_CONSTANT(BIND_LEFT);
+ BIND_ENUM_CONSTANT(BIND_CENTER);
BIND_ENUM_CONSTANT(BIND_RIGHT);
BIND_ENUM_CONSTANT(BIND_BOTTOMLEFT);
BIND_ENUM_CONSTANT(BIND_BOTTOM);
diff --git a/scene/resources/video_stream.cpp b/scene/resources/video_stream.cpp
deleted file mode 100644
index 81b4477c9a..0000000000
--- a/scene/resources/video_stream.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/*************************************************************************/
-/* video_stream.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-#include "video_stream.h"
-
-void VideoStreamPlayback::_bind_methods(){
-
-};
-
-VideoStreamPlayback::VideoStreamPlayback(){
-
-};
diff --git a/scene/resources/video_stream.h b/scene/resources/video_stream.h
index d8aee2eac3..444bb698ae 100644
--- a/scene/resources/video_stream.h
+++ b/scene/resources/video_stream.h
@@ -37,9 +37,6 @@ class VideoStreamPlayback : public Resource {
GDCLASS(VideoStreamPlayback, Resource);
-protected:
- static void _bind_methods();
-
public:
typedef int (*AudioMixCallback)(void *p_udata, const float *p_data, int p_frames);
@@ -61,28 +58,22 @@ public:
virtual void set_audio_track(int p_idx) = 0;
- //virtual int mix(int16_t* p_buffer,int p_frames)=0;
-
virtual Ref<Texture> get_texture() const = 0;
virtual void update(float p_delta) = 0;
virtual void set_mix_callback(AudioMixCallback p_callback, void *p_userdata) = 0;
virtual int get_channels() const = 0;
virtual int get_mix_rate() const = 0;
-
- VideoStreamPlayback();
};
class VideoStream : public Resource {
GDCLASS(VideoStream, Resource);
- OBJ_SAVE_TYPE(VideoStream); //children are all saved as AudioStream, so they can be exchanged
+ OBJ_SAVE_TYPE(VideoStream); // Saves derived classes with common type so they can be interchanged.
public:
virtual void set_audio_track(int p_track) = 0;
virtual Ref<VideoStreamPlayback> instance_playback() = 0;
-
- VideoStream() {}
};
#endif
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index 37792eaaea..e350a0a99e 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -79,7 +79,7 @@ Vector<StringName> VisualShaderNode::get_editable_properties() const {
return Vector<StringName>();
}
-Array VisualShaderNode::_get_default_input_values() const {
+Array VisualShaderNode::get_default_input_values() const {
Array ret;
for (Map<int, Variant>::Element *E = default_input_values.front(); E; E = E->next()) {
@@ -88,7 +88,7 @@ Array VisualShaderNode::_get_default_input_values() const {
}
return ret;
}
-void VisualShaderNode::_set_default_input_values(const Array &p_values) {
+void VisualShaderNode::set_default_input_values(const Array &p_values) {
if (p_values.size() % 2 == 0) {
for (int i = 0; i < p_values.size(); i += 2) {
@@ -115,11 +115,11 @@ void VisualShaderNode::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_input_port_default_value", "port", "value"), &VisualShaderNode::set_input_port_default_value);
ClassDB::bind_method(D_METHOD("get_input_port_default_value", "port"), &VisualShaderNode::get_input_port_default_value);
- ClassDB::bind_method(D_METHOD("_set_default_input_values", "values"), &VisualShaderNode::_set_default_input_values);
- ClassDB::bind_method(D_METHOD("_get_default_input_values"), &VisualShaderNode::_get_default_input_values);
+ ClassDB::bind_method(D_METHOD("set_default_input_values", "values"), &VisualShaderNode::set_default_input_values);
+ ClassDB::bind_method(D_METHOD("get_default_input_values"), &VisualShaderNode::get_default_input_values);
ADD_PROPERTY(PropertyInfo(Variant::INT, "output_port_for_preview"), "set_output_port_for_preview", "get_output_port_for_preview");
- ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "default_input_values", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_default_input_values", "_get_default_input_values");
+ ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "default_input_values", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_default_input_values", "get_default_input_values");
ADD_SIGNAL(MethodInfo("editor_refresh_request"));
BIND_ENUM_CONSTANT(PORT_TYPE_SCALAR);
@@ -378,6 +378,9 @@ void VisualShader::remove_node(Type p_type, int p_id) {
List<Connection>::Element *N = E->next();
if (E->get().from_node == p_id || E->get().to_node == p_id) {
g->connections.erase(E);
+ if (E->get().from_node == p_id) {
+ g->nodes[E->get().to_node].prev_connected_nodes.erase(p_id);
+ }
}
E = N;
}
@@ -399,6 +402,25 @@ bool VisualShader::is_node_connection(Type p_type, int p_from_node, int p_from_p
return false;
}
+bool VisualShader::is_nodes_connected_relatively(const Graph *p_graph, int p_node, int p_target) const {
+ bool result = false;
+
+ const VisualShader::Node &node = p_graph->nodes[p_node];
+
+ for (const List<int>::Element *E = node.prev_connected_nodes.front(); E; E = E->next()) {
+
+ if (E->get() == p_target) {
+ return true;
+ }
+
+ result = is_nodes_connected_relatively(p_graph, E->get(), p_target);
+ if (result) {
+ break;
+ }
+ }
+ return result;
+}
+
bool VisualShader::can_connect_nodes(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) const {
ERR_FAIL_INDEX_V(p_type, TYPE_MAX, false);
@@ -433,6 +455,9 @@ bool VisualShader::can_connect_nodes(Type p_type, int p_from_node, int p_from_po
}
}
+ if (is_nodes_connected_relatively(g, p_from_node, p_to_node))
+ return false;
+
return true;
}
@@ -449,6 +474,8 @@ void VisualShader::connect_nodes_forced(Type p_type, int p_from_node, int p_from
c.to_node = p_to_node;
c.to_port = p_to_port;
g->connections.push_back(c);
+ g->nodes[p_to_node].prev_connected_nodes.push_back(p_from_node);
+
_queue_update();
}
@@ -479,6 +506,7 @@ Error VisualShader::connect_nodes(Type p_type, int p_from_node, int p_from_port,
c.to_node = p_to_node;
c.to_port = p_to_port;
g->connections.push_back(c);
+ g->nodes[p_to_node].prev_connected_nodes.push_back(p_from_node);
_queue_update();
return OK;
@@ -492,6 +520,7 @@ void VisualShader::disconnect_nodes(Type p_type, int p_from_node, int p_from_por
if (E->get().from_node == p_from_node && E->get().from_port == p_from_port && E->get().to_node == p_to_node && E->get().to_port == p_to_port) {
g->connections.erase(E);
+ g->nodes[p_to_node].prev_connected_nodes.erase(p_from_node);
_queue_update();
return;
}
@@ -1326,6 +1355,7 @@ void VisualShader::_input_type_changed(Type p_type, int p_id) {
List<Connection>::Element *N = E->next();
if (E->get().from_node == p_id) {
g->connections.erase(E);
+ g->nodes[E->get().to_node].prev_connected_nodes.erase(p_id);
}
E = N;
}
@@ -2472,13 +2502,7 @@ void VisualShaderNodeGroupBase::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_free_input_port_id"), &VisualShaderNodeGroupBase::get_free_input_port_id);
ClassDB::bind_method(D_METHOD("get_free_output_port_id"), &VisualShaderNodeGroupBase::get_free_output_port_id);
- ClassDB::bind_method(D_METHOD("set_control", "control", "index"), &VisualShaderNodeGroupBase::set_control);
- ClassDB::bind_method(D_METHOD("get_control", "index"), &VisualShaderNodeGroupBase::get_control);
-
- ClassDB::bind_method(D_METHOD("set_editable", "enabled"), &VisualShaderNodeGroupBase::set_editable);
- ClassDB::bind_method(D_METHOD("is_editable"), &VisualShaderNodeGroupBase::is_editable);
-
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editable"), "set_editable", "is_editable");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size"), "set_size", "get_size");
}
String VisualShaderNodeGroupBase::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
@@ -2502,10 +2526,6 @@ void VisualShaderNodeExpression::set_expression(const String &p_expression) {
expression = p_expression;
}
-void VisualShaderNodeExpression::build() {
- emit_changed();
-}
-
String VisualShaderNodeExpression::get_expression() const {
return expression;
}
@@ -2612,8 +2632,6 @@ void VisualShaderNodeExpression::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_expression", "expression"), &VisualShaderNodeExpression::set_expression);
ClassDB::bind_method(D_METHOD("get_expression"), &VisualShaderNodeExpression::get_expression);
- ClassDB::bind_method(D_METHOD("build"), &VisualShaderNodeExpression::build);
-
ADD_PROPERTY(PropertyInfo(Variant::STRING, "expression"), "set_expression", "get_expression");
}
diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h
index 0a3d5f96bd..f81090d9cb 100644
--- a/scene/resources/visual_shader.h
+++ b/scene/resources/visual_shader.h
@@ -65,6 +65,7 @@ private:
struct Node {
Ref<VisualShaderNode> node;
Vector2 position;
+ List<int> prev_connected_nodes;
};
struct Graph {
@@ -135,6 +136,8 @@ public:
void remove_node(Type p_type, int p_id);
bool is_node_connection(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) const;
+
+ bool is_nodes_connected_relatively(const Graph *p_graph, int p_node, int p_target) const;
bool can_connect_nodes(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) const;
Error connect_nodes(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port);
void disconnect_nodes(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port);
@@ -172,9 +175,6 @@ class VisualShaderNode : public Resource {
Map<int, Variant> default_input_values;
- Array _get_default_input_values() const;
- void _set_default_input_values(const Array &p_values);
-
protected:
static void _bind_methods();
@@ -196,6 +196,8 @@ public:
void set_input_port_default_value(int p_port, const Variant &p_value);
Variant get_input_port_default_value(int p_port) const; // if NIL (default if node does not set anything) is returned, it means no default value is wanted if disconnected, thus no input var must be supplied (empty string will be supplied)
+ Array get_default_input_values() const;
+ void set_default_input_values(const Array &p_values);
virtual int get_output_port_count() const = 0;
virtual PortType get_output_port_type(int p_port) const = 0;
@@ -455,8 +457,6 @@ public:
void set_expression(const String &p_expression);
String get_expression() const;
- void build();
-
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const;
VisualShaderNodeExpression();
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp
index 0035a138d7..7d8c396b7f 100644
--- a/scene/resources/visual_shader_nodes.cpp
+++ b/scene/resources/visual_shader_nodes.cpp
@@ -792,7 +792,7 @@ String VisualShaderNodeCubeMap::generate_global(Shader::Mode p_mode, VisualShade
case TYPE_COLOR: u += " : hint_albedo"; break;
case TYPE_NORMALMAP: u += " : hint_normal"; break;
}
- return u + ";";
+ return u + ";\n";
}
return String();
}
@@ -809,29 +809,33 @@ String VisualShaderNodeCubeMap::generate_code(Shader::Mode p_mode, VisualShader:
return String();
}
+ code += "\t{\n";
+
if (id == String()) {
- code += "\tvec4 " + id + "_read = vec4(0.0);\n";
- code += "\t" + p_output_vars[0] + " = " + id + "_read.rgb;\n";
- code += "\t" + p_output_vars[1] + " = " + id + "_read.a;\n";
+ code += "\t\tvec4 " + id + "_read = vec4(0.0);\n";
+ code += "\t\t" + p_output_vars[0] + " = " + id + "_read.rgb;\n";
+ code += "\t\t" + p_output_vars[1] + " = " + id + "_read.a;\n";
+ code += "\t}\n";
return code;
}
if (p_input_vars[0] == String()) { // Use UV by default.
if (p_input_vars[1] == String()) {
- code += "\tvec4 " + id + "_read = texture( " + id + " , vec3( UV, 0.0 ) );\n";
+ code += "\t\tvec4 " + id + "_read = texture( " + id + " , vec3( UV, 0.0 ) );\n";
} else {
- code += "\tvec4 " + id + "_read = textureLod( " + id + " , vec3( UV, 0.0 )" + " , " + p_input_vars[1] + " );\n";
+ code += "\t\tvec4 " + id + "_read = textureLod( " + id + " , vec3( UV, 0.0 )" + " , " + p_input_vars[1] + " );\n";
}
} else if (p_input_vars[1] == String()) {
//no lod
- code += "\tvec4 " + id + "_read = texture( " + id + " , " + p_input_vars[0] + " );\n";
+ code += "\t\tvec4 " + id + "_read = texture( " + id + " , " + p_input_vars[0] + " );\n";
} else {
- code += "\tvec4 " + id + "_read = textureLod( " + id + " , " + p_input_vars[0] + " , " + p_input_vars[1] + " );\n";
+ code += "\t\tvec4 " + id + "_read = textureLod( " + id + " , " + p_input_vars[0] + " , " + p_input_vars[1] + " );\n";
}
- code += "\t" + p_output_vars[0] + " = " + id + "_read.rgb;\n";
- code += "\t" + p_output_vars[1] + " = " + id + "_read.a;\n";
+ code += "\t\t" + p_output_vars[0] + " = " + id + "_read.rgb;\n";
+ code += "\t\t" + p_output_vars[1] + " = " + id + "_read.a;\n";
+ code += "\t}\n";
return code;
}
@@ -3685,12 +3689,33 @@ String VisualShaderNodeFresnel::get_output_port_name(int p_port) const {
}
String VisualShaderNodeFresnel::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
- return "\t" + p_output_vars[0] + " = " + p_input_vars[2] + " ? (pow(clamp(dot(" + p_input_vars[0] + ", " + p_input_vars[1] + "), 0.0, 1.0), " + p_input_vars[3] + ")) : (pow(1.0 - clamp(dot(" + p_input_vars[0] + ", " + p_input_vars[1] + "), 0.0, 1.0), " + p_input_vars[3] + "));";
+
+ String normal;
+ String view;
+ if (p_input_vars[0] == String()) {
+ normal = "NORMAL";
+ } else {
+ normal = p_input_vars[0];
+ }
+ if (p_input_vars[1] == String()) {
+ view = "VIEW";
+ } else {
+ view = p_input_vars[1];
+ }
+
+ return "\t" + p_output_vars[0] + " = " + p_input_vars[2] + " ? (pow(clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + ")) : (pow(1.0 - clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + "));";
+}
+
+String VisualShaderNodeFresnel::get_input_port_default_hint(int p_port) const {
+ if (p_port == 0) {
+ return "default";
+ } else if (p_port == 1) {
+ return "default";
+ }
+ return "";
}
VisualShaderNodeFresnel::VisualShaderNodeFresnel() {
- set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0));
- set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0));
set_input_port_default_value(2, false);
set_input_port_default_value(3, 1.0);
}
@@ -3908,7 +3933,7 @@ String VisualShaderNodeCompare::generate_code(Shader::Mode p_mode, VisualShader:
return code;
}
-void VisualShaderNodeCompare::set_comparsion_type(ComparsionType p_type) {
+void VisualShaderNodeCompare::set_comparison_type(ComparisonType p_type) {
ctype = p_type;
@@ -3933,7 +3958,7 @@ void VisualShaderNodeCompare::set_comparsion_type(ComparsionType p_type) {
emit_changed();
}
-VisualShaderNodeCompare::ComparsionType VisualShaderNodeCompare::get_comparsion_type() const {
+VisualShaderNodeCompare::ComparisonType VisualShaderNodeCompare::get_comparison_type() const {
return ctype;
}
@@ -3971,8 +3996,8 @@ Vector<StringName> VisualShaderNodeCompare::get_editable_properties() const {
void VisualShaderNodeCompare::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_comparsion_type", "type"), &VisualShaderNodeCompare::set_comparsion_type);
- ClassDB::bind_method(D_METHOD("get_comparsion_type"), &VisualShaderNodeCompare::get_comparsion_type);
+ ClassDB::bind_method(D_METHOD("set_comparison_type", "type"), &VisualShaderNodeCompare::set_comparison_type);
+ ClassDB::bind_method(D_METHOD("get_comparison_type"), &VisualShaderNodeCompare::get_comparison_type);
ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeCompare::set_function);
ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeCompare::get_function);
@@ -3980,7 +4005,7 @@ void VisualShaderNodeCompare::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_condition", "condition"), &VisualShaderNodeCompare::set_condition);
ClassDB::bind_method(D_METHOD("get_condition"), &VisualShaderNodeCompare::get_condition);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, "Scalar,Vector,Boolean,Transform"), "set_comparsion_type", "get_comparsion_type");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, "Scalar,Vector,Boolean,Transform"), "set_comparison_type", "get_comparison_type");
ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "a == b,a != b,a > b,a >= b,a < b,a <= b"), "set_function", "get_function");
ADD_PROPERTY(PropertyInfo(Variant::INT, "condition", PROPERTY_HINT_ENUM, "All,Any"), "set_condition", "get_condition");
diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h
index 99b4c01d53..cca37273d9 100644
--- a/scene/resources/visual_shader_nodes.h
+++ b/scene/resources/visual_shader_nodes.h
@@ -1579,6 +1579,7 @@ public:
virtual PortType get_output_port_type(int p_port) const;
virtual String get_output_port_name(int p_port) const;
+ virtual String get_input_port_default_hint(int p_port) const;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const;
VisualShaderNodeFresnel();
@@ -1634,7 +1635,7 @@ class VisualShaderNodeCompare : public VisualShaderNode {
GDCLASS(VisualShaderNodeCompare, VisualShaderNode);
public:
- enum ComparsionType {
+ enum ComparisonType {
CTYPE_SCALAR,
CTYPE_VECTOR,
CTYPE_BOOLEAN,
@@ -1656,7 +1657,7 @@ public:
};
protected:
- ComparsionType ctype;
+ ComparisonType ctype;
Function func;
Condition condition;
@@ -1676,8 +1677,8 @@ public:
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
- void set_comparsion_type(ComparsionType p_type);
- ComparsionType get_comparsion_type() const;
+ void set_comparison_type(ComparisonType p_type);
+ ComparisonType get_comparison_type() const;
void set_function(Function p_func);
Function get_function() const;
@@ -1691,7 +1692,7 @@ public:
VisualShaderNodeCompare();
};
-VARIANT_ENUM_CAST(VisualShaderNodeCompare::ComparsionType)
+VARIANT_ENUM_CAST(VisualShaderNodeCompare::ComparisonType)
VARIANT_ENUM_CAST(VisualShaderNodeCompare::Function)
VARIANT_ENUM_CAST(VisualShaderNodeCompare::Condition)