summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/2d/canvas_item.cpp13
-rw-r--r--scene/2d/canvas_item.h2
-rw-r--r--scene/2d/light_2d.cpp2
-rw-r--r--scene/3d/camera.cpp2
-rw-r--r--scene/3d/spatial.cpp12
-rw-r--r--scene/3d/spatial.h2
-rw-r--r--scene/gui/control.cpp5
-rw-r--r--scene/gui/gradient_edit.cpp64
-rw-r--r--scene/gui/gradient_edit.h2
-rw-r--r--scene/gui/popup.cpp51
-rw-r--r--scene/gui/popup.h2
-rw-r--r--scene/gui/text_edit.cpp4
-rw-r--r--scene/main/node.cpp16
-rw-r--r--scene/main/node.h1
-rw-r--r--scene/main/scene_tree.cpp1
-rw-r--r--scene/resources/multimesh.cpp88
-rw-r--r--scene/resources/multimesh.h18
-rw-r--r--scene/resources/texture.cpp2
18 files changed, 239 insertions, 48 deletions
diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp
index 7f7e3542ed..3914c75ca8 100644
--- a/scene/2d/canvas_item.cpp
+++ b/scene/2d/canvas_item.cpp
@@ -967,6 +967,17 @@ Vector2 CanvasItem::get_local_mouse_position() const {
return get_global_transform().affine_inverse().xform(get_global_mouse_position());
}
+void CanvasItem::force_update_transform() {
+ ERR_FAIL_COND(!is_inside_tree());
+ if (!xform_change.in_list()) {
+ return;
+ }
+
+ get_tree()->xform_change_list.remove(&xform_change);
+
+ notification(NOTIFICATION_TRANSFORM_CHANGED);
+}
+
void CanvasItem::_bind_methods() {
ClassDB::bind_method(D_METHOD("_toplevel_raise_self"), &CanvasItem::_toplevel_raise_self);
@@ -1061,6 +1072,8 @@ void CanvasItem::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_notify_transform", "enable"), &CanvasItem::set_notify_transform);
ClassDB::bind_method(D_METHOD("is_transform_notification_enabled"), &CanvasItem::is_transform_notification_enabled);
+ ClassDB::bind_method(D_METHOD("force_update_transform"), &CanvasItem::force_update_transform);
+
ClassDB::bind_method(D_METHOD("make_canvas_position_local", "screen_point"), &CanvasItem::make_canvas_position_local);
ClassDB::bind_method(D_METHOD("make_input_local", "event"), &CanvasItem::make_input_local);
diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h
index 1e6a251c9c..6dc2e2e39d 100644
--- a/scene/2d/canvas_item.h
+++ b/scene/2d/canvas_item.h
@@ -346,6 +346,8 @@ public:
void set_notify_transform(bool p_enable);
bool is_transform_notification_enabled() const;
+ void force_update_transform();
+
// Used by control nodes to retreive the parent's anchorable area
virtual Rect2 get_anchorable_rect() const { return Rect2(0, 0, 0, 0); };
diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp
index f93c7d1f79..4d24daa5a7 100644
--- a/scene/2d/light_2d.cpp
+++ b/scene/2d/light_2d.cpp
@@ -431,7 +431,7 @@ void Light2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor_only"), "set_editor_only", "is_editor_only");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "StreamTexture,ImageTexture"), "set_texture", "get_texture");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_texture_offset", "get_texture_offset");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "texture_scale", PROPERTY_HINT_RANGE, "0.01,50,0.01"), "set_texture_scale", "get_texture_scale");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color");
diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp
index a4582b7d7d..6ecf219c2b 100644
--- a/scene/3d/camera.cpp
+++ b/scene/3d/camera.cpp
@@ -553,11 +553,13 @@ Camera::Projection Camera::get_projection() const {
void Camera::set_fov(float p_fov) {
fov = p_fov;
_update_camera_mode();
+ _change_notify("fov");
}
void Camera::set_size(float p_size) {
size = p_size;
_update_camera_mode();
+ _change_notify("size");
}
void Camera::set_znear(float p_znear) {
diff --git a/scene/3d/spatial.cpp b/scene/3d/spatial.cpp
index d52f634639..d6141c12a8 100644
--- a/scene/3d/spatial.cpp
+++ b/scene/3d/spatial.cpp
@@ -721,6 +721,16 @@ bool Spatial::is_local_transform_notification_enabled() const {
return data.notify_local_transform;
}
+void Spatial::force_update_transform() {
+ ERR_FAIL_COND(!is_inside_tree());
+ if (!xform_change.in_list()) {
+ return; //nothing to update
+ }
+ get_tree()->xform_change_list.remove(&xform_change);
+
+ notification(NOTIFICATION_TRANSFORM_CHANGED);
+}
+
void Spatial::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_transform", "local"), &Spatial::set_transform);
@@ -743,6 +753,8 @@ void Spatial::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_scale_disabled"), &Spatial::is_scale_disabled);
ClassDB::bind_method(D_METHOD("get_world"), &Spatial::get_world);
+ ClassDB::bind_method(D_METHOD("force_update_transform"), &Spatial::force_update_transform);
+
ClassDB::bind_method(D_METHOD("_update_gizmo"), &Spatial::_update_gizmo);
ClassDB::bind_method(D_METHOD("update_gizmo"), &Spatial::update_gizmo);
diff --git a/scene/3d/spatial.h b/scene/3d/spatial.h
index 8d3c32d116..815ca16bc5 100644
--- a/scene/3d/spatial.h
+++ b/scene/3d/spatial.h
@@ -202,6 +202,8 @@ public:
void hide();
bool is_visible_in_tree() const;
+ void force_update_transform();
+
Spatial();
~Spatial();
};
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index fad91c29cf..dc042b88d2 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -2062,8 +2062,11 @@ void Control::grab_focus() {
if (!is_inside_tree()) {
ERR_FAIL_COND(!is_inside_tree());
}
- if (data.focus_mode == FOCUS_NONE)
+
+ if (data.focus_mode == FOCUS_NONE) {
+ WARN_PRINT("This control can't grab focus. Use set_focus_mode() to allow a control to get focus.");
return;
+ }
get_viewport()->_gui_control_grab_focus(this);
}
diff --git a/scene/gui/gradient_edit.cpp b/scene/gui/gradient_edit.cpp
index e82c0c4ad1..dc013f00a5 100644
--- a/scene/gui/gradient_edit.cpp
+++ b/scene/gui/gradient_edit.cpp
@@ -29,8 +29,11 @@
/*************************************************************************/
#include "gradient_edit.h"
+#include "editor/editor_scale.h"
#include "os/keyboard.h"
+#define SPACING (3 * EDSCALE)
+
GradientEdit::GradientEdit() {
grabbed = -1;
grabbing = false;
@@ -49,11 +52,15 @@ GradientEdit::GradientEdit() {
int GradientEdit::_get_point_from_pos(int x) {
int result = -1;
- int total_w = get_size().width - get_size().height - 3;
+ int total_w = get_size().width - get_size().height - SPACING;
+ float min_distance = 1e20;
for (int i = 0; i < points.size(); i++) {
//Check if we clicked at point
- if (ABS(x - points[i].offset * total_w + 1) < (POINT_WIDTH / 2 + 1)) {
+ float distance = ABS(x - points[i].offset * total_w);
+ float min = (POINT_WIDTH / 2 * 1.7); //make it easier to grab
+ if (distance <= min && distance < min_distance) {
result = i;
+ min_distance = distance;
}
}
return result;
@@ -63,7 +70,16 @@ void GradientEdit::_show_color_picker() {
if (grabbed == -1)
return;
picker->set_pick_color(points[grabbed].color);
- popup->set_position(get_global_position() - popup->get_combined_minimum_size());
+ Size2 minsize = popup->get_combined_minimum_size();
+ bool show_above = false;
+ if (get_global_position().y + get_size().y + minsize.y > get_viewport_rect().size.y) {
+ show_above = true;
+ }
+ if (show_above) {
+ popup->set_position(get_global_position() - Vector2(0, minsize.y));
+ } else {
+ popup->set_position(get_global_position() + Vector2(0, get_size().y));
+ }
popup->popup();
}
@@ -112,7 +128,7 @@ void GradientEdit::_gui_input(const Ref<InputEvent> &p_event) {
grabbed = _get_point_from_pos(x);
if (grabbed != -1) {
- int total_w = get_size().width - get_size().height - 3;
+ int total_w = get_size().width - get_size().height - SPACING;
Gradient::Point newPoint = points[grabbed];
newPoint.offset = CLAMP(x / float(total_w), 0, 1);
@@ -130,14 +146,15 @@ void GradientEdit::_gui_input(const Ref<InputEvent> &p_event) {
}
}
+ //select
if (mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed()) {
update();
int x = mb->get_position().x;
- int total_w = get_size().width - get_size().height - 3;
+ int total_w = get_size().width - get_size().height - SPACING;
//Check if color selector was clicked.
- if (x > total_w + 3) {
+ if (x > total_w + SPACING) {
_show_color_picker();
return;
}
@@ -211,7 +228,7 @@ void GradientEdit::_gui_input(const Ref<InputEvent> &p_event) {
if (mm.is_valid() && grabbing) {
- int total_w = get_size().width - get_size().height - 3;
+ int total_w = get_size().width - get_size().height - SPACING;
int x = mm->get_position().x;
@@ -286,7 +303,7 @@ void GradientEdit::_notification(int p_what) {
if (w == 0 || h == 0)
return; //Safety check. We have division by 'h'. And in any case there is nothing to draw with such size
- int total_w = get_size().width - get_size().height - 3;
+ int total_w = get_size().width - get_size().height - SPACING;
//Draw checker pattern for ramp
_draw_checker(0, 0, total_w, h);
@@ -335,27 +352,36 @@ void GradientEdit::_notification(int p_what) {
//Draw point markers
for (int i = 0; i < points.size(); i++) {
- Color col = i == grabbed ? Color(1, 0.0, 0.0, 0.9) : points[i].color.contrasted();
+ Color col = points[i].color.contrasted();
col.a = 0.9;
draw_line(Vector2(points[i].offset * total_w, 0), Vector2(points[i].offset * total_w, h / 2), col);
- draw_rect(Rect2(points[i].offset * total_w - POINT_WIDTH / 2, h / 2, POINT_WIDTH, h / 2), Color(0.6, 0.6, 0.6, i == grabbed ? 0.9 : 0.4));
- draw_line(Vector2(points[i].offset * total_w - POINT_WIDTH / 2, h / 2), Vector2(points[i].offset * total_w - POINT_WIDTH / 2, h - 1), col);
- draw_line(Vector2(points[i].offset * total_w + POINT_WIDTH / 2, h / 2), Vector2(points[i].offset * total_w + POINT_WIDTH / 2, h - 1), col);
- draw_line(Vector2(points[i].offset * total_w - POINT_WIDTH / 2, h / 2), Vector2(points[i].offset * total_w + POINT_WIDTH / 2, h / 2), col);
- draw_line(Vector2(points[i].offset * total_w - POINT_WIDTH / 2, h - 1), Vector2(points[i].offset * total_w + POINT_WIDTH / 2, h - 1), col);
+ Rect2 rect = Rect2(points[i].offset * total_w - POINT_WIDTH / 2, h / 2, POINT_WIDTH, h / 2);
+ draw_rect(rect, points[i].color, true);
+ draw_rect(rect, col, false);
+ if (grabbed == i) {
+ rect = rect.grow(-1);
+ if (has_focus()) {
+ draw_rect(rect, Color(1, 0, 0, 0.9), false);
+ } else {
+ draw_rect(rect, Color(0.6, 0, 0, 0.9), false);
+ }
+
+ rect = rect.grow(-1);
+ draw_rect(rect, col, false);
+ }
}
//Draw "button" for color selector
- _draw_checker(total_w + 3, 0, h, h);
+ _draw_checker(total_w + SPACING, 0, h, h);
if (grabbed != -1) {
//Draw with selection color
- draw_rect(Rect2(total_w + 3, 0, h, h), points[grabbed].color);
+ draw_rect(Rect2(total_w + SPACING, 0, h, h), points[grabbed].color);
} else {
//if no color selected draw grey color with 'X' on top.
- draw_rect(Rect2(total_w + 3, 0, h, h), Color(0.5, 0.5, 0.5, 1));
- draw_line(Vector2(total_w + 3, 0), Vector2(total_w + 3 + h, h), Color(1, 1, 1, 0.6));
- draw_line(Vector2(total_w + 3, h), Vector2(total_w + 3 + h, 0), Color(1, 1, 1, 0.6));
+ draw_rect(Rect2(total_w + SPACING, 0, h, h), Color(0.5, 0.5, 0.5, 1));
+ draw_line(Vector2(total_w + SPACING, 0), Vector2(total_w + SPACING + h, h), Color(1, 1, 1, 0.6));
+ draw_line(Vector2(total_w + SPACING, h), Vector2(total_w + SPACING + h, 0), Color(1, 1, 1, 0.6));
}
//Draw borders around color ramp if in focus
diff --git a/scene/gui/gradient_edit.h b/scene/gui/gradient_edit.h
index e7834ea0de..f6927ad0b7 100644
--- a/scene/gui/gradient_edit.h
+++ b/scene/gui/gradient_edit.h
@@ -36,7 +36,7 @@
#include "scene/resources/color_ramp.h"
#include "scene/resources/default_theme/theme_data.h"
-#define POINT_WIDTH 8
+#define POINT_WIDTH (8 * EDSCALE)
class GradientEdit : public Control {
diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp
index 26d01ecc09..2add67ace1 100644
--- a/scene/gui/popup.cpp
+++ b/scene/gui/popup.cpp
@@ -234,15 +234,46 @@ String Popup::get_configuration_warning() const {
Popup::~Popup() {
}
-void PopupPanel::set_child_rect(Control *p_child) {
- ERR_FAIL_NULL(p_child);
+Size2 PopupPanel::get_minimum_size() const {
Ref<StyleBox> p = get_stylebox("panel");
- p_child->set_anchors_preset(Control::PRESET_WIDE);
- p_child->set_margin(MARGIN_LEFT, p->get_margin(MARGIN_LEFT));
- p_child->set_margin(MARGIN_RIGHT, -p->get_margin(MARGIN_RIGHT));
- p_child->set_margin(MARGIN_TOP, p->get_margin(MARGIN_TOP));
- p_child->set_margin(MARGIN_BOTTOM, -p->get_margin(MARGIN_BOTTOM));
+
+ Size2 ms;
+
+ for (int i = 0; i < get_child_count(); i++) {
+ Control *c = Object::cast_to<Control>(get_child(i));
+ if (!c)
+ continue;
+
+ if (c->is_set_as_toplevel())
+ continue;
+
+ Size2 cms = c->get_combined_minimum_size();
+ ms.x = MAX(cms.x, ms.x);
+ ms.y = MAX(cms.y, ms.y);
+ }
+
+ return ms + p->get_minimum_size();
+}
+
+void PopupPanel::_update_child_rects() {
+
+ Ref<StyleBox> p = get_stylebox("panel");
+
+ Vector2 cpos(p->get_offset());
+ Vector2 csize(get_size() - p->get_minimum_size());
+
+ for (int i = 0; i < get_child_count(); i++) {
+ Control *c = Object::cast_to<Control>(get_child(i));
+ if (!c)
+ continue;
+
+ if (c->is_set_as_toplevel())
+ continue;
+
+ c->set_position(cpos);
+ c->set_size(csize);
+ }
}
void PopupPanel::_notification(int p_what) {
@@ -250,6 +281,12 @@ void PopupPanel::_notification(int p_what) {
if (p_what == NOTIFICATION_DRAW) {
get_stylebox("panel")->draw(get_canvas_item(), Rect2(Point2(), get_size()));
+ } else if (p_what == NOTIFICATION_READY) {
+
+ _update_child_rects();
+ } else if (p_what == NOTIFICATION_RESIZED) {
+
+ _update_child_rects();
}
}
diff --git a/scene/gui/popup.h b/scene/gui/popup.h
index 550e803578..5b1ef7d6ca 100644
--- a/scene/gui/popup.h
+++ b/scene/gui/popup.h
@@ -77,10 +77,12 @@ class PopupPanel : public Popup {
GDCLASS(PopupPanel, Popup);
protected:
+ void _update_child_rects();
void _notification(int p_what);
public:
void set_child_rect(Control *p_child);
+ virtual Size2 get_minimum_size() const;
PopupPanel();
};
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index ec98b01ced..a32beecdd9 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -6400,8 +6400,8 @@ Map<int, TextEdit::HighlighterInfo> TextEdit::_get_line_syntax_highlighting(int
is_hex_notation = false;
}
- // check for dot or underscore or 'x' for hex notation in floating point number
- if ((str[j] == '.' || str[j] == 'x' || str[j] == '_' || str[j] == 'f') && !in_word && prev_is_number && !is_number) {
+ // check for dot or underscore or 'x' for hex notation in floating point number or 'e' for scientific notation
+ if ((str[j] == '.' || str[j] == 'x' || str[j] == '_' || str[j] == 'f' || str[j] == 'e') && !in_word && prev_is_number && !is_number) {
is_number = true;
is_symbol = false;
is_char = false;
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index e30f58e012..3d1614199a 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -238,6 +238,16 @@ void Node::_propagate_enter_tree() {
// enter groups
}
+void Node::_propagate_after_exit_tree() {
+
+ data.blocked++;
+ for (int i = 0; i < data.children.size(); i++) {
+ data.children[i]->_propagate_after_exit_tree();
+ }
+ data.blocked--;
+ emit_signal(SceneStringNames::get_singleton()->tree_exited);
+}
+
void Node::_propagate_exit_tree() {
//block while removing children
@@ -299,8 +309,6 @@ void Node::_propagate_exit_tree() {
data.ready_notified = false;
data.tree = NULL;
data.depth = -1;
-
- emit_signal(SceneStringNames::get_singleton()->tree_exited);
}
void Node::move_child(Node *p_child, int p_pos) {
@@ -1207,6 +1215,10 @@ void Node::remove_child(Node *p_child) {
// validate owner
p_child->_propagate_validate_owner();
+
+ if (data.inside_tree) {
+ p_child->_propagate_after_exit_tree();
+ }
}
int Node::get_child_count() const {
diff --git a/scene/main/node.h b/scene/main/node.h
index f3422618ce..fb84981feb 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -166,6 +166,7 @@ private:
void _propagate_enter_tree();
void _propagate_ready();
void _propagate_exit_tree();
+ void _propagate_after_exit_tree();
void _propagate_validate_owner();
void _print_stray_nodes();
void _propagate_pause_owner(Node *p_owner);
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index 11268cc5c6..0b763d2433 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -598,6 +598,7 @@ void SceneTree::finish() {
if (root) {
root->_set_tree(NULL);
+ root->_propagate_after_exit_tree();
memdelete(root); //delete root
}
}
diff --git a/scene/resources/multimesh.cpp b/scene/resources/multimesh.cpp
index 4d0a14e3aa..e8e19fdb60 100644
--- a/scene/resources/multimesh.cpp
+++ b/scene/resources/multimesh.cpp
@@ -33,8 +33,6 @@
void MultiMesh::_set_transform_array(const PoolVector<Vector3> &p_array) {
- int instance_count = get_instance_count();
-
PoolVector<Vector3> xforms = p_array;
int len = xforms.size();
ERR_FAIL_COND((len / 4) != instance_count);
@@ -57,8 +55,6 @@ void MultiMesh::_set_transform_array(const PoolVector<Vector3> &p_array) {
PoolVector<Vector3> MultiMesh::_get_transform_array() const {
- int instance_count = get_instance_count();
-
if (instance_count == 0)
return PoolVector<Vector3>();
@@ -81,13 +77,11 @@ PoolVector<Vector3> MultiMesh::_get_transform_array() const {
void MultiMesh::_set_color_array(const PoolVector<Color> &p_array) {
- int instance_count = get_instance_count();
-
PoolVector<Color> colors = p_array;
int len = colors.size();
- ERR_FAIL_COND(len != instance_count);
if (len == 0)
return;
+ ERR_FAIL_COND(len != instance_count);
PoolVector<Color>::Read r = colors.read();
@@ -99,9 +93,7 @@ void MultiMesh::_set_color_array(const PoolVector<Color> &p_array) {
PoolVector<Color> MultiMesh::_get_color_array() const {
- int instance_count = get_instance_count();
-
- if (instance_count == 0)
+ if (instance_count == 0 || color_format == COLOR_NONE)
return PoolVector<Color>();
PoolVector<Color> colors;
@@ -115,6 +107,37 @@ PoolVector<Color> MultiMesh::_get_color_array() const {
return colors;
}
+void MultiMesh::_set_custom_data_array(const PoolVector<Color> &p_array) {
+
+ PoolVector<Color> custom_datas = p_array;
+ int len = custom_datas.size();
+ if (len == 0)
+ return;
+ ERR_FAIL_COND(len != instance_count);
+
+ PoolVector<Color>::Read r = custom_datas.read();
+
+ for (int i = 0; i < len; i++) {
+
+ set_instance_custom_data(i, r[i]);
+ }
+}
+
+PoolVector<Color> MultiMesh::_get_custom_data_array() const {
+
+ if (instance_count == 0 || custom_data_format == CUSTOM_DATA_NONE)
+ return PoolVector<Color>();
+
+ PoolVector<Color> custom_datas;
+ custom_datas.resize(instance_count);
+
+ for (int i = 0; i < instance_count; i++) {
+
+ custom_datas.set(i, get_instance_custom_data(i));
+ }
+
+ return custom_datas;
+}
void MultiMesh::set_mesh(const Ref<Mesh> &p_mesh) {
mesh = p_mesh;
@@ -130,12 +153,13 @@ Ref<Mesh> MultiMesh::get_mesh() const {
}
void MultiMesh::set_instance_count(int p_count) {
-
- VisualServer::get_singleton()->multimesh_allocate(multimesh, p_count, VS::MultimeshTransformFormat(transform_format), VS::MultimeshColorFormat(color_format));
+ ERR_FAIL_COND(p_count < 0);
+ VisualServer::get_singleton()->multimesh_allocate(multimesh, p_count, VS::MultimeshTransformFormat(transform_format), VS::MultimeshColorFormat(color_format), VS::MultimeshCustomDataFormat(custom_data_format));
+ instance_count = p_count;
}
int MultiMesh::get_instance_count() const {
- return VisualServer::get_singleton()->multimesh_get_instance_count(multimesh);
+ return instance_count;
}
void MultiMesh::set_instance_transform(int p_instance, const Transform &p_transform) {
@@ -156,6 +180,15 @@ Color MultiMesh::get_instance_color(int p_instance) const {
return VisualServer::get_singleton()->multimesh_instance_get_color(multimesh, p_instance);
}
+void MultiMesh::set_instance_custom_data(int p_instance, const Color &p_custom_data) {
+
+ VisualServer::get_singleton()->multimesh_instance_set_custom_data(multimesh, p_instance, p_custom_data);
+}
+Color MultiMesh::get_instance_custom_data(int p_instance) const {
+
+ return VisualServer::get_singleton()->multimesh_instance_get_custom_data(multimesh, p_instance);
+}
+
AABB MultiMesh::get_aabb() const {
return VisualServer::get_singleton()->multimesh_get_aabb(multimesh);
@@ -168,6 +201,7 @@ RID MultiMesh::get_rid() const {
void MultiMesh::set_color_format(ColorFormat p_color_format) {
+ ERR_FAIL_COND(instance_count > 0);
color_format = p_color_format;
}
@@ -176,8 +210,20 @@ MultiMesh::ColorFormat MultiMesh::get_color_format() const {
return color_format;
}
+void MultiMesh::set_custom_data_format(CustomDataFormat p_custom_data_format) {
+
+ ERR_FAIL_COND(instance_count > 0);
+ custom_data_format = p_custom_data_format;
+}
+
+MultiMesh::CustomDataFormat MultiMesh::get_custom_data_format() const {
+
+ return custom_data_format;
+}
+
void MultiMesh::set_transform_format(TransformFormat p_transform_format) {
+ ERR_FAIL_COND(instance_count > 0);
transform_format = p_transform_format;
}
MultiMesh::TransformFormat MultiMesh::get_transform_format() const {
@@ -191,6 +237,8 @@ void MultiMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_mesh"), &MultiMesh::get_mesh);
ClassDB::bind_method(D_METHOD("set_color_format", "format"), &MultiMesh::set_color_format);
ClassDB::bind_method(D_METHOD("get_color_format"), &MultiMesh::get_color_format);
+ ClassDB::bind_method(D_METHOD("set_custom_data_format", "format"), &MultiMesh::set_custom_data_format);
+ ClassDB::bind_method(D_METHOD("get_custom_data_format"), &MultiMesh::get_custom_data_format);
ClassDB::bind_method(D_METHOD("set_transform_format", "format"), &MultiMesh::set_transform_format);
ClassDB::bind_method(D_METHOD("get_transform_format"), &MultiMesh::get_transform_format);
@@ -200,19 +248,25 @@ void MultiMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_instance_transform", "instance"), &MultiMesh::get_instance_transform);
ClassDB::bind_method(D_METHOD("set_instance_color", "instance", "color"), &MultiMesh::set_instance_color);
ClassDB::bind_method(D_METHOD("get_instance_color", "instance"), &MultiMesh::get_instance_color);
+ ClassDB::bind_method(D_METHOD("set_instance_custom_data", "instance", "custom_data"), &MultiMesh::set_instance_custom_data);
+ ClassDB::bind_method(D_METHOD("get_instance_custom_data", "instance"), &MultiMesh::get_instance_custom_data);
ClassDB::bind_method(D_METHOD("get_aabb"), &MultiMesh::get_aabb);
ClassDB::bind_method(D_METHOD("_set_transform_array"), &MultiMesh::_set_transform_array);
ClassDB::bind_method(D_METHOD("_get_transform_array"), &MultiMesh::_get_transform_array);
ClassDB::bind_method(D_METHOD("_set_color_array"), &MultiMesh::_set_color_array);
ClassDB::bind_method(D_METHOD("_get_color_array"), &MultiMesh::_get_color_array);
+ ClassDB::bind_method(D_METHOD("_set_custom_data_array"), &MultiMesh::_set_custom_data_array);
+ ClassDB::bind_method(D_METHOD("_get_custom_data_array"), &MultiMesh::_get_custom_data_array);
ADD_PROPERTY(PropertyInfo(Variant::INT, "color_format", PROPERTY_HINT_ENUM, "None,Byte,Float"), "set_color_format", "get_color_format");
ADD_PROPERTY(PropertyInfo(Variant::INT, "transform_format", PROPERTY_HINT_ENUM, "2D,3D"), "set_transform_format", "get_transform_format");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "instance_count", PROPERTY_HINT_RANGE, "0,16384,1"), "set_instance_count", "get_instance_count");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "custom_data_format", PROPERTY_HINT_ENUM, "None,Byte,Float"), "set_custom_data_format", "get_custom_data_format");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "instance_count", PROPERTY_HINT_RANGE, "0,16384,1,or_greater"), "set_instance_count", "get_instance_count");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh");
ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR3_ARRAY, "transform_array", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_transform_array", "_get_transform_array");
ADD_PROPERTY(PropertyInfo(Variant::POOL_COLOR_ARRAY, "color_array", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_color_array", "_get_color_array");
+ ADD_PROPERTY(PropertyInfo(Variant::POOL_COLOR_ARRAY, "custom_data_array", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_custom_data_array", "_get_custom_data_array");
BIND_ENUM_CONSTANT(TRANSFORM_2D);
BIND_ENUM_CONSTANT(TRANSFORM_3D);
@@ -220,13 +274,19 @@ void MultiMesh::_bind_methods() {
BIND_ENUM_CONSTANT(COLOR_NONE);
BIND_ENUM_CONSTANT(COLOR_8BIT);
BIND_ENUM_CONSTANT(COLOR_FLOAT);
+
+ BIND_ENUM_CONSTANT(CUSTOM_DATA_NONE);
+ BIND_ENUM_CONSTANT(CUSTOM_DATA_8BIT);
+ BIND_ENUM_CONSTANT(CUSTOM_DATA_FLOAT);
}
MultiMesh::MultiMesh() {
multimesh = VisualServer::get_singleton()->multimesh_create();
color_format = COLOR_NONE;
+ custom_data_format = CUSTOM_DATA_NONE;
transform_format = TRANSFORM_2D;
+ instance_count = 0;
}
MultiMesh::~MultiMesh() {
diff --git a/scene/resources/multimesh.h b/scene/resources/multimesh.h
index 0875d6d06d..ec5a5ca4d5 100644
--- a/scene/resources/multimesh.h
+++ b/scene/resources/multimesh.h
@@ -51,11 +51,19 @@ public:
COLOR_FLOAT = VS::MULTIMESH_COLOR_FLOAT,
};
+ enum CustomDataFormat {
+ CUSTOM_DATA_NONE,
+ CUSTOM_DATA_8BIT,
+ CUSTOM_DATA_FLOAT,
+ };
+
private:
Ref<Mesh> mesh;
RID multimesh;
TransformFormat transform_format;
ColorFormat color_format;
+ CustomDataFormat custom_data_format;
+ int instance_count;
protected:
static void _bind_methods();
@@ -66,6 +74,9 @@ protected:
void _set_color_array(const PoolVector<Color> &p_array);
PoolVector<Color> _get_color_array() const;
+ void _set_custom_data_array(const PoolVector<Color> &p_array);
+ PoolVector<Color> _get_custom_data_array() const;
+
public:
void set_mesh(const Ref<Mesh> &p_mesh);
Ref<Mesh> get_mesh() const;
@@ -73,6 +84,9 @@ public:
void set_color_format(ColorFormat p_color_format);
ColorFormat get_color_format() const;
+ void set_custom_data_format(CustomDataFormat p_custom_data_format);
+ CustomDataFormat get_custom_data_format() const;
+
void set_transform_format(TransformFormat p_transform_format);
TransformFormat get_transform_format() const;
@@ -85,6 +99,9 @@ public:
void set_instance_color(int p_instance, const Color &p_color);
Color get_instance_color(int p_instance) const;
+ void set_instance_custom_data(int p_instance, const Color &p_custom_data);
+ Color get_instance_custom_data(int p_instance) const;
+
virtual AABB get_aabb() const;
virtual RID get_rid() const;
@@ -95,5 +112,6 @@ public:
VARIANT_ENUM_CAST(MultiMesh::TransformFormat);
VARIANT_ENUM_CAST(MultiMesh::ColorFormat);
+VARIANT_ENUM_CAST(MultiMesh::CustomDataFormat);
#endif // MULTI_MESH_H
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 811e5c3d2c..dba3e4d71b 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -1606,7 +1606,7 @@ void GradientTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("_update"), &GradientTexture::_update);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "gradient", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_gradient", "get_gradient");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "width"), "set_width", "get_width");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "width", PROPERTY_HINT_RANGE, "1,2048,1,or_greater"), "set_width", "get_width");
}
void GradientTexture::set_gradient(Ref<Gradient> p_gradient) {