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/area_2d.cpp4
-rw-r--r--scene/2d/canvas_item.cpp33
-rw-r--r--scene/2d/canvas_item.h2
-rw-r--r--scene/2d/line_2d.cpp4
-rw-r--r--scene/2d/navigation2d.h6
-rw-r--r--scene/2d/path_2d.cpp75
-rw-r--r--scene/2d/path_2d.h5
-rw-r--r--scene/2d/physics_body_2d.cpp16
-rw-r--r--scene/2d/tile_map.cpp19
-rw-r--r--scene/2d/tile_map.h14
-rw-r--r--scene/3d/area.cpp4
-rw-r--r--scene/3d/camera.cpp9
-rw-r--r--scene/3d/gi_probe.cpp9
-rw-r--r--scene/3d/light.cpp8
-rw-r--r--scene/3d/light.h4
-rw-r--r--scene/3d/navigation.h6
-rw-r--r--scene/3d/particles.cpp36
-rw-r--r--scene/3d/physics_body.cpp122
-rw-r--r--scene/3d/physics_body.h27
-rw-r--r--scene/3d/spatial.cpp4
-rw-r--r--scene/3d/vehicle_body.cpp20
-rw-r--r--scene/animation/animation_player.cpp10
-rw-r--r--scene/animation/animation_tree_player.cpp6
-rw-r--r--scene/animation/tween_interpolaters.cpp22
-rw-r--r--scene/gui/box_container.h8
-rw-r--r--scene/gui/check_box.cpp4
-rw-r--r--scene/gui/color_picker.cpp4
-rw-r--r--scene/gui/control.cpp11
-rw-r--r--scene/gui/control.h5
-rw-r--r--scene/gui/file_dialog.cpp28
-rw-r--r--scene/gui/file_dialog.h5
-rw-r--r--scene/gui/line_edit.cpp4
-rw-r--r--scene/gui/menu_button.cpp1
-rw-r--r--scene/gui/option_button.cpp1
-rw-r--r--scene/gui/scroll_bar.h8
-rw-r--r--scene/gui/scroll_container.cpp2
-rw-r--r--scene/gui/slider.h8
-rw-r--r--scene/gui/split_container.h8
-rw-r--r--scene/gui/text_edit.cpp78
-rw-r--r--scene/gui/text_edit.h6
-rw-r--r--scene/main/scene_tree.cpp2
-rw-r--r--scene/main/scene_tree.h4
-rw-r--r--scene/main/viewport.cpp21
-rw-r--r--scene/resources/animation.cpp38
-rw-r--r--scene/resources/animation.h7
-rw-r--r--scene/resources/box_shape.cpp4
-rw-r--r--scene/resources/capsule_shape.cpp4
-rw-r--r--scene/resources/capsule_shape_2d.cpp4
-rw-r--r--scene/resources/circle_shape_2d.cpp4
-rw-r--r--scene/resources/concave_polygon_shape.cpp4
-rw-r--r--scene/resources/concave_polygon_shape_2d.cpp4
-rw-r--r--scene/resources/convex_polygon_shape.cpp4
-rw-r--r--scene/resources/convex_polygon_shape_2d.cpp4
-rw-r--r--scene/resources/default_theme/default_theme.cpp1
-rw-r--r--scene/resources/material.cpp4
-rw-r--r--scene/resources/mesh.cpp211
-rw-r--r--scene/resources/mesh.h7
-rw-r--r--scene/resources/plane_shape.cpp4
-rw-r--r--scene/resources/ray_shape.cpp4
-rw-r--r--scene/resources/rectangle_shape_2d.cpp4
-rw-r--r--scene/resources/segment_shape_2d.cpp8
-rw-r--r--scene/resources/shape_line_2d.cpp4
-rw-r--r--scene/resources/sphere_shape.cpp4
-rw-r--r--scene/resources/surface_tool.cpp114
-rw-r--r--scene/resources/surface_tool.h3
-rw-r--r--scene/resources/tile_set.cpp16
-rw-r--r--scene/resources/tile_set.h12
68 files changed, 892 insertions, 256 deletions
diff --git a/scene/2d/animated_sprite.cpp b/scene/2d/animated_sprite.cpp
index 4865858b7d..f8f94926b7 100644
--- a/scene/2d/animated_sprite.cpp
+++ b/scene/2d/animated_sprite.cpp
@@ -568,7 +568,7 @@ void AnimatedSprite::stop() {
bool AnimatedSprite::is_playing() const {
- return is_processing();
+ return playing;
}
void AnimatedSprite::_reset_timeout() {
diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp
index 9ee77a710c..80f9bf0f9f 100644
--- a/scene/2d/area_2d.cpp
+++ b/scene/2d/area_2d.cpp
@@ -688,8 +688,8 @@ void Area2D::_bind_methods() {
BIND_ENUM_CONSTANT(SPACE_OVERRIDE_REPLACE_COMBINE);
}
-Area2D::Area2D()
- : CollisionObject2D(Physics2DServer::get_singleton()->area_create(), true) {
+Area2D::Area2D() :
+ CollisionObject2D(Physics2DServer::get_singleton()->area_create(), true) {
space_override = SPACE_OVERRIDE_DISABLED;
set_gravity(98);
diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp
index 9a3debbe90..82123d12ac 100644
--- a/scene/2d/canvas_item.cpp
+++ b/scene/2d/canvas_item.cpp
@@ -211,8 +211,8 @@ void CanvasItemMaterial::_bind_methods() {
BIND_ENUM_CONSTANT(LIGHT_MODE_LIGHT_ONLY);
}
-CanvasItemMaterial::CanvasItemMaterial()
- : element(this) {
+CanvasItemMaterial::CanvasItemMaterial() :
+ element(this) {
blend_mode = BLEND_MODE_MIX;
light_mode = LIGHT_MODE_NORMAL;
@@ -623,6 +623,29 @@ void CanvasItem::draw_polyline_colors(const Vector<Point2> &p_points, const Vect
VisualServer::get_singleton()->canvas_item_add_polyline(canvas_item, p_points, p_colors, p_width, p_antialiased);
}
+
+void CanvasItem::draw_multiline(const Vector<Point2> &p_points, const Color &p_color, float p_width, bool p_antialiased) {
+
+ if (!drawing) {
+ ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
+ ERR_FAIL();
+ }
+
+ Vector<Color> colors;
+ colors.push_back(p_color);
+ VisualServer::get_singleton()->canvas_item_add_multiline(canvas_item, p_points, colors, p_width, p_antialiased);
+}
+
+void CanvasItem::draw_multiline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width, bool p_antialiased) {
+
+ if (!drawing) {
+ ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
+ ERR_FAIL();
+ }
+
+ VisualServer::get_singleton()->canvas_item_add_multiline(canvas_item, p_points, p_colors, p_width, p_antialiased);
+}
+
void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled) {
if (!drawing) {
@@ -979,6 +1002,8 @@ void CanvasItem::_bind_methods() {
ClassDB::bind_method(D_METHOD("draw_line", "from", "to", "color", "width", "antialiased"), &CanvasItem::draw_line, DEFVAL(1.0), DEFVAL(false));
ClassDB::bind_method(D_METHOD("draw_polyline", "points", "color", "width", "antialiased"), &CanvasItem::draw_polyline, DEFVAL(1.0), DEFVAL(false));
ClassDB::bind_method(D_METHOD("draw_polyline_colors", "points", "colors", "width", "antialiased"), &CanvasItem::draw_polyline_colors, DEFVAL(1.0), DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("draw_multiline", "points", "color", "width", "antialiased"), &CanvasItem::draw_multiline, DEFVAL(1.0), DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("draw_multiline_colors", "points", "colors", "width", "antialiased"), &CanvasItem::draw_multiline_colors, DEFVAL(1.0), DEFVAL(false));
ClassDB::bind_method(D_METHOD("draw_rect", "rect", "color", "filled"), &CanvasItem::draw_rect, DEFVAL(true));
ClassDB::bind_method(D_METHOD("draw_circle", "position", "radius", "color"), &CanvasItem::draw_circle);
ClassDB::bind_method(D_METHOD("draw_texture", "texture", "position", "modulate", "normal_map"), &CanvasItem::draw_texture, DEFVAL(Color(1, 1, 1, 1)), DEFVAL(Variant()));
@@ -1131,8 +1156,8 @@ Rect2 CanvasItem::_edit_get_item_and_children_rect() const {
return rect;
}
-CanvasItem::CanvasItem()
- : xform_change(this) {
+CanvasItem::CanvasItem() :
+ xform_change(this) {
canvas_item = VisualServer::get_singleton()->canvas_item_create();
visible = true;
diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h
index ccbb528d6f..2384c0f370 100644
--- a/scene/2d/canvas_item.h
+++ b/scene/2d/canvas_item.h
@@ -268,6 +268,8 @@ public:
void draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width = 1.0, bool p_antialiased = false);
void draw_polyline(const Vector<Point2> &p_points, const Color &p_color, float p_width = 1.0, bool p_antialiased = false);
void draw_polyline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = 1.0, bool p_antialiased = false);
+ void draw_multiline(const Vector<Point2> &p_points, const Color &p_color, float p_width = 1.0, bool p_antialiased = false);
+ void draw_multiline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = 1.0, bool p_antialiased = false);
void draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled = true);
void draw_circle(const Point2 &p_pos, float p_radius, const Color &p_color);
void draw_texture(const Ref<Texture> &p_texture, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1, 1), const Ref<Texture> &p_normal_map = Ref<Texture>());
diff --git a/scene/2d/line_2d.cpp b/scene/2d/line_2d.cpp
index 9131223ff3..57a0e15447 100644
--- a/scene/2d/line_2d.cpp
+++ b/scene/2d/line_2d.cpp
@@ -37,8 +37,8 @@ VARIANT_ENUM_CAST(Line2D::LineJointMode)
VARIANT_ENUM_CAST(Line2D::LineCapMode)
VARIANT_ENUM_CAST(Line2D::LineTextureMode)
-Line2D::Line2D()
- : Node2D() {
+Line2D::Line2D() :
+ Node2D() {
_joint_mode = LINE_JOINT_SHARP;
_begin_cap_mode = LINE_CAP_NONE;
_end_cap_mode = LINE_CAP_NONE;
diff --git a/scene/2d/navigation2d.h b/scene/2d/navigation2d.h
index e87b01f7c5..bb97e1a9a9 100644
--- a/scene/2d/navigation2d.h
+++ b/scene/2d/navigation2d.h
@@ -57,9 +57,9 @@ class Navigation2D : public Node2D {
return (a.key == p_key.a.key) ? (b.key < p_key.b.key) : (a.key < p_key.a.key);
};
- EdgeKey(const Point &p_a = Point(), const Point &p_b = Point())
- : a(p_a),
- b(p_b) {
+ EdgeKey(const Point &p_a = Point(), const Point &p_b = Point()) :
+ a(p_a),
+ b(p_b) {
if (a.key > b.key) {
SWAP(a, b);
}
diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp
index e1c7331393..4029ef137b 100644
--- a/scene/2d/path_2d.cpp
+++ b/scene/2d/path_2d.cpp
@@ -107,34 +107,56 @@ void PathFollow2D::_update_transform() {
if (!c.is_valid())
return;
- if (delta_offset == 0) {
- return;
- }
-
- float o = offset;
+ float path_length = c->get_baked_length();
+ float bounded_offset = offset;
if (loop)
- o = Math::fposmod(o, c->get_baked_length());
-
- Vector2 pos = c->interpolate_baked(o, cubic);
+ bounded_offset = Math::fposmod(bounded_offset, path_length);
+ else
+ bounded_offset = CLAMP(bounded_offset, 0, path_length);
- Vector2 displacement_offset = Vector2(h_offset, v_offset);
+ Vector2 pos = c->interpolate_baked(bounded_offset, cubic);
if (rotate) {
+ float ahead = bounded_offset + lookahead;
+
+ if (loop && ahead >= path_length) {
+ // If our lookahead will loop, we need to check if the path is closed.
+ int point_count = c->get_point_count();
+ if (point_count > 0) {
+ Vector2 start_point = c->get_point_position(0);
+ Vector2 end_point = c->get_point_position(point_count - 1);
+ if (start_point == end_point) {
+ // Since the path is closed we want to 'smooth off'
+ // the corner at the start/end.
+ // So we wrap the lookahead back round.
+ ahead = Math::fmod(ahead, path_length);
+ }
+ }
+ }
+
+ Vector2 ahead_pos = c->interpolate_baked(ahead, cubic);
- Vector2 t_prev = (pos - c->interpolate_baked(o - delta_offset, cubic)).normalized();
- Vector2 t_next = (c->interpolate_baked(o + delta_offset, cubic) - pos).normalized();
+ Vector2 tangent_to_curve;
+ if (ahead_pos == pos) {
+ // This will happen at the end of non-looping or non-closed paths.
+ // We'll try a look behind instead, in order to get a meaningful angle.
+ tangent_to_curve =
+ (pos - c->interpolate_baked(bounded_offset - lookahead, cubic)).normalized();
+ } else {
+ tangent_to_curve = (ahead_pos - pos).normalized();
+ }
- float angle = t_prev.angle_to(t_next);
+ Vector2 normal_of_curve = -tangent_to_curve.tangent();
- set_rotation(get_rotation() + angle);
+ pos += tangent_to_curve * h_offset;
+ pos += normal_of_curve * v_offset;
- Vector2 n = t_next;
- Vector2 t = -n.tangent();
- pos += n * h_offset + t * v_offset;
+ set_rotation(tangent_to_curve.angle());
} else {
- pos += displacement_offset;
+ pos.x += h_offset;
+ pos.y += v_offset;
}
set_position(pos);
@@ -185,6 +207,8 @@ bool PathFollow2D::_set(const StringName &p_name, const Variant &p_value) {
set_cubic_interpolation(p_value);
} else if (String(p_name) == "loop") {
set_loop(p_value);
+ } else if (String(p_name) == "lookahead") {
+ set_lookahead(p_value);
} else
return false;
@@ -207,6 +231,8 @@ bool PathFollow2D::_get(const StringName &p_name, Variant &r_ret) const {
r_ret = cubic;
} else if (String(p_name) == "loop") {
r_ret = loop;
+ } else if (String(p_name) == "lookahead") {
+ r_ret = lookahead;
} else
return false;
@@ -224,6 +250,7 @@ void PathFollow2D::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::BOOL, "rotate"));
p_list->push_back(PropertyInfo(Variant::BOOL, "cubic_interp"));
p_list->push_back(PropertyInfo(Variant::BOOL, "loop"));
+ p_list->push_back(PropertyInfo(Variant::REAL, "lookahead", PROPERTY_HINT_RANGE, "0.001,1024.0,0.001"));
}
String PathFollow2D::get_configuration_warning() const {
@@ -263,7 +290,7 @@ void PathFollow2D::_bind_methods() {
}
void PathFollow2D::set_offset(float p_offset) {
- delta_offset = p_offset - offset;
+
offset = p_offset;
if (path)
_update_transform();
@@ -314,6 +341,16 @@ float PathFollow2D::get_unit_offset() const {
return 0;
}
+void PathFollow2D::set_lookahead(float p_lookahead) {
+
+ lookahead = p_lookahead;
+}
+
+float PathFollow2D::get_lookahead() const {
+
+ return lookahead;
+}
+
void PathFollow2D::set_rotate(bool p_rotate) {
rotate = p_rotate;
@@ -338,11 +375,11 @@ bool PathFollow2D::has_loop() const {
PathFollow2D::PathFollow2D() {
offset = 0;
- delta_offset = 0;
h_offset = 0;
v_offset = 0;
path = NULL;
rotate = true;
cubic = true;
loop = true;
+ lookahead = 4;
}
diff --git a/scene/2d/path_2d.h b/scene/2d/path_2d.h
index f5ba3a3d32..88a0abdea9 100644
--- a/scene/2d/path_2d.h
+++ b/scene/2d/path_2d.h
@@ -60,9 +60,9 @@ public:
private:
Path2D *path;
real_t offset;
- real_t delta_offset; // change in offset since last _update_transform
real_t h_offset;
real_t v_offset;
+ real_t lookahead;
bool cubic;
bool loop;
bool rotate;
@@ -90,6 +90,9 @@ public:
void set_unit_offset(float p_unit_offset);
float get_unit_offset() const;
+ void set_lookahead(float p_lookahead);
+ float get_lookahead() const;
+
void set_loop(bool p_loop);
bool has_loop() const;
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index 1f6127e6eb..a1a1101b11 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -132,8 +132,8 @@ bool PhysicsBody2D::get_collision_layer_bit(int p_bit) const {
return get_collision_layer() & (1 << p_bit);
}
-PhysicsBody2D::PhysicsBody2D(Physics2DServer::BodyMode p_mode)
- : CollisionObject2D(Physics2DServer::get_singleton()->body_create(), false) {
+PhysicsBody2D::PhysicsBody2D(Physics2DServer::BodyMode p_mode) :
+ CollisionObject2D(Physics2DServer::get_singleton()->body_create(), false) {
Physics2DServer::get_singleton()->body_set_mode(get_rid(), p_mode);
collision_layer = 1;
@@ -226,8 +226,8 @@ void StaticBody2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_bounce", "get_bounce");
}
-StaticBody2D::StaticBody2D()
- : PhysicsBody2D(Physics2DServer::BODY_MODE_STATIC) {
+StaticBody2D::StaticBody2D() :
+ PhysicsBody2D(Physics2DServer::BODY_MODE_STATIC) {
constant_angular_velocity = 0;
bounce = 0;
@@ -921,8 +921,8 @@ void RigidBody2D::_bind_methods() {
BIND_ENUM_CONSTANT(CCD_MODE_CAST_SHAPE);
}
-RigidBody2D::RigidBody2D()
- : PhysicsBody2D(Physics2DServer::BODY_MODE_RIGID) {
+RigidBody2D::RigidBody2D() :
+ PhysicsBody2D(Physics2DServer::BODY_MODE_RIGID) {
mode = MODE_RIGID;
@@ -1144,8 +1144,8 @@ void KinematicBody2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin");
}
-KinematicBody2D::KinematicBody2D()
- : PhysicsBody2D(Physics2DServer::BODY_MODE_KINEMATIC) {
+KinematicBody2D::KinematicBody2D() :
+ PhysicsBody2D(Physics2DServer::BODY_MODE_KINEMATIC) {
margin = 0.08;
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index c0d0a6e011..5a32a3d0f0 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -513,16 +513,13 @@ void TileMap::_update_dirty_quadrants() {
}
Ref<OccluderPolygon2D> occluder;
- Vector2 occluder_ofs;
if (tile_set->tile_get_is_autotile(c.id)) {
occluder = tile_set->autotile_get_light_occluder(c.id, Vector2(c.autotile_coord_x, c.autotile_coord_y));
- occluder_ofs = tile_set->tile_get_occluder_offset(c.id);
} else {
occluder = tile_set->tile_get_light_occluder(c.id);
- occluder_ofs = Vector2();
}
if (occluder.is_valid()) {
-
+ Vector2 occluder_ofs = tile_set->tile_get_occluder_offset(c.id);
Transform2D xform;
xform.set_origin(offset.floor() + q.pos);
_fix_cell_transform(xform, c, occluder_ofs + center_ofs, s);
@@ -968,14 +965,14 @@ void TileMap::_set_tile_data(const PoolVector<int> &p_data) {
int c = p_data.size();
PoolVector<int>::Read r = p_data.read();
- int offset = (format == FORMAT_2_1_5) ? 3 : 2;
+ int offset = (format == FORMAT_2) ? 3 : 2;
clear();
for (int i = 0; i < c; i += offset) {
const uint8_t *ptr = (const uint8_t *)&r[i];
uint8_t local[12];
- for (int j = 0; j < ((format == FORMAT_2_1_5) ? 12 : 8); j++)
+ for (int j = 0; j < ((format == FORMAT_2) ? 12 : 8); j++)
local[j] = ptr[j];
#ifdef BIG_ENDIAN_ENABLED
@@ -985,7 +982,7 @@ void TileMap::_set_tile_data(const PoolVector<int> &p_data) {
SWAP(local[4], local[7]);
SWAP(local[5], local[6]);
//TODO: ask someone to check this...
- if (FORMAT == FORMAT_2_1_5) {
+ if (FORMAT == FORMAT_2) {
SWAP(local[8], local[11]);
SWAP(local[9], local[10]);
}
@@ -1000,7 +997,7 @@ void TileMap::_set_tile_data(const PoolVector<int> &p_data) {
v &= (1 << 29) - 1;
int16_t coord_x;
int16_t coord_y;
- if (format == FORMAT_2_1_5) {
+ if (format == FORMAT_2) {
coord_x = decode_uint16(&local[8]);
coord_y = decode_uint16(&local[10]);
}
@@ -1018,6 +1015,8 @@ PoolVector<int> TileMap::_get_tile_data() const {
data.resize(tile_map.size() * 3);
PoolVector<int>::Write w = data.write();
+ format = FORMAT_2;
+
int idx = 0;
for (const Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) {
uint8_t *ptr = (uint8_t *)&w[idx];
@@ -1298,7 +1297,7 @@ bool TileMap::_set(const StringName &p_name, const Variant &p_value) {
bool TileMap::_get(const StringName &p_name, Variant &r_ret) const {
if (p_name == "format") {
- r_ret = FORMAT_2_1_5;
+ r_ret = FORMAT_2;
return true;
} else if (p_name == "tile_data") {
r_ret = _get_tile_data();
@@ -1594,7 +1593,7 @@ TileMap::TileMap() {
y_sort_mode = false;
occluder_light_mask = 1;
clip_uv = false;
- format = FORMAT_2_1_4; //Always initialize with the lowest format
+ format = FORMAT_1; //Always initialize with the lowest format
fp_adjust = 0.00001;
tile_origin = TILE_ORIGIN_TOP_LEFT;
diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h
index 8eecf48df2..11d9915cb6 100644
--- a/scene/2d/tile_map.h
+++ b/scene/2d/tile_map.h
@@ -61,8 +61,8 @@ public:
private:
enum DataFormat {
- FORMAT_2_1_4 = 0,
- FORMAT_2_1_5
+ FORMAT_1 = 0,
+ FORMAT_2
};
Ref<TileSet> tile_set;
@@ -147,8 +147,8 @@ private:
navpoly_ids = q.navpoly_ids;
occluder_instances = q.occluder_instances;
}
- Quadrant(const Quadrant &q)
- : dirty_list(this) {
+ Quadrant(const Quadrant &q) :
+ dirty_list(this) {
pos = q.pos;
canvas_items = q.canvas_items;
body = q.body;
@@ -156,8 +156,8 @@ private:
occluder_instances = q.occluder_instances;
navpoly_ids = q.navpoly_ids;
}
- Quadrant()
- : dirty_list(this) {}
+ Quadrant() :
+ dirty_list(this) {}
};
Map<PosKey, Quadrant> quadrant_map;
@@ -178,7 +178,7 @@ private:
float bounce;
uint32_t collision_layer;
uint32_t collision_mask;
- DataFormat format;
+ mutable DataFormat format;
TileOrigin tile_origin;
diff --git a/scene/3d/area.cpp b/scene/3d/area.cpp
index 266bc5e381..422aa556f9 100644
--- a/scene/3d/area.cpp
+++ b/scene/3d/area.cpp
@@ -737,8 +737,8 @@ void Area::_bind_methods() {
BIND_ENUM_CONSTANT(SPACE_OVERRIDE_REPLACE_COMBINE);
}
-Area::Area()
- : CollisionObject(PhysicsServer::get_singleton()->area_create(), true) {
+Area::Area() :
+ CollisionObject(PhysicsServer::get_singleton()->area_create(), true) {
space_override = SPACE_OVERRIDE_DISABLED;
set_gravity(9.8);
diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp
index abc4a03498..af210fff1c 100644
--- a/scene/3d/camera.cpp
+++ b/scene/3d/camera.cpp
@@ -191,11 +191,12 @@ void Camera::_update_camera() {
get_viewport()->_camera_transform_changed_notify();
*/
- if (is_inside_tree() && is_current()) {
- get_viewport()->_camera_transform_changed_notify();
- }
+ if (!is_inside_tree() || get_tree()->is_node_being_edited(this) || !is_current())
+ return;
+
+ get_viewport()->_camera_transform_changed_notify();
- if (is_current() && get_world().is_valid()) {
+ if (get_world().is_valid()) {
get_world()->_update_camera(this);
}
}
diff --git a/scene/3d/gi_probe.cpp b/scene/3d/gi_probe.cpp
index 2754d56a05..1f2b43165e 100644
--- a/scene/3d/gi_probe.cpp
+++ b/scene/3d/gi_probe.cpp
@@ -410,7 +410,7 @@ static bool planeBoxOverlap(Vector3 normal, float d, Vector3 maxbox) {
rad = fa * boxhalfsize.x + fb * boxhalfsize.z; \
if (min > rad || max < -rad) return false;
-/*======================== Z-tests ========================*/
+ /*======================== Z-tests ========================*/
#define AXISTEST_Z12(a, b, fa, fb) \
p1 = a * v1.x - b * v1.y; \
@@ -1284,8 +1284,11 @@ void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug) {
_create_debug_mesh(&baker);
} else {
- Ref<GIProbeData> probe_data;
- probe_data.instance();
+ Ref<GIProbeData> probe_data = get_probe_data();
+
+ if (probe_data.is_null())
+ probe_data.instance();
+
probe_data->set_bounds(AABB(-extents, extents * 2.0));
probe_data->set_cell_size(baker.po2_bounds.size[longest_axis] / baker.axis_cell_size[longest_axis]);
probe_data->set_dynamic_data(data);
diff --git a/scene/3d/light.cpp b/scene/3d/light.cpp
index 126c07f0be..1fc4e932e8 100644
--- a/scene/3d/light.cpp
+++ b/scene/3d/light.cpp
@@ -367,8 +367,8 @@ void DirectionalLight::_bind_methods() {
BIND_ENUM_CONSTANT(SHADOW_DEPTH_RANGE_OPTIMIZED);
}
-DirectionalLight::DirectionalLight()
- : Light(VisualServer::LIGHT_DIRECTIONAL) {
+DirectionalLight::DirectionalLight() :
+ Light(VisualServer::LIGHT_DIRECTIONAL) {
set_param(PARAM_SHADOW_NORMAL_BIAS, 0.8);
set_param(PARAM_SHADOW_BIAS, 0.1);
@@ -422,8 +422,8 @@ void OmniLight::_bind_methods() {
BIND_ENUM_CONSTANT(SHADOW_DETAIL_HORIZONTAL);
}
-OmniLight::OmniLight()
- : Light(VisualServer::LIGHT_OMNI) {
+OmniLight::OmniLight() :
+ Light(VisualServer::LIGHT_OMNI) {
set_shadow_mode(SHADOW_CUBE);
set_shadow_detail(SHADOW_DETAIL_HORIZONTAL);
diff --git a/scene/3d/light.h b/scene/3d/light.h
index 8514b429ec..33e62214b1 100644
--- a/scene/3d/light.h
+++ b/scene/3d/light.h
@@ -208,8 +208,8 @@ protected:
static void _bind_methods();
public:
- SpotLight()
- : Light(VisualServer::LIGHT_SPOT) {}
+ SpotLight() :
+ Light(VisualServer::LIGHT_SPOT) {}
};
#endif
diff --git a/scene/3d/navigation.h b/scene/3d/navigation.h
index 010d16dedd..d9a38f7b00 100644
--- a/scene/3d/navigation.h
+++ b/scene/3d/navigation.h
@@ -58,9 +58,9 @@ class Navigation : public Spatial {
return (a.key == p_key.a.key) ? (b.key < p_key.b.key) : (a.key < p_key.a.key);
};
- EdgeKey(const Point &p_a = Point(), const Point &p_b = Point())
- : a(p_a),
- b(p_b) {
+ EdgeKey(const Point &p_a = Point(), const Point &p_b = Point()) :
+ a(p_a),
+ b(p_b) {
if (a.key > b.key) {
SWAP(a, b);
}
diff --git a/scene/3d/particles.cpp b/scene/3d/particles.cpp
index f8685a7b7c..821f1a5a78 100644
--- a/scene/3d/particles.cpp
+++ b/scene/3d/particles.cpp
@@ -703,10 +703,13 @@ void ParticlesMaterial::_update_shader() {
else
code += " float tex_linear_velocity = 0.0;\n";
- if (tex_parameters[PARAM_ORBIT_VELOCITY].is_valid())
- code += " float tex_orbit_velocity = textureLod(orbit_velocity_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
- else
- code += " float tex_orbit_velocity = 0.0;\n";
+ if (flags[FLAG_DISABLE_Z]) {
+
+ if (tex_parameters[PARAM_ORBIT_VELOCITY].is_valid())
+ code += " float tex_orbit_velocity = textureLod(orbit_velocity_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
+ else
+ code += " float tex_orbit_velocity = 0.0;\n";
+ }
if (tex_parameters[PARAM_ANGULAR_VELOCITY].is_valid())
code += " float tex_angular_velocity = textureLod(angular_velocity_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
@@ -756,7 +759,7 @@ void ParticlesMaterial::_update_shader() {
code += " //apply linear acceleration\n";
code += " force += length(VELOCITY) > 0.0 ? normalize(VELOCITY) * (linear_accel+tex_linear_accel)*mix(1.0,rand_from_seed(alt_seed),linear_accel_random) : vec3(0.0);\n";
code += " //apply radial acceleration\n";
- code += " vec3 org = vec3(0.0);\n";
+ code += " vec3 org = EMISSION_TRANSFORM[3].xyz;\n";
code += " vec3 diff = pos-org;\n";
code += " force += length(diff) > 0.0 ? normalize(diff) * (radial_accel+tex_radial_accel)*mix(1.0,rand_from_seed(alt_seed),radial_accel_random) : vec3(0.0);\n";
code += " //apply tangential acceleration;\n";
@@ -769,6 +772,18 @@ void ParticlesMaterial::_update_shader() {
}
code += " //apply attractor forces\n";
code += " VELOCITY += force * DELTA;\n";
+ code += " //orbit velocity\n";
+ if (flags[FLAG_DISABLE_Z]) {
+
+ code += " float orbit_amount = (orbit_velocity+tex_orbit_velocity)*mix(1.0,rand_from_seed(alt_seed),orbit_velocity_random);\n";
+ code += " if (orbit_amount!=0.0) {\n";
+ code += " float ang = orbit_amount * DELTA * 3.1416 * 2.0;\n";
+ code += " mat2 rot = mat2(vec2(cos(ang),-sin(ang)),vec2(sin(ang),cos(ang)));\n";
+ code += " TRANSFORM[3].xy-=diff.xy;\n";
+ code += " TRANSFORM[3].xy+=rot * diff.xy;\n";
+ code += " }\n";
+ }
+
if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) {
code += " VELOCITY = normalize(VELOCITY)*tex_linear_velocity;\n";
}
@@ -1174,6 +1189,9 @@ void ParticlesMaterial::set_flag(Flags p_flag, bool p_enable) {
ERR_FAIL_INDEX(p_flag, FLAG_MAX);
flags[p_flag] = p_enable;
_queue_shader_change();
+ if (p_flag == FLAG_DISABLE_Z) {
+ _change_notify();
+ }
}
bool ParticlesMaterial::get_flag(Flags p_flag) const {
@@ -1359,6 +1377,10 @@ void ParticlesMaterial::_validate_property(PropertyInfo &property) const {
if (property.name == "emission_point_count" && (emission_shape != EMISSION_SHAPE_POINTS && emission_shape != EMISSION_SHAPE_DIRECTED_POINTS)) {
property.usage = 0;
}
+
+ if (property.name.begins_with("orbit_") && !flags[FLAG_DISABLE_Z]) {
+ property.usage = 0;
+ }
}
Shader::Mode ParticlesMaterial::get_shader_mode() const {
@@ -1523,8 +1545,8 @@ void ParticlesMaterial::_bind_methods() {
BIND_ENUM_CONSTANT(EMISSION_SHAPE_DIRECTED_POINTS);
}
-ParticlesMaterial::ParticlesMaterial()
- : element(this) {
+ParticlesMaterial::ParticlesMaterial() :
+ element(this) {
set_spread(45);
set_flatness(0);
diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp
index 4e06b272e2..8c9f59e267 100644
--- a/scene/3d/physics_body.cpp
+++ b/scene/3d/physics_body.cpp
@@ -166,8 +166,8 @@ void PhysicsBody::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask");
}
-PhysicsBody::PhysicsBody(PhysicsServer::BodyMode p_mode)
- : CollisionObject(PhysicsServer::get_singleton()->body_create(p_mode), false) {
+PhysicsBody::PhysicsBody(PhysicsServer::BodyMode p_mode) :
+ CollisionObject(PhysicsServer::get_singleton()->body_create(p_mode), false) {
collision_layer = 1;
collision_mask = 1;
@@ -241,8 +241,8 @@ void StaticBody::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "constant_angular_velocity"), "set_constant_angular_velocity", "get_constant_angular_velocity");
}
-StaticBody::StaticBody()
- : PhysicsBody(PhysicsServer::BODY_MODE_STATIC) {
+StaticBody::StaticBody() :
+ PhysicsBody(PhysicsServer::BODY_MODE_STATIC) {
bounce = 0;
friction = 1;
@@ -734,15 +734,31 @@ bool RigidBody::is_contact_monitor_enabled() const {
return contact_monitor != NULL;
}
-void RigidBody::set_axis_lock(AxisLock p_lock) {
+void RigidBody::set_axis_lock_x(bool p_lock) {
+ RigidBody::locked_axis[0] = p_lock;
+ PhysicsServer::get_singleton()->body_set_axis_lock(get_rid(), 0, locked_axis[0]);
+}
+
+void RigidBody::set_axis_lock_y(bool p_lock) {
+ RigidBody::locked_axis[1] = p_lock;
+ PhysicsServer::get_singleton()->body_set_axis_lock(get_rid(), 1, locked_axis[1]);
+}
+
+void RigidBody::set_axis_lock_z(bool p_lock) {
+ RigidBody::locked_axis[2] = p_lock;
+ PhysicsServer::get_singleton()->body_set_axis_lock(get_rid(), 2, locked_axis[2]);
+}
- axis_lock = p_lock;
- PhysicsServer::get_singleton()->body_set_axis_lock(get_rid(), PhysicsServer::BodyAxisLock(axis_lock));
+bool RigidBody::get_axis_lock_x() const {
+ return RigidBody::locked_axis[0];
}
-RigidBody::AxisLock RigidBody::get_axis_lock() const {
+bool RigidBody::get_axis_lock_y() const {
+ return RigidBody::locked_axis[1];
+}
- return axis_lock;
+bool RigidBody::get_axis_lock_z() const {
+ return RigidBody::locked_axis[2];
}
Array RigidBody::get_colliding_bodies() const {
@@ -837,8 +853,12 @@ void RigidBody::_bind_methods() {
ClassDB::bind_method(D_METHOD("_body_enter_tree"), &RigidBody::_body_enter_tree);
ClassDB::bind_method(D_METHOD("_body_exit_tree"), &RigidBody::_body_exit_tree);
- ClassDB::bind_method(D_METHOD("set_axis_lock", "axis_lock"), &RigidBody::set_axis_lock);
- ClassDB::bind_method(D_METHOD("get_axis_lock"), &RigidBody::get_axis_lock);
+ ClassDB::bind_method(D_METHOD("set_axis_lock_x", "axis_lock_x"), &RigidBody::set_axis_lock_x);
+ ClassDB::bind_method(D_METHOD("set_axis_lock_y", "axis_lock_y"), &RigidBody::set_axis_lock_y);
+ ClassDB::bind_method(D_METHOD("set_axis_lock_z", "axis_lock_z"), &RigidBody::set_axis_lock_z);
+ ClassDB::bind_method(D_METHOD("get_axis_lock_x"), &RigidBody::get_axis_lock_x);
+ ClassDB::bind_method(D_METHOD("get_axis_lock_y"), &RigidBody::get_axis_lock_y);
+ ClassDB::bind_method(D_METHOD("get_axis_lock_z"), &RigidBody::get_axis_lock_z);
ClassDB::bind_method(D_METHOD("get_colliding_bodies"), &RigidBody::get_colliding_bodies);
@@ -856,7 +876,10 @@ void RigidBody::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "contact_monitor"), "set_contact_monitor", "is_contact_monitor_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sleeping"), "set_sleeping", "is_sleeping");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "can_sleep"), "set_can_sleep", "is_able_to_sleep");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "axis_lock", PROPERTY_HINT_ENUM, "Disabled,Lock X,Lock Y,Lock Z"), "set_axis_lock", "get_axis_lock");
+ ADD_GROUP("Axis Lock", "axis_lock_");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "axis_lock_x"), "set_axis_lock_x", "get_axis_lock_x");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "axis_lock_y"), "set_axis_lock_y", "get_axis_lock_y");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "axis_lock_z"), "set_axis_lock_z", "get_axis_lock_z");
ADD_GROUP("Linear", "linear_");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "linear_velocity"), "set_linear_velocity", "get_linear_velocity");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "linear_damp", PROPERTY_HINT_RANGE, "-1,128,0.01"), "set_linear_damp", "get_linear_damp");
@@ -874,15 +897,10 @@ void RigidBody::_bind_methods() {
BIND_ENUM_CONSTANT(MODE_STATIC);
BIND_ENUM_CONSTANT(MODE_CHARACTER);
BIND_ENUM_CONSTANT(MODE_KINEMATIC);
-
- BIND_ENUM_CONSTANT(AXIS_LOCK_DISABLED);
- BIND_ENUM_CONSTANT(AXIS_LOCK_X);
- BIND_ENUM_CONSTANT(AXIS_LOCK_Y);
- BIND_ENUM_CONSTANT(AXIS_LOCK_Z);
}
-RigidBody::RigidBody()
- : PhysicsBody(PhysicsServer::BODY_MODE_RIGID) {
+RigidBody::RigidBody() :
+ PhysicsBody(PhysicsServer::BODY_MODE_RIGID) {
mode = MODE_RIGID;
@@ -904,8 +922,6 @@ RigidBody::RigidBody()
contact_monitor = NULL;
can_sleep = true;
- axis_lock = AXIS_LOCK_DISABLED;
-
PhysicsServer::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed");
}
@@ -952,6 +968,12 @@ bool KinematicBody::move_and_collide(const Vector3 &p_motion, Collision &r_colli
r_collision.local_shape = result.collision_local_shape;
}
+ for (int i = 0; i < 3; i++) {
+ if (locked_axis[i]) {
+ result.motion[i] = 0;
+ }
+ }
+
gt.origin += result.motion;
set_global_transform(gt);
@@ -960,9 +982,16 @@ bool KinematicBody::move_and_collide(const Vector3 &p_motion, Collision &r_colli
Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction, float p_slope_stop_min_velocity, int p_max_slides, float p_floor_max_angle) {
- Vector3 motion = (floor_velocity + p_linear_velocity) * get_physics_process_delta_time();
Vector3 lv = p_linear_velocity;
+ for (int i = 0; i < 3; i++) {
+ if (locked_axis[i]) {
+ lv[i] = 0;
+ }
+ }
+
+ Vector3 motion = (floor_velocity + lv) * get_physics_process_delta_time();
+
on_floor = false;
on_ceiling = false;
on_wall = false;
@@ -1008,6 +1037,12 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve
motion = motion.slide(n);
lv = lv.slide(n);
+ for (int i = 0; i < 3; i++) {
+ if (locked_axis[i]) {
+ lv[i] = 0;
+ }
+ }
+
colliders.push_back(collision);
} else {
@@ -1047,6 +1082,33 @@ bool KinematicBody::test_move(const Transform &p_from, const Vector3 &p_motion)
return PhysicsServer::get_singleton()->body_test_motion(get_rid(), p_from, p_motion);
}
+void KinematicBody::set_axis_lock_x(bool p_lock) {
+ KinematicBody::locked_axis[0] = p_lock;
+ PhysicsServer::get_singleton()->body_set_axis_lock(get_rid(), 0, locked_axis[0]);
+}
+
+void KinematicBody::set_axis_lock_y(bool p_lock) {
+ KinematicBody::locked_axis[1] = p_lock;
+ PhysicsServer::get_singleton()->body_set_axis_lock(get_rid(), 1, locked_axis[1]);
+}
+
+void KinematicBody::set_axis_lock_z(bool p_lock) {
+ KinematicBody::locked_axis[2] = p_lock;
+ PhysicsServer::get_singleton()->body_set_axis_lock(get_rid(), 2, locked_axis[2]);
+}
+
+bool KinematicBody::get_axis_lock_x() const {
+ return KinematicBody::locked_axis[0];
+}
+
+bool KinematicBody::get_axis_lock_y() const {
+ return KinematicBody::locked_axis[1];
+}
+
+bool KinematicBody::get_axis_lock_z() const {
+ return KinematicBody::locked_axis[2];
+}
+
void KinematicBody::set_safe_margin(float p_margin) {
margin = p_margin;
@@ -1095,17 +1157,29 @@ void KinematicBody::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_on_wall"), &KinematicBody::is_on_wall);
ClassDB::bind_method(D_METHOD("get_floor_velocity"), &KinematicBody::get_floor_velocity);
+ ClassDB::bind_method(D_METHOD("set_axis_lock_x", "axis_lock_x"), &KinematicBody::set_axis_lock_x);
+ ClassDB::bind_method(D_METHOD("set_axis_lock_y", "axis_lock_y"), &KinematicBody::set_axis_lock_y);
+ ClassDB::bind_method(D_METHOD("set_axis_lock_z", "axis_lock_z"), &KinematicBody::set_axis_lock_z);
+ ClassDB::bind_method(D_METHOD("get_axis_lock_x"), &KinematicBody::get_axis_lock_x);
+ ClassDB::bind_method(D_METHOD("get_axis_lock_y"), &KinematicBody::get_axis_lock_y);
+ ClassDB::bind_method(D_METHOD("get_axis_lock_z"), &KinematicBody::get_axis_lock_z);
+
ClassDB::bind_method(D_METHOD("set_safe_margin", "pixels"), &KinematicBody::set_safe_margin);
ClassDB::bind_method(D_METHOD("get_safe_margin"), &KinematicBody::get_safe_margin);
ClassDB::bind_method(D_METHOD("get_slide_count"), &KinematicBody::get_slide_count);
ClassDB::bind_method(D_METHOD("get_slide_collision", "slide_idx"), &KinematicBody::_get_slide_collision);
+ ADD_GROUP("Axis Lock", "axis_lock_");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "axis_lock_x"), "set_axis_lock_x", "get_axis_lock_x");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "axis_lock_y"), "set_axis_lock_y", "get_axis_lock_y");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "axis_lock_z"), "set_axis_lock_z", "get_axis_lock_z");
+
ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin");
}
-KinematicBody::KinematicBody()
- : PhysicsBody(PhysicsServer::BODY_MODE_KINEMATIC) {
+KinematicBody::KinematicBody() :
+ PhysicsBody(PhysicsServer::BODY_MODE_KINEMATIC) {
margin = 0.001;
diff --git a/scene/3d/physics_body.h b/scene/3d/physics_body.h
index f88b3860dc..57b120ef63 100644
--- a/scene/3d/physics_body.h
+++ b/scene/3d/physics_body.h
@@ -114,13 +114,6 @@ public:
MODE_KINEMATIC,
};
- enum AxisLock {
- AXIS_LOCK_DISABLED,
- AXIS_LOCK_X,
- AXIS_LOCK_Y,
- AXIS_LOCK_Z,
- };
-
private:
bool can_sleep;
PhysicsDirectBodyState *state;
@@ -139,7 +132,7 @@ private:
bool sleeping;
bool ccd;
- AxisLock axis_lock;
+ bool locked_axis[3] = { false, false, false };
int max_contacts_reported;
@@ -245,8 +238,12 @@ public:
void set_use_continuous_collision_detection(bool p_enable);
bool is_using_continuous_collision_detection() const;
- void set_axis_lock(AxisLock p_lock);
- AxisLock get_axis_lock() const;
+ void set_axis_lock_x(bool p_lock);
+ void set_axis_lock_y(bool p_lock);
+ void set_axis_lock_z(bool p_lock);
+ bool get_axis_lock_x() const;
+ bool get_axis_lock_y() const;
+ bool get_axis_lock_z() const;
Array get_colliding_bodies() const;
@@ -259,7 +256,6 @@ public:
};
VARIANT_ENUM_CAST(RigidBody::Mode);
-VARIANT_ENUM_CAST(RigidBody::AxisLock);
class KinematicCollision;
@@ -281,6 +277,8 @@ public:
};
private:
+ bool locked_axis[3] = { false, false, false };
+
float margin;
Vector3 floor_velocity;
@@ -303,6 +301,13 @@ public:
bool move_and_collide(const Vector3 &p_motion, Collision &r_collision);
bool test_move(const Transform &p_from, const Vector3 &p_motion);
+ void set_axis_lock_x(bool p_lock);
+ void set_axis_lock_y(bool p_lock);
+ void set_axis_lock_z(bool p_lock);
+ bool get_axis_lock_x() const;
+ bool get_axis_lock_y() const;
+ bool get_axis_lock_z() const;
+
void set_safe_margin(float p_margin);
float get_safe_margin() const;
diff --git a/scene/3d/spatial.cpp b/scene/3d/spatial.cpp
index 588aa2881a..d9f88ac693 100644
--- a/scene/3d/spatial.cpp
+++ b/scene/3d/spatial.cpp
@@ -756,8 +756,8 @@ void Spatial::_bind_methods() {
ADD_SIGNAL(MethodInfo("visibility_changed"));
}
-Spatial::Spatial()
- : xform_change(this) {
+Spatial::Spatial() :
+ xform_change(this) {
data.dirty = DIRTY_NONE;
data.children_lock = 0;
diff --git a/scene/3d/vehicle_body.cpp b/scene/3d/vehicle_body.cpp
index a072572142..2e3e179a7b 100644
--- a/scene/3d/vehicle_body.cpp
+++ b/scene/3d/vehicle_body.cpp
@@ -54,8 +54,8 @@ public:
const Vector3 &inertiaInvA,
const real_t massInvA,
const Vector3 &inertiaInvB,
- const real_t massInvB)
- : m_linearJointAxis(jointAxis) {
+ const real_t massInvB) :
+ m_linearJointAxis(jointAxis) {
m_aJ = world2A.xform(rel_pos1.cross(m_linearJointAxis));
m_bJ = world2B.xform(rel_pos2.cross(-m_linearJointAxis));
m_0MinvJt = inertiaInvA * m_aJ;
@@ -593,12 +593,12 @@ void VehicleBody::_resolve_single_bilateral(PhysicsDirectBodyState *s, const Vec
#endif
}
-VehicleBody::btVehicleWheelContactPoint::btVehicleWheelContactPoint(PhysicsDirectBodyState *s, PhysicsBody *body1, const Vector3 &frictionPosWorld, const Vector3 &frictionDirectionWorld, real_t maxImpulse)
- : m_s(s),
- m_body1(body1),
- m_frictionPositionWorld(frictionPosWorld),
- m_frictionDirectionWorld(frictionDirectionWorld),
- m_maxImpulse(maxImpulse) {
+VehicleBody::btVehicleWheelContactPoint::btVehicleWheelContactPoint(PhysicsDirectBodyState *s, PhysicsBody *body1, const Vector3 &frictionPosWorld, const Vector3 &frictionDirectionWorld, real_t maxImpulse) :
+ m_s(s),
+ m_body1(body1),
+ m_frictionPositionWorld(frictionPosWorld),
+ m_frictionDirectionWorld(frictionDirectionWorld),
+ m_maxImpulse(maxImpulse) {
float denom0 = 0;
float denom1 = 0;
@@ -969,8 +969,8 @@ void VehicleBody::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "friction", PROPERTY_HINT_RANGE, "0.01,1,0.01"), "set_friction", "get_friction");
}
-VehicleBody::VehicleBody()
- : PhysicsBody(PhysicsServer::BODY_MODE_RIGID) {
+VehicleBody::VehicleBody() :
+ PhysicsBody(PhysicsServer::BODY_MODE_RIGID) {
m_pitchControl = 0;
m_currentVehicleSpeedKmHour = real_t(0.);
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index f3e750d0da..e866e665d8 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -364,6 +364,9 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
if (!nc) // no node cache for this track, skip it
continue;
+ if (!a->track_is_enabled(i))
+ continue; // do nothing if the track is disabled
+
if (a->track_get_key_count(i) == 0)
continue; // do nothing if track is empty
@@ -1325,8 +1328,6 @@ void AnimationPlayer::_bind_methods() {
ClassDB::bind_method(D_METHOD("seek", "seconds", "update"), &AnimationPlayer::seek, DEFVAL(false));
ClassDB::bind_method(D_METHOD("advance", "delta"), &AnimationPlayer::advance);
- ClassDB::bind_method(D_METHOD("get_anim_position"), &AnimationPlayer::get_current_animation_position);
- ClassDB::bind_method(D_METHOD("get_anim_length"), &AnimationPlayer::get_current_animation_length);
ClassDB::bind_method(D_METHOD("find_animation", "animation"), &AnimationPlayer::find_animation);
@@ -1335,6 +1336,9 @@ void AnimationPlayer::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_animation_process_mode", "mode"), &AnimationPlayer::set_animation_process_mode);
ClassDB::bind_method(D_METHOD("get_animation_process_mode"), &AnimationPlayer::get_animation_process_mode);
+ ClassDB::bind_method(D_METHOD("get_current_animation_position"), &AnimationPlayer::get_current_animation_position);
+ ClassDB::bind_method(D_METHOD("get_current_animation_length"), &AnimationPlayer::get_current_animation_length);
+
ADD_GROUP("Playback Options", "playback_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "playback_process_mode", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_animation_process_mode", "get_animation_process_mode");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "playback_default_blend_time", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_default_blend_time", "get_default_blend_time");
@@ -1343,7 +1347,7 @@ void AnimationPlayer::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::STRING, "autoplay"), "set_autoplay", "get_autoplay");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "speed_scale"), "set_speed_scale", "get_speed_scale");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "active"), "set_active", "is_active");
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_anim"), "set_current_anim", "get_current_anim");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_animation"), "set_current_animation", "get_current_animation");
ADD_SIGNAL(MethodInfo("animation_finished", PropertyInfo(Variant::STRING, "name")));
ADD_SIGNAL(MethodInfo("animation_changed", PropertyInfo(Variant::STRING, "old_name"), PropertyInfo(Variant::STRING, "new_name")));
diff --git a/scene/animation/animation_tree_player.cpp b/scene/animation/animation_tree_player.cpp
index 23eccec82f..32f82fe6b8 100644
--- a/scene/animation/animation_tree_player.cpp
+++ b/scene/animation/animation_tree_player.cpp
@@ -831,7 +831,7 @@ void AnimationTreePlayer::_process_animation(float p_delta) {
for (List<AnimationNode::TrackRef>::Element *E = anim_list->tref.front(); E; E = E->next()) {
AnimationNode::TrackRef &tr = E->get();
- if (tr.track == NULL || tr.local_track < 0 || tr.weight < CMP_EPSILON)
+ if (tr.track == NULL || tr.local_track < 0 || tr.weight < CMP_EPSILON || !a->track_is_enabled(tr.local_track))
continue;
switch (a->track_get_type(tr.local_track)) {
@@ -1796,6 +1796,10 @@ void AnimationTreePlayer::_bind_methods() {
ADD_GROUP("Playback", "playback_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "playback_process_mode", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_animation_process_mode", "get_animation_process_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "master_player"), "set_master_player", "get_master_player");
+ ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "base_path"), "set_base_path", "get_base_path");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "active"), "set_active", "is_active");
+
BIND_ENUM_CONSTANT(NODE_OUTPUT);
BIND_ENUM_CONSTANT(NODE_ANIMATION);
BIND_ENUM_CONSTANT(NODE_ONESHOT);
diff --git a/scene/animation/tween_interpolaters.cpp b/scene/animation/tween_interpolaters.cpp
index 8f543a575a..cbf941f3ed 100644
--- a/scene/animation/tween_interpolaters.cpp
+++ b/scene/animation/tween_interpolaters.cpp
@@ -50,7 +50,7 @@ static real_t in_out(real_t t, real_t b, real_t c, real_t d) {
static real_t out_in(real_t t, real_t b, real_t c, real_t d) {
return c * t / d + b;
}
-};
+}; // namespace linear
///////////////////////////////////////////////////////////////////////////
// sine
///////////////////////////////////////////////////////////////////////////
@@ -70,7 +70,7 @@ static real_t in_out(real_t t, real_t b, real_t c, real_t d) {
static real_t out_in(real_t t, real_t b, real_t c, real_t d) {
return (t < d / 2) ? out(t * 2, b, c / 2, d) : in((t * 2) - d, b + c / 2, c / 2, d);
}
-};
+}; // namespace sine
///////////////////////////////////////////////////////////////////////////
// quint
///////////////////////////////////////////////////////////////////////////
@@ -92,7 +92,7 @@ static real_t in_out(real_t t, real_t b, real_t c, real_t d) {
static real_t out_in(real_t t, real_t b, real_t c, real_t d) {
return (t < d / 2) ? out(t * 2, b, c / 2, d) : in((t * 2) - d, b + c / 2, c / 2, d);
}
-};
+}; // namespace quint
///////////////////////////////////////////////////////////////////////////
// quart
///////////////////////////////////////////////////////////////////////////
@@ -114,7 +114,7 @@ static real_t in_out(real_t t, real_t b, real_t c, real_t d) {
static real_t out_in(real_t t, real_t b, real_t c, real_t d) {
return (t < d / 2) ? out(t * 2, b, c / 2, d) : in((t * 2) - d, b + c / 2, c / 2, d);
}
-};
+}; // namespace quart
///////////////////////////////////////////////////////////////////////////
// quad
///////////////////////////////////////////////////////////////////////////
@@ -137,7 +137,7 @@ static real_t in_out(real_t t, real_t b, real_t c, real_t d) {
static real_t out_in(real_t t, real_t b, real_t c, real_t d) {
return (t < d / 2) ? out(t * 2, b, c / 2, d) : in((t * 2) - d, b + c / 2, c / 2, d);
}
-};
+}; // namespace quad
///////////////////////////////////////////////////////////////////////////
// expo
///////////////////////////////////////////////////////////////////////////
@@ -163,7 +163,7 @@ static real_t in_out(real_t t, real_t b, real_t c, real_t d) {
static real_t out_in(real_t t, real_t b, real_t c, real_t d) {
return (t < d / 2) ? out(t * 2, b, c / 2, d) : in((t * 2) - d, b + c / 2, c / 2, d);
}
-};
+}; // namespace expo
///////////////////////////////////////////////////////////////////////////
// elastic
///////////////////////////////////////////////////////////////////////////
@@ -205,7 +205,7 @@ static real_t in_out(real_t t, real_t b, real_t c, real_t d) {
static real_t out_in(real_t t, real_t b, real_t c, real_t d) {
return (t < d / 2) ? out(t * 2, b, c / 2, d) : in((t * 2) - d, b + c / 2, c / 2, d);
}
-};
+}; // namespace elastic
///////////////////////////////////////////////////////////////////////////
// cubic
///////////////////////////////////////////////////////////////////////////
@@ -227,7 +227,7 @@ static real_t in_out(real_t t, real_t b, real_t c, real_t d) {
static real_t out_in(real_t t, real_t b, real_t c, real_t d) {
return (t < d / 2) ? out(t * 2, b, c / 2, d) : in((t * 2) - d, b + c / 2, c / 2, d);
}
-};
+}; // namespace cubic
///////////////////////////////////////////////////////////////////////////
// circ
///////////////////////////////////////////////////////////////////////////
@@ -248,7 +248,7 @@ static real_t in_out(real_t t, real_t b, real_t c, real_t d) {
static real_t out_in(real_t t, real_t b, real_t c, real_t d) {
return (t < d / 2) ? out(t * 2, b, c / 2, d) : in((t * 2) - d, b + c / 2, c / 2, d);
}
-};
+}; // namespace circ
///////////////////////////////////////////////////////////////////////////
// bounce
///////////////////////////////////////////////////////////////////////////
@@ -281,7 +281,7 @@ static real_t in_out(real_t t, real_t b, real_t c, real_t d) {
static real_t out_in(real_t t, real_t b, real_t c, real_t d) {
return (t < d / 2) ? out(t * 2, b, c / 2, d) : in((t * 2) - d, b + c / 2, c / 2, d);
}
-};
+}; // namespace bounce
///////////////////////////////////////////////////////////////////////////
// back
///////////////////////////////////////////////////////////////////////////
@@ -307,7 +307,7 @@ static real_t in_out(real_t t, real_t b, real_t c, real_t d) {
static real_t out_in(real_t t, real_t b, real_t c, real_t d) {
return (t < d / 2) ? out(t * 2, b, c / 2, d) : in((t * 2) - d, b + c / 2, c / 2, d);
}
-};
+}; // namespace back
Tween::interpolater Tween::interpolaters[Tween::TRANS_COUNT][Tween::EASE_COUNT] = {
{ &linear::in, &linear::out, &linear::in_out, &linear::out_in },
diff --git a/scene/gui/box_container.h b/scene/gui/box_container.h
index 4d00a2011f..ebbbbed1f9 100644
--- a/scene/gui/box_container.h
+++ b/scene/gui/box_container.h
@@ -70,8 +70,8 @@ class HBoxContainer : public BoxContainer {
GDCLASS(HBoxContainer, BoxContainer);
public:
- HBoxContainer()
- : BoxContainer(false) {}
+ HBoxContainer() :
+ BoxContainer(false) {}
};
class MarginContainer;
@@ -82,8 +82,8 @@ class VBoxContainer : public BoxContainer {
public:
MarginContainer *add_margin_child(const String &p_label, Control *p_control, bool p_expand = false);
- VBoxContainer()
- : BoxContainer(true) {}
+ VBoxContainer() :
+ BoxContainer(true) {}
};
VARIANT_ENUM_CAST(BoxContainer::AlignMode);
diff --git a/scene/gui/check_box.cpp b/scene/gui/check_box.cpp
index e2b10a948f..00f6153062 100644
--- a/scene/gui/check_box.cpp
+++ b/scene/gui/check_box.cpp
@@ -56,8 +56,8 @@ bool CheckBox::is_radio() {
return get_button_group().is_valid();
}
-CheckBox::CheckBox(const String &p_text)
- : Button(p_text) {
+CheckBox::CheckBox(const String &p_text) :
+ Button(p_text) {
set_toggle_mode(true);
set_text_align(ALIGN_LEFT);
}
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index 7a0593bc87..cb6283507e 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -486,8 +486,8 @@ void ColorPicker::_bind_methods() {
ADD_SIGNAL(MethodInfo("color_changed", PropertyInfo(Variant::COLOR, "color")));
}
-ColorPicker::ColorPicker()
- : BoxContainer(true) {
+ColorPicker::ColorPicker() :
+ BoxContainer(true) {
updating = true;
edit_alpha = true;
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index adca78d1d4..81d2b6731f 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -2470,6 +2470,16 @@ Control::MouseFilter Control::get_mouse_filter() const {
return data.mouse_filter;
}
+void Control::set_pass_on_modal_close_click(bool p_pass_on) {
+
+ data.pass_on_modal_close_click = p_pass_on;
+}
+
+bool Control::pass_on_modal_close_click() const {
+
+ return data.pass_on_modal_close_click;
+}
+
Control *Control::get_focus_owner() const {
ERR_FAIL_COND_V(!is_inside_tree(), NULL);
@@ -2934,6 +2944,7 @@ Control::Control() {
data.parent = NULL;
data.mouse_filter = MOUSE_FILTER_STOP;
+ data.pass_on_modal_close_click = true;
data.SI = NULL;
data.MI = NULL;
diff --git a/scene/gui/control.h b/scene/gui/control.h
index 92d1c969fc..9ac0eb0be3 100644
--- a/scene/gui/control.h
+++ b/scene/gui/control.h
@@ -165,6 +165,8 @@ private:
bool pending_min_size_update;
Point2 custom_minimum_size;
+ bool pass_on_modal_close_click;
+
MouseFilter mouse_filter;
bool clip_contents;
@@ -401,6 +403,9 @@ public:
void set_mouse_filter(MouseFilter p_filter);
MouseFilter get_mouse_filter() const;
+ void set_pass_on_modal_close_click(bool p_pass_on);
+ bool pass_on_modal_close_click() const;
+
/* SKINNING */
void add_icon_override(const StringName &p_name, const Ref<Texture> &p_icon);
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index 8af499fd96..6af869c503 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -603,6 +603,14 @@ void FileDialog::set_current_path(const String &p_path) {
}
}
+void FileDialog::set_mode_overrides_title(bool p_override) {
+ mode_overrides_title = p_override;
+}
+
+bool FileDialog::is_mode_overriding_title() const {
+ return mode_overrides_title;
+}
+
void FileDialog::set_mode(Mode p_mode) {
mode = p_mode;
@@ -610,27 +618,32 @@ void FileDialog::set_mode(Mode p_mode) {
case MODE_OPEN_FILE:
get_ok()->set_text(RTR("Open"));
- set_title(RTR("Open a File"));
+ if (mode_overrides_title)
+ set_title(RTR("Open a File"));
makedir->hide();
break;
case MODE_OPEN_FILES:
get_ok()->set_text(RTR("Open"));
- set_title(RTR("Open File(s)"));
+ if (mode_overrides_title)
+ set_title(RTR("Open File(s)"));
makedir->hide();
break;
case MODE_OPEN_DIR:
get_ok()->set_text(RTR("Select Current Folder"));
- set_title(RTR("Open a Directory"));
+ if (mode_overrides_title)
+ set_title(RTR("Open a Directory"));
makedir->show();
break;
case MODE_OPEN_ANY:
get_ok()->set_text(RTR("Open"));
- set_title(RTR("Open a File or Directory"));
+ if (mode_overrides_title)
+ set_title(RTR("Open a File or Directory"));
makedir->show();
break;
case MODE_SAVE_FILE:
get_ok()->set_text(RTR("Save"));
- set_title(RTR("Save a File"));
+ if (mode_overrides_title)
+ set_title(RTR("Save a File"));
makedir->show();
break;
}
@@ -760,6 +773,8 @@ void FileDialog::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_current_dir", "dir"), &FileDialog::set_current_dir);
ClassDB::bind_method(D_METHOD("set_current_file", "file"), &FileDialog::set_current_file);
ClassDB::bind_method(D_METHOD("set_current_path", "path"), &FileDialog::set_current_path);
+ ClassDB::bind_method(D_METHOD("set_mode_overrides_title", "override"), &FileDialog::set_mode_overrides_title);
+ ClassDB::bind_method(D_METHOD("is_mode_overriding_title"), &FileDialog::is_mode_overriding_title);
ClassDB::bind_method(D_METHOD("set_mode", "mode"), &FileDialog::set_mode);
ClassDB::bind_method(D_METHOD("get_mode"), &FileDialog::get_mode);
ClassDB::bind_method(D_METHOD("get_vbox"), &FileDialog::get_vbox);
@@ -791,6 +806,7 @@ void FileDialog::_bind_methods() {
BIND_ENUM_CONSTANT(ACCESS_USERDATA);
BIND_ENUM_CONSTANT(ACCESS_FILESYSTEM);
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "mode_overrides_title"), "set_mode_overrides_title", "is_mode_overriding_title");
ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Open one,Open many,Open folder,Open any,Save"), "set_mode", "get_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "access", PROPERTY_HINT_ENUM, "Resources,User data,File system"), "set_access", "get_access");
ADD_PROPERTY(PropertyInfo(Variant::POOL_STRING_ARRAY, "filters"), "set_filters", "get_filters");
@@ -814,6 +830,8 @@ FileDialog::FileDialog() {
show_hidden_files = default_show_hidden_files;
+ mode_overrides_title = true;
+
VBoxContainer *vbc = memnew(VBoxContainer);
add_child(vbc);
diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h
index ca3d9f54b2..c8c1f23105 100644
--- a/scene/gui/file_dialog.h
+++ b/scene/gui/file_dialog.h
@@ -92,6 +92,8 @@ private:
Vector<String> filters;
+ bool mode_overrides_title;
+
static bool default_show_hidden_files;
bool show_hidden_files;
@@ -143,6 +145,9 @@ public:
void set_current_file(const String &p_file);
void set_current_path(const String &p_path);
+ void set_mode_overrides_title(bool p_override);
+ bool is_mode_overriding_title() const;
+
void set_mode(Mode p_mode);
Mode get_mode() const;
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index f7bf1cd9ea..85ae6d6241 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -1046,6 +1046,10 @@ void LineEdit::set_cursor_position(int p_pos) {
} else if (cursor_pos > window_pos) {
/* Adjust window if cursor goes too much to the right */
int window_width = get_size().width - style->get_minimum_size().width;
+ if (has_icon("right_icon")) {
+ Ref<Texture> r_icon = Control::get_icon("right_icon");
+ window_width -= r_icon->get_width();
+ }
if (window_width < 0)
return;
diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp
index ac450616d6..d850553957 100644
--- a/scene/gui/menu_button.cpp
+++ b/scene/gui/menu_button.cpp
@@ -111,6 +111,7 @@ MenuButton::MenuButton() {
popup->hide();
add_child(popup);
popup->set_as_toplevel(true);
+ popup->set_pass_on_modal_close_click(false);
connect("button_up", popup, "call_deferred", make_binds("grab_click_focus"));
set_process_unhandled_key_input(true);
set_action_mode(ACTION_MODE_BUTTON_PRESS);
diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp
index b4d0799945..70f3d9ca83 100644
--- a/scene/gui/option_button.cpp
+++ b/scene/gui/option_button.cpp
@@ -323,6 +323,7 @@ OptionButton::OptionButton() {
popup = memnew(PopupMenu);
popup->hide();
popup->set_as_toplevel(true);
+ popup->set_pass_on_modal_close_click(false);
add_child(popup);
popup->connect("id_pressed", this, "_selected");
diff --git a/scene/gui/scroll_bar.h b/scene/gui/scroll_bar.h
index 373483a8a0..753bd35de7 100644
--- a/scene/gui/scroll_bar.h
+++ b/scene/gui/scroll_bar.h
@@ -117,8 +117,8 @@ class HScrollBar : public ScrollBar {
GDCLASS(HScrollBar, ScrollBar);
public:
- HScrollBar()
- : ScrollBar(HORIZONTAL) { set_v_size_flags(0); }
+ HScrollBar() :
+ ScrollBar(HORIZONTAL) { set_v_size_flags(0); }
};
class VScrollBar : public ScrollBar {
@@ -126,8 +126,8 @@ class VScrollBar : public ScrollBar {
GDCLASS(VScrollBar, ScrollBar);
public:
- VScrollBar()
- : ScrollBar(VERTICAL) { set_h_size_flags(0); }
+ VScrollBar() :
+ ScrollBar(VERTICAL) { set_h_size_flags(0); }
};
#endif
diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp
index a71a1c5f92..ffe0db691f 100644
--- a/scene/gui/scroll_container.cpp
+++ b/scene/gui/scroll_container.cpp
@@ -354,6 +354,7 @@ void ScrollContainer::update_scrollbars() {
if (!scroll_v || min.height <= size.height - hmin.height) {
v_scroll->hide();
+ v_scroll->set_max(0);
scroll.y = 0;
} else {
@@ -366,6 +367,7 @@ void ScrollContainer::update_scrollbars() {
if (!scroll_h || min.width <= size.width - vmin.width) {
h_scroll->hide();
+ h_scroll->set_max(0);
scroll.x = 0;
} else {
diff --git a/scene/gui/slider.h b/scene/gui/slider.h
index a2334a69fc..95ae429d63 100644
--- a/scene/gui/slider.h
+++ b/scene/gui/slider.h
@@ -77,8 +77,8 @@ class HSlider : public Slider {
GDCLASS(HSlider, Slider);
public:
- HSlider()
- : Slider(HORIZONTAL) { set_v_size_flags(0); }
+ HSlider() :
+ Slider(HORIZONTAL) { set_v_size_flags(0); }
};
class VSlider : public Slider {
@@ -86,8 +86,8 @@ class VSlider : public Slider {
GDCLASS(VSlider, Slider);
public:
- VSlider()
- : Slider(VERTICAL) { set_h_size_flags(0); }
+ VSlider() :
+ Slider(VERTICAL) { set_h_size_flags(0); }
};
#endif // SLIDER_H
diff --git a/scene/gui/split_container.h b/scene/gui/split_container.h
index 8ec21b5eaa..c7a484c4c5 100644
--- a/scene/gui/split_container.h
+++ b/scene/gui/split_container.h
@@ -87,8 +87,8 @@ class HSplitContainer : public SplitContainer {
GDCLASS(HSplitContainer, SplitContainer);
public:
- HSplitContainer()
- : SplitContainer(false) { set_default_cursor_shape(CURSOR_HSPLIT); }
+ HSplitContainer() :
+ SplitContainer(false) { set_default_cursor_shape(CURSOR_HSPLIT); }
};
class VSplitContainer : public SplitContainer {
@@ -96,8 +96,8 @@ class VSplitContainer : public SplitContainer {
GDCLASS(VSplitContainer, SplitContainer);
public:
- VSplitContainer()
- : SplitContainer(true) { set_default_cursor_shape(CURSOR_VSPLIT); }
+ VSplitContainer() :
+ SplitContainer(true) { set_default_cursor_shape(CURSOR_VSPLIT); }
};
#endif // SPLIT_CONTAINER_H
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 396186d487..e5169089f2 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -251,13 +251,14 @@ void TextEdit::Text::clear() {
insert(0, "");
}
-int TextEdit::Text::get_max_width() const {
+int TextEdit::Text::get_max_width(bool p_exclude_hidden) const {
//quite some work.. but should be fast enough.
int max = 0;
-
- for (int i = 0; i < text.size(); i++)
- max = MAX(max, get_line_width(i));
+ for (int i = 0; i < text.size(); i++) {
+ if (!p_exclude_hidden || !is_hidden(i))
+ max = MAX(max, get_line_width(i));
+ }
return max;
}
@@ -307,7 +308,7 @@ void TextEdit::_update_scrollbars() {
int vscroll_pixels = v_scroll->get_combined_minimum_size().width;
int visible_width = size.width - cache.style_normal->get_minimum_size().width;
- int total_width = text.get_max_width() + vmin.x;
+ int total_width = text.get_max_width(true) + vmin.x;
if (line_numbers)
total_width += cache.line_number_w;
@@ -360,6 +361,7 @@ void TextEdit::_update_scrollbars() {
}
} else {
+
cursor.line_ofs = 0;
line_scroll_pos = 0;
v_scroll->set_value(0);
@@ -371,12 +373,16 @@ void TextEdit::_update_scrollbars() {
h_scroll->show();
h_scroll->set_max(total_width);
h_scroll->set_page(visible_width);
+ if (cursor.x_ofs > (total_width - visible_width))
+ cursor.x_ofs = (total_width - visible_width);
if (fabs(h_scroll->get_value() - (double)cursor.x_ofs) >= 1) {
h_scroll->set_value(cursor.x_ofs);
}
} else {
+ cursor.x_ofs = 0;
+ h_scroll->set_value(0);
h_scroll->hide();
}
@@ -880,6 +886,11 @@ void TextEdit::_notification(int p_what) {
int char_w = cache.font->get_char_size(' ').width;
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(xmargin_beg + ofs_x, ofs_y, char_w, get_row_height()), cache.selection_color);
}
+ } else {
+ // if it has text, then draw current line marker in the margin, as line number ect will draw over it, draw the rest of line marker later.
+ if (line == cursor.line && highlight_current_line) {
+ VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(0, ofs_y, xmargin_beg, get_row_height()), cache.current_line_color);
+ }
}
if (text.is_breakpoint(line) && !draw_breakpoint_gutter) {
@@ -909,11 +920,11 @@ void TextEdit::_notification(int p_what) {
if (is_folded(line)) {
int xofs = horizontal_gap - (cache.can_fold_icon->get_width()) / 2;
int yofs = (get_row_height() - cache.folded_icon->get_height()) / 2;
- cache.folded_icon->draw(ci, Point2(gutter_left + xofs + ofs_x, ofs_y + yofs), Color(0.8f, 0.8f, 0.8f, 0.8f));
+ cache.folded_icon->draw(ci, Point2(gutter_left + xofs + ofs_x, ofs_y + yofs), cache.code_folding_color);
} else if (can_fold(line)) {
int xofs = -cache.can_fold_icon->get_width() / 2 - horizontal_gap + 3;
int yofs = (get_row_height() - cache.can_fold_icon->get_height()) / 2;
- cache.can_fold_icon->draw(ci, Point2(gutter_left + xofs + ofs_x, ofs_y + yofs), Color(0.8f, 0.8f, 0.8f, 0.8f));
+ cache.can_fold_icon->draw(ci, Point2(gutter_left + xofs + ofs_x, ofs_y + yofs), cache.code_folding_color);
}
}
@@ -1120,10 +1131,6 @@ void TextEdit::_notification(int p_what) {
bool in_selection = (selection.active && line >= selection.from_line && line <= selection.to_line && (line > selection.from_line || j >= selection.from_column) && (line < selection.to_line || j < selection.to_column));
if (line == cursor.line && highlight_current_line) {
- // if its the first char draw behind line numbers
- if (j == 0) {
- VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(0, ofs_y, (char_ofs + char_margin + ofs_x), get_row_height()), cache.current_line_color);
- }
// if its the last char draw to end of the line
if (j == str.length() - 1) {
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(char_ofs + char_margin + char_w, ofs_y, xmargin_end - (char_ofs + char_margin + char_w), get_row_height()), cache.current_line_color);
@@ -1262,7 +1269,9 @@ void TextEdit::_notification(int p_what) {
if (j == str.length() - 1 && is_folded(line)) {
int yofs = (get_row_height() - cache.folded_eol_icon->get_height()) / 2;
int xofs = cache.folded_eol_icon->get_width() / 2;
- cache.folded_eol_icon->draw(ci, Point2(char_ofs + char_margin + xofs + ofs_x, ofs_y + yofs), Color(1, 1, 1, 1));
+ Color eol_color = cache.code_folding_color;
+ eol_color.a = 1;
+ cache.folded_eol_icon->draw(ci, Point2(char_ofs + char_margin + xofs + ofs_x, ofs_y + yofs), eol_color);
}
}
@@ -3987,6 +3996,7 @@ void TextEdit::_update_caches() {
cache.current_line_color = get_color("current_line_color");
cache.line_length_guideline_color = get_color("line_length_guideline_color");
cache.breakpoint_color = get_color("breakpoint_color");
+ cache.code_folding_color = get_color("code_folding_color");
cache.brace_mismatch_color = get_color("brace_mismatch_color");
cache.word_highlighted_color = get_color("word_highlighted_color");
cache.search_result_color = get_color("search_result_color");
@@ -4507,16 +4517,17 @@ int TextEdit::num_lines_from(int p_line_from, int unhidden_amount) const {
return num_total;
}
-int TextEdit::get_whitespace_level(int p_line) const {
+int TextEdit::get_indent_level(int p_line) const {
ERR_FAIL_INDEX_V(p_line, text.size(), 0);
// counts number of tabs and spaces before line starts
+ int tab_count = 0;
int whitespace_count = 0;
int line_length = text[p_line].size();
for (int i = 0; i < line_length - 1; i++) {
if (text[p_line][i] == '\t') {
- whitespace_count++;
+ tab_count++;
} else if (text[p_line][i] == ' ') {
whitespace_count++;
} else if (text[p_line][i] == '#') {
@@ -4525,7 +4536,7 @@ int TextEdit::get_whitespace_level(int p_line) const {
break;
}
}
- return whitespace_count;
+ return tab_count + whitespace_count / indent_size;
}
bool TextEdit::can_fold(int p_line) const {
@@ -4542,12 +4553,12 @@ bool TextEdit::can_fold(int p_line) const {
if (is_line_hidden(p_line))
return false;
- int start_indent = get_whitespace_level(p_line);
+ int start_indent = get_indent_level(p_line);
for (int i = p_line + 1; i < text.size(); i++) {
if (text[i].size() == 0)
continue;
- int next_indent = get_whitespace_level(i);
+ int next_indent = get_indent_level(i);
if (next_indent > start_indent)
return true;
else
@@ -4576,22 +4587,20 @@ void TextEdit::fold_line(int p_line) {
return;
// hide lines below this one
- int start_indent = get_whitespace_level(p_line);
+ int start_indent = get_indent_level(p_line);
+ int last_line = start_indent;
for (int i = p_line + 1; i < text.size(); i++) {
- int cur_indent = get_whitespace_level(i);
- if (text[i].size() == 0 || cur_indent > start_indent) {
- set_line_as_hidden(i, true);
- } else {
- // exclude trailing empty lines
- for (int trail_i = i - 1; trail_i > p_line; trail_i--) {
- if (text[trail_i].size() == 0)
- set_line_as_hidden(trail_i, false);
- else
- break;
+ if (text[i].strip_edges().size() != 0) {
+ if (get_indent_level(i) > start_indent) {
+ last_line = i;
+ } else {
+ break;
}
- break;
}
}
+ for (int i = p_line + 1; i <= last_line; i++) {
+ set_line_as_hidden(i, true);
+ }
// fix selection
if (is_selection_active()) {
@@ -4637,6 +4646,16 @@ void TextEdit::unfold_line(int p_line) {
update();
}
+void TextEdit::toggle_fold_line(int p_line) {
+
+ ERR_FAIL_INDEX(p_line, text.size());
+
+ if (!is_folded(p_line))
+ fold_line(p_line);
+ else
+ unfold_line(p_line);
+}
+
int TextEdit::get_line_count() const {
return text.size();
@@ -5452,6 +5471,7 @@ void TextEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("unhide_all_lines"), &TextEdit::unhide_all_lines);
ClassDB::bind_method(D_METHOD("fold_line", "line"), &TextEdit::fold_line);
ClassDB::bind_method(D_METHOD("unfold_line", "line"), &TextEdit::unfold_line);
+ ClassDB::bind_method(D_METHOD("toggle_fold_line", "line"), &TextEdit::toggle_fold_line);
ClassDB::bind_method(D_METHOD("can_fold", "line"), &TextEdit::can_fold);
ClassDB::bind_method(D_METHOD("is_folded", "line"), &TextEdit::is_folded);
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index 428c850a1b..dd305d5822 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -96,6 +96,7 @@ class TextEdit : public Control {
Color selection_color;
Color mark_color;
Color breakpoint_color;
+ Color code_folding_color;
Color current_line_color;
Color line_length_guideline_color;
Color brace_mismatch_color;
@@ -159,7 +160,7 @@ class TextEdit : public Control {
void set_font(const Ref<Font> &p_font);
void set_color_regions(const Vector<ColorRegion> *p_regions) { color_regions = p_regions; }
int get_line_width(int p_line) const;
- int get_max_width() const;
+ int get_max_width(bool p_exclude_hidden = false) const;
const Map<int, ColorRegionInfo> &get_color_region_info(int p_line);
void set(int p_line, const String &p_text);
void set_marked(int p_line, bool p_marked) { text[p_line].marked = p_marked; }
@@ -431,11 +432,11 @@ public:
void fold_all_lines();
void unhide_all_lines();
int num_lines_from(int p_line_from, int unhidden_amount) const;
- int get_whitespace_level(int p_line) const;
bool can_fold(int p_line) const;
bool is_folded(int p_line) const;
void fold_line(int p_line);
void unfold_line(int p_line);
+ void toggle_fold_line(int p_line);
String get_text();
String get_line(int line) const;
@@ -444,6 +445,7 @@ public:
void indent_selection_left();
void indent_selection_right();
+ int get_indent_level(int p_line) const;
inline void set_scroll_pass_end_of_file(bool p_enabled) {
scroll_past_end_of_file_enabled = p_enabled;
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index 5ee286c2d5..deb40800bc 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -794,6 +794,7 @@ Ref<ArrayMesh> SceneTree::get_debug_contact_mesh() {
Vector3(0, 0, 1)
};
+ /* clang-format off */
int diamond_faces[8 * 3] = {
0, 2, 4,
0, 3, 4,
@@ -804,6 +805,7 @@ Ref<ArrayMesh> SceneTree::get_debug_contact_mesh() {
1, 2, 5,
1, 3, 5,
};
+ /* clang-format on */
PoolVector<int> indices;
for (int i = 0; i < 8 * 3; i++)
diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h
index 7898dc065a..244fc8da62 100644
--- a/scene/main/scene_tree.h
+++ b/scene/main/scene_tree.h
@@ -420,8 +420,8 @@ public:
void set_screen_stretch(StretchMode p_mode, StretchAspect p_aspect, const Size2 p_minsize, real_t p_shrink = 1);
-//void change_scene(const String& p_path);
-//Node *get_loaded_scene();
+ //void change_scene(const String& p_path);
+ //Node *get_loaded_scene();
#ifdef TOOLS_ENABLED
void set_edited_scene_root(Node *p_node);
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index d864b0f763..4635de81e8 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -936,6 +936,9 @@ void Viewport::_camera_remove(Camera *p_camera) {
cameras.erase(p_camera);
if (camera == p_camera) {
+ if (camera && find_world().is_valid()) {
+ camera->notification(Camera::NOTIFICATION_LOST_CURRENT);
+ }
camera = NULL;
}
}
@@ -1266,12 +1269,9 @@ Transform2D Viewport::_get_input_pre_xform() const {
Vector2 Viewport::_get_window_offset() const {
- /*
- if (parent_control) {
- return (parent_control->get_viewport()->get_final_transform() * parent_control->get_global_transform_with_canvas()).get_origin();
+ if (get_parent() && get_parent()->has_method("get_global_position")) {
+ return get_parent()->call("get_global_position");
}
- */
-
return Vector2();
}
@@ -1646,6 +1646,8 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
} else {
+ bool is_handled = false;
+
_gui_sort_modal_stack();
while (!gui.modal_stack.empty()) {
@@ -1663,11 +1665,20 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
top->notification(Control::NOTIFICATION_MODAL_CLOSE);
top->_modal_stack_remove();
top->hide();
+
+ if (!top->pass_on_modal_close_click()) {
+ is_handled = true;
+ }
} else {
break;
}
}
+ if (is_handled) {
+ get_tree()->set_input_as_handled();
+ return;
+ }
+
//Matrix32 parent_xform;
/*
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp
index 8192074c17..4544549f94 100644
--- a/scene/resources/animation.cpp
+++ b/scene/resources/animation.cpp
@@ -77,6 +77,8 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) {
track_set_interpolation_loop_wrap(track, p_value);
else if (what == "imported")
track_set_imported(track, p_value);
+ else if (what == "enabled")
+ track_set_enabled(track, p_value);
else if (what == "keys" || what == "key_values") {
if (track_get_type(track) == TYPE_TRANSFORM) {
@@ -247,6 +249,8 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const {
r_ret = track_get_interpolation_loop_wrap(track);
else if (what == "imported")
r_ret = track_is_imported(track);
+ else if (what == "enabled")
+ r_ret = track_is_enabled(track);
else if (what == "keys") {
if (track_get_type(track) == TYPE_TRANSFORM) {
@@ -391,6 +395,7 @@ void Animation::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::INT, "tracks/" + itos(i) + "/interp", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
p_list->push_back(PropertyInfo(Variant::BOOL, "tracks/" + itos(i) + "/loop_wrap", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
p_list->push_back(PropertyInfo(Variant::BOOL, "tracks/" + itos(i) + "/imported", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_list->push_back(PropertyInfo(Variant::BOOL, "tracks/" + itos(i) + "/enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
p_list->push_back(PropertyInfo(Variant::ARRAY, "tracks/" + itos(i) + "/keys", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
}
}
@@ -1575,6 +1580,19 @@ bool Animation::track_is_imported(int p_track) const {
return tracks[p_track]->imported;
}
+void Animation::track_set_enabled(int p_track, bool p_enabled) {
+
+ ERR_FAIL_INDEX(p_track, tracks.size());
+ tracks[p_track]->enabled = p_enabled;
+ emit_changed();
+}
+
+bool Animation::track_is_enabled(int p_track) const {
+
+ ERR_FAIL_INDEX_V(p_track, tracks.size(), false);
+ return tracks[p_track]->enabled;
+}
+
void Animation::track_move_down(int p_track) {
if (p_track > 0 && p_track < tracks.size()) {
@@ -1595,6 +1613,22 @@ float Animation::get_step() const {
return step;
}
+void Animation::copy_track(int src_track, Ref<Animation> p_to_animation) {
+ ERR_FAIL_COND(p_to_animation.is_null());
+ ERR_FAIL_INDEX(src_track, get_track_count());
+ int dst_track = p_to_animation->get_track_count();
+ p_to_animation->add_track(track_get_type(src_track));
+
+ p_to_animation->track_set_path(dst_track, track_get_path(src_track));
+ p_to_animation->track_set_imported(dst_track, track_is_imported(src_track));
+ p_to_animation->track_set_enabled(dst_track, track_is_enabled(src_track));
+ p_to_animation->track_set_interpolation_type(dst_track, track_get_interpolation_type(src_track));
+ p_to_animation->track_set_interpolation_loop_wrap(dst_track, track_get_interpolation_loop_wrap(src_track));
+ for (int i = 0; i < track_get_key_count(src_track); i++) {
+ p_to_animation->track_insert_key(dst_track, track_get_key_time(src_track, i), track_get_key_value(src_track, i), track_get_key_transition(src_track, i));
+ }
+}
+
void Animation::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_track", "type", "at_position"), &Animation::add_track, DEFVAL(-1));
@@ -1611,6 +1645,9 @@ void Animation::_bind_methods() {
ClassDB::bind_method(D_METHOD("track_set_imported", "idx", "imported"), &Animation::track_set_imported);
ClassDB::bind_method(D_METHOD("track_is_imported", "idx"), &Animation::track_is_imported);
+ ClassDB::bind_method(D_METHOD("track_set_enabled", "idx", "enabled"), &Animation::track_set_enabled);
+ ClassDB::bind_method(D_METHOD("track_is_enabled", "idx"), &Animation::track_is_enabled);
+
ClassDB::bind_method(D_METHOD("transform_track_insert_key", "idx", "time", "location", "rotation", "scale"), &Animation::transform_track_insert_key);
ClassDB::bind_method(D_METHOD("track_insert_key", "idx", "time", "key", "transition"), &Animation::track_insert_key, DEFVAL(1));
ClassDB::bind_method(D_METHOD("track_remove_key", "idx", "key_idx"), &Animation::track_remove_key);
@@ -1650,6 +1687,7 @@ void Animation::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_step"), &Animation::get_step);
ClassDB::bind_method(D_METHOD("clear"), &Animation::clear);
+ ClassDB::bind_method(D_METHOD("copy_track", "track", "to_animation"), &Animation::copy_track);
BIND_ENUM_CONSTANT(TYPE_VALUE);
BIND_ENUM_CONSTANT(TYPE_TRANSFORM);
diff --git a/scene/resources/animation.h b/scene/resources/animation.h
index 6235e161a3..1f468b29b5 100644
--- a/scene/resources/animation.h
+++ b/scene/resources/animation.h
@@ -67,10 +67,12 @@ private:
bool loop_wrap;
NodePath path; // path to something
bool imported;
+ bool enabled;
Track() {
interpolation = INTERPOLATION_LINEAR;
imported = false;
loop_wrap = true;
+ enabled = true;
}
virtual ~Track() {}
};
@@ -239,6 +241,9 @@ public:
void track_set_imported(int p_track, bool p_imported);
bool track_is_imported(int p_track) const;
+ void track_set_enabled(int p_track, bool p_enabled);
+ bool track_is_enabled(int p_track) const;
+
int transform_track_insert_key(int p_track, float p_time, const Vector3 p_loc, const Quat &p_rot = Quat(), const Vector3 &p_scale = Vector3());
void track_insert_key(int p_track, float p_time, const Variant &p_key, float p_transition = 1);
void track_set_key_transition(int p_track, int p_key_idx, float p_transition);
@@ -269,6 +274,8 @@ public:
Vector<Variant> method_track_get_params(int p_track, int p_key_idx) const;
StringName method_track_get_name(int p_track, int p_key_idx) const;
+ void copy_track(int p_track, Ref<Animation> p_to_animation);
+
void set_length(float p_length);
float get_length() const;
diff --git a/scene/resources/box_shape.cpp b/scene/resources/box_shape.cpp
index 4b9843f3f5..858e19c9a6 100644
--- a/scene/resources/box_shape.cpp
+++ b/scene/resources/box_shape.cpp
@@ -73,8 +73,8 @@ void BoxShape::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents"), "set_extents", "get_extents");
}
-BoxShape::BoxShape()
- : Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_BOX)) {
+BoxShape::BoxShape() :
+ Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_BOX)) {
set_extents(Vector3(1, 1, 1));
}
diff --git a/scene/resources/capsule_shape.cpp b/scene/resources/capsule_shape.cpp
index e11b98f82e..f0eb8232e5 100644
--- a/scene/resources/capsule_shape.cpp
+++ b/scene/resources/capsule_shape.cpp
@@ -113,8 +113,8 @@ void CapsuleShape::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "height", PROPERTY_HINT_RANGE, "0.01,4096,0.01"), "set_height", "get_height");
}
-CapsuleShape::CapsuleShape()
- : Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CAPSULE)) {
+CapsuleShape::CapsuleShape() :
+ Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CAPSULE)) {
radius = 1.0;
height = 1.0;
diff --git a/scene/resources/capsule_shape_2d.cpp b/scene/resources/capsule_shape_2d.cpp
index 912150b939..3caf12feb8 100644
--- a/scene/resources/capsule_shape_2d.cpp
+++ b/scene/resources/capsule_shape_2d.cpp
@@ -97,8 +97,8 @@ void CapsuleShape2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "height"), "set_height", "get_height");
}
-CapsuleShape2D::CapsuleShape2D()
- : Shape2D(Physics2DServer::get_singleton()->capsule_shape_create()) {
+CapsuleShape2D::CapsuleShape2D() :
+ Shape2D(Physics2DServer::get_singleton()->capsule_shape_create()) {
radius = 10;
height = 20;
diff --git a/scene/resources/circle_shape_2d.cpp b/scene/resources/circle_shape_2d.cpp
index 287bde4bfb..bff3ed4d67 100644
--- a/scene/resources/circle_shape_2d.cpp
+++ b/scene/resources/circle_shape_2d.cpp
@@ -76,8 +76,8 @@ void CircleShape2D::draw(const RID &p_to_rid, const Color &p_color) {
VisualServer::get_singleton()->canvas_item_add_polygon(p_to_rid, points, col);
}
-CircleShape2D::CircleShape2D()
- : Shape2D(Physics2DServer::get_singleton()->circle_shape_create()) {
+CircleShape2D::CircleShape2D() :
+ Shape2D(Physics2DServer::get_singleton()->circle_shape_create()) {
radius = 10;
_update_shape();
diff --git a/scene/resources/concave_polygon_shape.cpp b/scene/resources/concave_polygon_shape.cpp
index 6ae4fde85e..1c48f0c30b 100644
--- a/scene/resources/concave_polygon_shape.cpp
+++ b/scene/resources/concave_polygon_shape.cpp
@@ -106,8 +106,8 @@ void ConcavePolygonShape::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_faces"), &ConcavePolygonShape::get_faces);
}
-ConcavePolygonShape::ConcavePolygonShape()
- : Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CONCAVE_POLYGON)) {
+ConcavePolygonShape::ConcavePolygonShape() :
+ Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CONCAVE_POLYGON)) {
//set_planes(Vector3(1,1,1));
}
diff --git a/scene/resources/concave_polygon_shape_2d.cpp b/scene/resources/concave_polygon_shape_2d.cpp
index bb91e33ec2..e90046fd28 100644
--- a/scene/resources/concave_polygon_shape_2d.cpp
+++ b/scene/resources/concave_polygon_shape_2d.cpp
@@ -84,6 +84,6 @@ void ConcavePolygonShape2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "segments"), "set_segments", "get_segments");
}
-ConcavePolygonShape2D::ConcavePolygonShape2D()
- : Shape2D(Physics2DServer::get_singleton()->concave_polygon_shape_create()) {
+ConcavePolygonShape2D::ConcavePolygonShape2D() :
+ Shape2D(Physics2DServer::get_singleton()->concave_polygon_shape_create()) {
}
diff --git a/scene/resources/convex_polygon_shape.cpp b/scene/resources/convex_polygon_shape.cpp
index bba52bd5ff..31c4ea55e9 100644
--- a/scene/resources/convex_polygon_shape.cpp
+++ b/scene/resources/convex_polygon_shape.cpp
@@ -81,8 +81,8 @@ void ConvexPolygonShape::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "points"), "set_points", "get_points");
}
-ConvexPolygonShape::ConvexPolygonShape()
- : Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CONVEX_POLYGON)) {
+ConvexPolygonShape::ConvexPolygonShape() :
+ Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_CONVEX_POLYGON)) {
//set_points(Vector3(1,1,1));
}
diff --git a/scene/resources/convex_polygon_shape_2d.cpp b/scene/resources/convex_polygon_shape_2d.cpp
index a76b6a7cf4..9c25b6b467 100644
--- a/scene/resources/convex_polygon_shape_2d.cpp
+++ b/scene/resources/convex_polygon_shape_2d.cpp
@@ -86,8 +86,8 @@ Rect2 ConvexPolygonShape2D::get_rect() const {
return rect;
}
-ConvexPolygonShape2D::ConvexPolygonShape2D()
- : Shape2D(Physics2DServer::get_singleton()->convex_polygon_shape_create()) {
+ConvexPolygonShape2D::ConvexPolygonShape2D() :
+ Shape2D(Physics2DServer::get_singleton()->convex_polygon_shape_create()) {
int pcount = 3;
for (int i = 0; i < pcount; i++)
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index 651b7543c6..bb2c8750e3 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -468,6 +468,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_color("selection_color", "TextEdit", font_color_selection);
theme->set_color("mark_color", "TextEdit", Color(1.0, 0.4, 0.4, 0.4));
theme->set_color("breakpoint_color", "TextEdit", Color(0.8, 0.8, 0.4, 0.2));
+ theme->set_color("code_folding_color", "TextEdit", Color(0.8, 0.8, 0.8, 0.8));
theme->set_color("current_line_color", "TextEdit", Color(0.25, 0.25, 0.26, 0.8));
theme->set_color("caret_color", "TextEdit", control_font_color);
theme->set_color("caret_background_color", "TextEdit", Color::html("000000"));
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index a6f301af1e..c8ab7c2a04 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -2066,8 +2066,8 @@ void SpatialMaterial::_bind_methods() {
BIND_ENUM_CONSTANT(EMISSION_OP_MULTIPLY);
}
-SpatialMaterial::SpatialMaterial()
- : element(this) {
+SpatialMaterial::SpatialMaterial() :
+ element(this) {
//initialize to right values
set_albedo(Color(1.0, 1.0, 1.0, 1.0));
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index 0a886c25b1..0b352efca2 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -28,10 +28,14 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "mesh.h"
+
+#include "pair.h"
#include "scene/resources/concave_polygon_shape.h"
#include "scene/resources/convex_polygon_shape.h"
#include "surface_tool.h"
+#include <stdlib.h>
+
void Mesh::_clear_triangle_mesh() const {
triangle_mesh.unref();
@@ -413,8 +417,21 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const {
return newmesh;
}
+void Mesh::set_lightmap_size_hint(const Vector2 &p_size) {
+ lightmap_size_hint = p_size;
+}
+
+Size2 Mesh::get_lightmap_size_hint() const {
+ return lightmap_size_hint;
+}
+
void Mesh::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_lightmap_size_hint", "size"), &Mesh::set_lightmap_size_hint);
+ ClassDB::bind_method(D_METHOD("get_lightmap_size_hint"), &Mesh::get_lightmap_size_hint);
+
+ ADD_PROPERTYNZ(PropertyInfo(Variant::VECTOR2, "lightmap_size_hint"), "set_lightmap_size_hint", "get_lightmap_size_hint");
+
BIND_ENUM_CONSTANT(PRIMITIVE_POINTS);
BIND_ENUM_CONSTANT(PRIMITIVE_LINES);
BIND_ENUM_CONSTANT(PRIMITIVE_LINE_STRIP);
@@ -1035,6 +1052,200 @@ void ArrayMesh::regen_normalmaps() {
}
}
+//dirty hack
+bool (*array_mesh_lightmap_unwrap_callback)(float p_texel_size, const float *p_vertices, const float *p_normals, int p_vertex_count, const int *p_indices, const int *p_face_materials, int p_index_count, float **r_uv, int **r_vertex, int *r_vertex_count, int **r_index, int *r_index_count, int *r_size_hint_x, int *r_size_hint_y) = NULL;
+
+struct ArrayMeshLightmapSurface {
+
+ Ref<Material> material;
+ Vector<SurfaceTool::Vertex> vertices;
+ Mesh::PrimitiveType primitive;
+ uint32_t format;
+};
+
+Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texel_size) {
+
+ ERR_FAIL_COND_V(!array_mesh_lightmap_unwrap_callback, ERR_UNCONFIGURED);
+ ERR_EXPLAIN("Can't unwrap mesh with blend shapes");
+ ERR_FAIL_COND_V(blend_shapes.size() != 0, ERR_UNAVAILABLE);
+
+ Vector<float> vertices;
+ Vector<float> normals;
+ Vector<int> indices;
+ Vector<int> face_materials;
+ Vector<float> uv;
+ Vector<Pair<int, int> > uv_index;
+
+ Vector<ArrayMeshLightmapSurface> surfaces;
+ for (int i = 0; i < get_surface_count(); i++) {
+ ArrayMeshLightmapSurface s;
+ s.primitive = surface_get_primitive_type(i);
+
+ if (s.primitive != Mesh::PRIMITIVE_TRIANGLES) {
+ ERR_EXPLAIN("Only triangles are supported for lightmap unwrap");
+ ERR_FAIL_V(ERR_UNAVAILABLE);
+ }
+ s.format = surface_get_format(i);
+ if (!(s.format & ARRAY_FORMAT_NORMAL)) {
+ ERR_EXPLAIN("Normals are required for lightmap unwrap");
+ ERR_FAIL_V(ERR_UNAVAILABLE);
+ }
+
+ Array arrays = surface_get_arrays(i);
+ s.material = surface_get_material(i);
+ s.vertices = SurfaceTool::create_vertex_array_from_triangle_arrays(arrays);
+
+ PoolVector<Vector3> rvertices = arrays[Mesh::ARRAY_VERTEX];
+ int vc = rvertices.size();
+ PoolVector<Vector3>::Read r = rvertices.read();
+
+ PoolVector<Vector3> rnormals = arrays[Mesh::ARRAY_NORMAL];
+ PoolVector<Vector3>::Read rn = rnormals.read();
+
+ int vertex_ofs = vertices.size() / 3;
+
+ vertices.resize((vertex_ofs + vc) * 3);
+ normals.resize((vertex_ofs + vc) * 3);
+ uv_index.resize(vertex_ofs + vc);
+
+ for (int j = 0; j < vc; j++) {
+
+ Vector3 v = p_base_transform.xform(r[j]);
+
+ vertices[(j + vertex_ofs) * 3 + 0] = v.x;
+ vertices[(j + vertex_ofs) * 3 + 1] = v.y;
+ vertices[(j + vertex_ofs) * 3 + 2] = v.z;
+ normals[(j + vertex_ofs) * 3 + 0] = rn[j].x;
+ normals[(j + vertex_ofs) * 3 + 1] = rn[j].y;
+ normals[(j + vertex_ofs) * 3 + 2] = rn[j].z;
+ uv_index[j + vertex_ofs] = Pair<int, int>(i, j);
+ }
+
+ PoolVector<int> rindices = arrays[Mesh::ARRAY_INDEX];
+ int ic = rindices.size();
+ int index_ofs = indices.size();
+
+ if (ic == 0) {
+ indices.resize(index_ofs + vc);
+ face_materials.resize((index_ofs + vc) / 3);
+ for (int j = 0; j < vc; j++) {
+ indices[index_ofs + j] = vertex_ofs + j;
+ }
+ for (int j = 0; j < vc / 3; j++) {
+ face_materials[(index_ofs / 3) + j] = i;
+ }
+
+ } else {
+ PoolVector<int>::Read ri = rindices.read();
+ indices.resize(index_ofs + ic);
+ face_materials.resize((index_ofs + ic) / 3);
+ for (int j = 0; j < ic; j++) {
+ indices[index_ofs + j] = vertex_ofs + ri[j];
+ }
+ for (int j = 0; j < ic / 3; j++) {
+ face_materials[(index_ofs / 3) + j] = i;
+ }
+ }
+
+ surfaces.push_back(s);
+ }
+
+ //unwrap
+
+ float *gen_uvs;
+ int *gen_vertices;
+ int *gen_indices;
+ int gen_vertex_count;
+ int gen_index_count;
+ int size_x;
+ int size_y;
+
+ bool ok = array_mesh_lightmap_unwrap_callback(p_texel_size, vertices.ptr(), normals.ptr(), vertices.size() / 3, indices.ptr(), face_materials.ptr(), indices.size(), &gen_uvs, &gen_vertices, &gen_vertex_count, &gen_indices, &gen_index_count, &size_x, &size_y);
+
+ if (!ok) {
+ return ERR_CANT_CREATE;
+ }
+
+ //remove surfaces
+ while (get_surface_count()) {
+ surface_remove(0);
+ }
+
+ //create surfacetools for each surface..
+ Vector<Ref<SurfaceTool> > surfaces_tools;
+
+ for (int i = 0; i < surfaces.size(); i++) {
+ Ref<SurfaceTool> st;
+ st.instance();
+ st->begin(Mesh::PRIMITIVE_TRIANGLES);
+ st->set_material(surfaces[i].material);
+ surfaces_tools.push_back(st); //stay there
+ }
+
+ print_line("gen indices: " + itos(gen_index_count));
+ //go through all indices
+ for (int i = 0; i < gen_index_count; i += 3) {
+
+ ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 0]], uv_index.size(), ERR_BUG);
+ ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 1]], uv_index.size(), ERR_BUG);
+ ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 2]], uv_index.size(), ERR_BUG);
+
+ ERR_FAIL_COND_V(uv_index[gen_vertices[gen_indices[i + 0]]].first != uv_index[gen_vertices[gen_indices[i + 1]]].first || uv_index[gen_vertices[gen_indices[i + 0]]].first != uv_index[gen_vertices[gen_indices[i + 2]]].first, ERR_BUG);
+
+ int surface = uv_index[gen_vertices[gen_indices[i + 0]]].first;
+
+ for (int j = 0; j < 3; j++) {
+
+ int vertex_idx = gen_vertices[gen_indices[i + j]];
+
+ SurfaceTool::Vertex v = surfaces[surface].vertices[uv_index[gen_vertices[gen_indices[i + j]]].second];
+
+ if (surfaces[surface].format & ARRAY_FORMAT_COLOR) {
+ surfaces_tools[surface]->add_color(v.color);
+ }
+ if (surfaces[surface].format & ARRAY_FORMAT_TEX_UV) {
+ surfaces_tools[surface]->add_uv(v.uv);
+ }
+ if (surfaces[surface].format & ARRAY_FORMAT_NORMAL) {
+ surfaces_tools[surface]->add_normal(v.normal);
+ }
+ if (surfaces[surface].format & ARRAY_FORMAT_TANGENT) {
+ Plane t;
+ t.normal = v.tangent;
+ t.d = v.binormal.dot(v.normal.cross(v.tangent)) < 0 ? -1 : 1;
+ surfaces_tools[surface]->add_tangent(t);
+ }
+ if (surfaces[surface].format & ARRAY_FORMAT_BONES) {
+ surfaces_tools[surface]->add_bones(v.bones);
+ }
+ if (surfaces[surface].format & ARRAY_FORMAT_WEIGHTS) {
+ surfaces_tools[surface]->add_weights(v.weights);
+ }
+
+ Vector2 uv2(gen_uvs[gen_indices[i + j] * 2 + 0], gen_uvs[gen_indices[i + j] * 2 + 1]);
+ surfaces_tools[surface]->add_uv2(uv2);
+
+ surfaces_tools[surface]->add_vertex(v.vertex);
+ }
+ }
+
+ //free stuff
+ ::free(gen_vertices);
+ ::free(gen_indices);
+ ::free(gen_uvs);
+
+ //generate surfaces
+
+ for (int i = 0; i < surfaces_tools.size(); i++) {
+ surfaces_tools[i]->index();
+ surfaces_tools[i]->commit(Ref<ArrayMesh>((ArrayMesh *)this), surfaces[i].format);
+ }
+
+ set_lightmap_size_hint(Size2(size_x, size_y));
+
+ return OK;
+}
+
void ArrayMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_blend_shape", "name"), &ArrayMesh::add_blend_shape);
diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h
index b85a6a84af..ea38ebf2ff 100644
--- a/scene/resources/mesh.h
+++ b/scene/resources/mesh.h
@@ -43,6 +43,8 @@ class Mesh : public Resource {
GDCLASS(Mesh, Resource);
mutable Ref<TriangleMesh> triangle_mesh; //cached
+ Size2 lightmap_size_hint;
+
protected:
void _clear_triangle_mesh() const;
@@ -138,6 +140,9 @@ public:
virtual AABB get_aabb() const = 0;
+ void set_lightmap_size_hint(const Vector2 &p_size);
+ Size2 get_lightmap_size_hint() const;
+
Mesh();
};
@@ -216,6 +221,8 @@ public:
void center_geometry();
void regen_normalmaps();
+ Error lightmap_unwrap(const Transform &p_base_transform = Transform(), float p_texel_size = 0.05);
+
virtual void reload_from_file();
ArrayMesh();
diff --git a/scene/resources/plane_shape.cpp b/scene/resources/plane_shape.cpp
index 2b1e890a5d..2eb2ceff24 100644
--- a/scene/resources/plane_shape.cpp
+++ b/scene/resources/plane_shape.cpp
@@ -86,8 +86,8 @@ void PlaneShape::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::PLANE, "plane"), "set_plane", "get_plane");
}
-PlaneShape::PlaneShape()
- : Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_PLANE)) {
+PlaneShape::PlaneShape() :
+ Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_PLANE)) {
set_plane(Plane(0, 1, 0, 0));
}
diff --git a/scene/resources/ray_shape.cpp b/scene/resources/ray_shape.cpp
index ccce7660c6..b03a81b6bd 100644
--- a/scene/resources/ray_shape.cpp
+++ b/scene/resources/ray_shape.cpp
@@ -66,8 +66,8 @@ void RayShape::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "length", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_length", "get_length");
}
-RayShape::RayShape()
- : Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_RAY)) {
+RayShape::RayShape() :
+ Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_RAY)) {
set_length(1.0);
}
diff --git a/scene/resources/rectangle_shape_2d.cpp b/scene/resources/rectangle_shape_2d.cpp
index 69dbb76744..202024aa96 100644
--- a/scene/resources/rectangle_shape_2d.cpp
+++ b/scene/resources/rectangle_shape_2d.cpp
@@ -66,8 +66,8 @@ void RectangleShape2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "extents"), "set_extents", "get_extents");
}
-RectangleShape2D::RectangleShape2D()
- : Shape2D(Physics2DServer::get_singleton()->rectangle_shape_create()) {
+RectangleShape2D::RectangleShape2D() :
+ Shape2D(Physics2DServer::get_singleton()->rectangle_shape_create()) {
extents = Vector2(10, 10);
_update_shape();
diff --git a/scene/resources/segment_shape_2d.cpp b/scene/resources/segment_shape_2d.cpp
index 7c7ec0d112..e8ef448e23 100644
--- a/scene/resources/segment_shape_2d.cpp
+++ b/scene/resources/segment_shape_2d.cpp
@@ -86,8 +86,8 @@ void SegmentShape2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "b"), "set_b", "get_b");
}
-SegmentShape2D::SegmentShape2D()
- : Shape2D(Physics2DServer::get_singleton()->segment_shape_create()) {
+SegmentShape2D::SegmentShape2D() :
+ Shape2D(Physics2DServer::get_singleton()->segment_shape_create()) {
a = Vector2();
b = Vector2(0, 10);
@@ -145,8 +145,8 @@ real_t RayShape2D::get_length() const {
return length;
}
-RayShape2D::RayShape2D()
- : Shape2D(Physics2DServer::get_singleton()->ray_shape_create()) {
+RayShape2D::RayShape2D() :
+ Shape2D(Physics2DServer::get_singleton()->ray_shape_create()) {
length = 20;
_update_shape();
diff --git a/scene/resources/shape_line_2d.cpp b/scene/resources/shape_line_2d.cpp
index d046ce876c..512ff3bc56 100644
--- a/scene/resources/shape_line_2d.cpp
+++ b/scene/resources/shape_line_2d.cpp
@@ -95,8 +95,8 @@ void LineShape2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "d"), "set_d", "get_d");
}
-LineShape2D::LineShape2D()
- : Shape2D(Physics2DServer::get_singleton()->line_shape_create()) {
+LineShape2D::LineShape2D() :
+ Shape2D(Physics2DServer::get_singleton()->line_shape_create()) {
normal = Vector2(0, -1);
d = 0;
diff --git a/scene/resources/sphere_shape.cpp b/scene/resources/sphere_shape.cpp
index 00203c2b4b..042988dcd3 100644
--- a/scene/resources/sphere_shape.cpp
+++ b/scene/resources/sphere_shape.cpp
@@ -80,8 +80,8 @@ void SphereShape::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_radius", "get_radius");
}
-SphereShape::SphereShape()
- : Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_SPHERE)) {
+SphereShape::SphereShape() :
+ Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_SPHERE)) {
set_radius(1.0);
}
diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp
index bf89e704bc..d8600e041d 100644
--- a/scene/resources/surface_tool.cpp
+++ b/scene/resources/surface_tool.cpp
@@ -101,6 +101,7 @@ void SurfaceTool::add_vertex(const Vector3 &p_vertex) {
vtx.color = last_color;
vtx.normal = last_normal;
vtx.uv = last_uv;
+ vtx.uv2 = last_uv2;
vtx.weights = last_weights;
vtx.bones = last_bones;
vtx.tangent = last_tangent.normal;
@@ -401,7 +402,7 @@ Array SurfaceTool::commit_to_arrays() {
return a;
}
-Ref<ArrayMesh> SurfaceTool::commit(const Ref<ArrayMesh> &p_existing) {
+Ref<ArrayMesh> SurfaceTool::commit(const Ref<ArrayMesh> &p_existing, uint32_t p_flags) {
Ref<ArrayMesh> mesh;
if (p_existing.is_valid())
@@ -418,7 +419,7 @@ Ref<ArrayMesh> SurfaceTool::commit(const Ref<ArrayMesh> &p_existing) {
Array a = commit_to_arrays();
- mesh->add_surface_from_arrays(primitive, a);
+ mesh->add_surface_from_arrays(primitive, a, Array(), p_flags);
if (material.is_valid())
mesh->surface_set_material(surface, material);
@@ -482,6 +483,113 @@ void SurfaceTool::_create_list(const Ref<Mesh> &p_existing, int p_surface, List<
_create_list_from_arrays(arr, r_vertex, r_index, lformat);
}
+Vector<SurfaceTool::Vertex> SurfaceTool::create_vertex_array_from_triangle_arrays(const Array &p_arrays) {
+
+ Vector<SurfaceTool::Vertex> ret;
+
+ PoolVector<Vector3> varr = p_arrays[VS::ARRAY_VERTEX];
+ PoolVector<Vector3> narr = p_arrays[VS::ARRAY_NORMAL];
+ PoolVector<float> tarr = p_arrays[VS::ARRAY_TANGENT];
+ PoolVector<Color> carr = p_arrays[VS::ARRAY_COLOR];
+ PoolVector<Vector2> uvarr = p_arrays[VS::ARRAY_TEX_UV];
+ PoolVector<Vector2> uv2arr = p_arrays[VS::ARRAY_TEX_UV2];
+ PoolVector<int> barr = p_arrays[VS::ARRAY_BONES];
+ PoolVector<float> warr = p_arrays[VS::ARRAY_WEIGHTS];
+
+ int vc = varr.size();
+
+ if (vc == 0)
+ return ret;
+ int lformat = 0;
+
+ PoolVector<Vector3>::Read rv;
+ if (varr.size()) {
+ lformat |= VS::ARRAY_FORMAT_VERTEX;
+ rv = varr.read();
+ }
+ PoolVector<Vector3>::Read rn;
+ if (narr.size()) {
+ lformat |= VS::ARRAY_FORMAT_NORMAL;
+ rn = narr.read();
+ }
+ PoolVector<float>::Read rt;
+ if (tarr.size()) {
+ lformat |= VS::ARRAY_FORMAT_TANGENT;
+ rt = tarr.read();
+ }
+ PoolVector<Color>::Read rc;
+ if (carr.size()) {
+ lformat |= VS::ARRAY_FORMAT_COLOR;
+ rc = carr.read();
+ }
+
+ PoolVector<Vector2>::Read ruv;
+ if (uvarr.size()) {
+ lformat |= VS::ARRAY_FORMAT_TEX_UV;
+ ruv = uvarr.read();
+ }
+
+ PoolVector<Vector2>::Read ruv2;
+ if (uv2arr.size()) {
+ lformat |= VS::ARRAY_FORMAT_TEX_UV2;
+ ruv2 = uv2arr.read();
+ }
+
+ PoolVector<int>::Read rb;
+ if (barr.size()) {
+ lformat |= VS::ARRAY_FORMAT_BONES;
+ rb = barr.read();
+ }
+
+ PoolVector<float>::Read rw;
+ if (warr.size()) {
+ lformat |= VS::ARRAY_FORMAT_WEIGHTS;
+ rw = warr.read();
+ }
+
+ for (int i = 0; i < vc; i++) {
+
+ Vertex v;
+ if (lformat & VS::ARRAY_FORMAT_VERTEX)
+ v.vertex = varr[i];
+ if (lformat & VS::ARRAY_FORMAT_NORMAL)
+ v.normal = narr[i];
+ if (lformat & VS::ARRAY_FORMAT_TANGENT) {
+ Plane p(tarr[i * 4 + 0], tarr[i * 4 + 1], tarr[i * 4 + 2], tarr[i * 4 + 3]);
+ v.tangent = p.normal;
+ v.binormal = p.normal.cross(v.tangent).normalized() * p.d;
+ }
+ if (lformat & VS::ARRAY_FORMAT_COLOR)
+ v.color = carr[i];
+ if (lformat & VS::ARRAY_FORMAT_TEX_UV)
+ v.uv = uvarr[i];
+ if (lformat & VS::ARRAY_FORMAT_TEX_UV2)
+ v.uv2 = uv2arr[i];
+ if (lformat & VS::ARRAY_FORMAT_BONES) {
+ Vector<int> b;
+ b.resize(4);
+ b[0] = barr[i * 4 + 0];
+ b[1] = barr[i * 4 + 1];
+ b[2] = barr[i * 4 + 2];
+ b[3] = barr[i * 4 + 3];
+ v.bones = b;
+ }
+ if (lformat & VS::ARRAY_FORMAT_WEIGHTS) {
+ Vector<float> w;
+ w.resize(4);
+ w[0] = warr[i * 4 + 0];
+ w[1] = warr[i * 4 + 1];
+ w[2] = warr[i * 4 + 2];
+ w[3] = warr[i * 4 + 3];
+ v.weights = w;
+ }
+
+ ret.push_back(v);
+ }
+
+ return ret;
+}
+
void SurfaceTool::_create_list_from_arrays(Array arr, List<Vertex> *r_vertex, List<int> *r_index, int &lformat) {
PoolVector<Vector3> varr = arr[VS::ARRAY_VERTEX];
@@ -882,7 +990,7 @@ void SurfaceTool::_bind_methods() {
ClassDB::bind_method(D_METHOD("create_from", "existing", "surface"), &SurfaceTool::create_from);
ClassDB::bind_method(D_METHOD("append_from", "existing", "surface", "transform"), &SurfaceTool::append_from);
- ClassDB::bind_method(D_METHOD("commit", "existing"), &SurfaceTool::commit, DEFVAL(Variant()));
+ ClassDB::bind_method(D_METHOD("commit", "existing", "flags"), &SurfaceTool::commit, DEFVAL(Variant()), DEFVAL(Mesh::ARRAY_COMPRESS_DEFAULT));
}
SurfaceTool::SurfaceTool() {
diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h
index cdaac643de..b180ffe260 100644
--- a/scene/resources/surface_tool.h
+++ b/scene/resources/surface_tool.h
@@ -127,10 +127,11 @@ public:
List<Vertex> &get_vertex_array() { return vertex_array; }
void create_from_triangle_arrays(const Array &p_arrays);
+ static Vector<Vertex> create_vertex_array_from_triangle_arrays(const Array &p_arrays);
Array commit_to_arrays();
void create_from(const Ref<Mesh> &p_existing, int p_surface);
void append_from(const Ref<Mesh> &p_existing, int p_surface, const Transform &p_xform);
- Ref<ArrayMesh> commit(const Ref<ArrayMesh> &p_existing = Ref<ArrayMesh>());
+ Ref<ArrayMesh> commit(const Ref<ArrayMesh> &p_existing = Ref<ArrayMesh>(), uint32_t p_flags = Mesh::ARRAY_COMPRESS_DEFAULT);
SurfaceTool();
};
diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp
index 6fab597d2b..1a46353fe3 100644
--- a/scene/resources/tile_set.cpp
+++ b/scene/resources/tile_set.cpp
@@ -83,7 +83,7 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
}
}
} else if (what == "occluder_map") {
- tile_map[id].autotile_data.ocludder_map.clear();
+ tile_map[id].autotile_data.occluder_map.clear();
Array p = p_value;
Vector2 last_coord;
while (p.size() > 0) {
@@ -194,7 +194,7 @@ bool TileSet::_get(const StringName &p_name, Variant &r_ret) const {
r_ret = p;
} else if (what == "occluder_map") {
Array p;
- for (Map<Vector2, Ref<OccluderPolygon2D> >::Element *E = tile_map[id].autotile_data.ocludder_map.front(); E; E = E->next()) {
+ for (Map<Vector2, Ref<OccluderPolygon2D> >::Element *E = tile_map[id].autotile_data.occluder_map.front(); E; E = E->next()) {
p.push_back(E->key());
p.push_back(E->value());
}
@@ -643,20 +643,20 @@ Ref<OccluderPolygon2D> TileSet::tile_get_light_occluder(int p_id) const {
void TileSet::autotile_set_light_occluder(int p_id, const Ref<OccluderPolygon2D> &p_light_occluder, const Vector2 &p_coord) {
ERR_FAIL_COND(!tile_map.has(p_id));
if (p_light_occluder.is_null()) {
- if (tile_map[p_id].autotile_data.ocludder_map.has(p_coord)) {
- tile_map[p_id].autotile_data.ocludder_map.erase(p_coord);
+ if (tile_map[p_id].autotile_data.occluder_map.has(p_coord)) {
+ tile_map[p_id].autotile_data.occluder_map.erase(p_coord);
}
} else {
- tile_map[p_id].autotile_data.ocludder_map[p_coord] = p_light_occluder;
+ tile_map[p_id].autotile_data.occluder_map[p_coord] = p_light_occluder;
}
}
Ref<OccluderPolygon2D> TileSet::autotile_get_light_occluder(int p_id, const Vector2 &p_coord) const {
ERR_FAIL_COND_V(!tile_map.has(p_id), Ref<OccluderPolygon2D>());
- if (!tile_map[p_id].autotile_data.ocludder_map.has(p_coord)) {
+ if (!tile_map[p_id].autotile_data.occluder_map.has(p_coord)) {
return Ref<OccluderPolygon2D>();
} else {
- return tile_map[p_id].autotile_data.ocludder_map[p_coord];
+ return tile_map[p_id].autotile_data.occluder_map[p_coord];
}
}
@@ -688,7 +688,7 @@ const Map<Vector2, Ref<OccluderPolygon2D> > &TileSet::autotile_get_light_oclusio
static Map<Vector2, Ref<OccluderPolygon2D> > dummy;
ERR_FAIL_COND_V(!tile_map.has(p_id), dummy);
- return tile_map[p_id].autotile_data.ocludder_map;
+ return tile_map[p_id].autotile_data.occluder_map;
}
void TileSet::autotile_set_navigation_polygon(int p_id, const Ref<NavigationPolygon> &p_navigation_polygon, const Vector2 &p_coord) {
diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h
index 18b62c778d..deac583f62 100644
--- a/scene/resources/tile_set.h
+++ b/scene/resources/tile_set.h
@@ -76,13 +76,14 @@ public:
Size2 size;
Vector2 icon_coord;
Map<Vector2, uint16_t> flags;
- Map<Vector2, Ref<OccluderPolygon2D> > ocludder_map;
+ Map<Vector2, Ref<OccluderPolygon2D> > occluder_map;
Map<Vector2, Ref<NavigationPolygon> > navpoly_map;
Map<Vector2, int> priority_map;
// Default size to prevent invalid value
- explicit AutotileData()
- : size(64, 64), icon_coord(0, 0) {
+ explicit AutotileData() :
+ size(64, 64),
+ icon_coord(0, 0) {
bitmask_mode = BITMASK_2X2;
}
};
@@ -106,8 +107,9 @@ private:
AutotileData autotile_data;
// Default modulate for back-compat
- explicit TileData()
- : modulate(1, 1, 1), is_autotile(false) {}
+ explicit TileData() :
+ modulate(1, 1, 1),
+ is_autotile(false) {}
};
Map<int, TileData> tile_map;