summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/3d/skeleton.cpp5
-rw-r--r--scene/gui/tree.cpp30
-rw-r--r--scene/register_scene_types.cpp2
-rw-r--r--scene/resources/surface_tool.cpp50
-rw-r--r--scene/resources/surface_tool.h8
-rw-r--r--scene/resources/visual_shader.cpp2
-rw-r--r--scene/resources/visual_shader_nodes.cpp137
-rw-r--r--scene/resources/visual_shader_nodes.h44
8 files changed, 257 insertions, 21 deletions
diff --git a/scene/3d/skeleton.cpp b/scene/3d/skeleton.cpp
index b7279e4d4f..dafcf95b1f 100644
--- a/scene/3d/skeleton.cpp
+++ b/scene/3d/skeleton.cpp
@@ -540,10 +540,11 @@ void Skeleton::clear_bones() {
void Skeleton::set_bone_pose(int p_bone, const Transform &p_pose) {
ERR_FAIL_INDEX(p_bone, bones.size());
- ERR_FAIL_COND(!is_inside_tree());
bones.write[p_bone].pose = p_pose;
- _make_dirty();
+ if (is_inside_tree()) {
+ _make_dirty();
+ }
}
Transform Skeleton::get_bone_pose(int p_bone) const {
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index 92f7d6b588..7e59606d2b 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -2850,7 +2850,7 @@ void Tree::_notification(int p_what) {
if (p_what == NOTIFICATION_DRAG_BEGIN) {
single_select_defer = NULL;
- if (cache.scroll_speed > 0 && get_rect().has_point(get_viewport()->get_mouse_position() - get_global_position())) {
+ if (cache.scroll_speed > 0) {
scrolling = true;
set_physics_process_internal(true);
}
@@ -2897,22 +2897,22 @@ void Tree::_notification(int p_what) {
}
}
- if (scrolling) {
- Point2 point = get_viewport()->get_mouse_position() - get_global_position();
- if (point.x < cache.scroll_border) {
- point.x -= cache.scroll_border;
- } else if (point.x > get_size().width - cache.scroll_border) {
- point.x -= get_size().width - cache.scroll_border;
- } else {
- point.x = 0;
+ Point2 mouse_position = get_viewport()->get_mouse_position() - get_global_position();
+ if (scrolling && get_rect().grow(cache.scroll_border).has_point(mouse_position)) {
+ Point2 point;
+
+ if ((ABS(mouse_position.x) < ABS(mouse_position.x - get_size().width)) && (ABS(mouse_position.x) < cache.scroll_border)) {
+ point.x = mouse_position.x - cache.scroll_border;
+ } else if (ABS(mouse_position.x - get_size().width) < cache.scroll_border) {
+ point.x = mouse_position.x - (get_size().width - cache.scroll_border);
}
- if (point.y < cache.scroll_border) {
- point.y -= cache.scroll_border;
- } else if (point.y > get_size().height - cache.scroll_border) {
- point.y -= get_size().height - cache.scroll_border;
- } else {
- point.y = 0;
+
+ if ((ABS(mouse_position.y) < ABS(mouse_position.y - get_size().height)) && (ABS(mouse_position.y) < cache.scroll_border)) {
+ point.y = mouse_position.y - cache.scroll_border;
+ } else if (ABS(mouse_position.y - get_size().height) < cache.scroll_border) {
+ point.y = mouse_position.y - (get_size().height - cache.scroll_border);
}
+
point *= cache.scroll_speed * get_physics_process_delta_time();
point += get_scroll();
h_scroll->set_value(point.x);
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 87a15bbeda..3148df15dd 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -521,6 +521,8 @@ void register_scene_types() {
ClassDB::register_class<VisualShaderNodeTransformUniform>();
ClassDB::register_class<VisualShaderNodeTextureUniform>();
ClassDB::register_class<VisualShaderNodeCubeMapUniform>();
+ ClassDB::register_class<VisualShaderNodeIf>();
+ ClassDB::register_class<VisualShaderNodeSwitch>();
ClassDB::register_class<ShaderMaterial>();
ClassDB::register_virtual_class<CanvasItem>();
diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp
index c0abee2030..3ba43006a3 100644
--- a/scene/resources/surface_tool.cpp
+++ b/scene/resources/surface_tool.cpp
@@ -108,8 +108,55 @@ void SurfaceTool::add_vertex(const Vector3 &p_vertex) {
vtx.bones = last_bones;
vtx.tangent = last_tangent.normal;
vtx.binormal = last_normal.cross(last_tangent.normal).normalized() * last_tangent.d;
+
+ const int expected_vertices = 4;
+
+ if ((format & Mesh::ARRAY_FORMAT_WEIGHTS || format & Mesh::ARRAY_FORMAT_BONES) && (vtx.weights.size() != expected_vertices || vtx.bones.size() != expected_vertices)) {
+ //ensure vertices are the expected amount
+ ERR_FAIL_COND(vtx.weights.size() != vtx.bones.size());
+ if (vtx.weights.size() < expected_vertices) {
+ //less than requred, fill
+ for (int i = vtx.weights.size(); i < expected_vertices; i++) {
+ vtx.weights.push_back(0);
+ vtx.bones.push_back(0);
+ }
+ } else if (vtx.weights.size() > expected_vertices) {
+ //more than required, sort, cap and normalize.
+ Vector<WeightSort> weights;
+ for (int i = 0; i < vtx.weights.size(); i++) {
+ WeightSort ws;
+ ws.index = vtx.bones[i];
+ ws.weight = vtx.weights[i];
+ weights.push_back(ws);
+ }
+
+ //sort
+ weights.sort();
+ //cap
+ weights.resize(expected_vertices);
+ //renormalize
+ float total = 0;
+ for (int i = 0; i < expected_vertices; i++) {
+ total += weights[i].weight;
+ }
+
+ vtx.weights.resize(expected_vertices);
+ vtx.bones.resize(expected_vertices);
+
+ for (int i = 0; i < expected_vertices; i++) {
+ if (total > 0) {
+ vtx.weights.write[i] = weights[i].weight / total;
+ } else {
+ vtx.weights.write[i] = 0;
+ }
+ vtx.bones.write[i] = weights[i].index;
+ }
+ }
+ }
+
vertex_array.push_back(vtx);
first = false;
+
format |= Mesh::ARRAY_FORMAT_VERTEX;
}
void SurfaceTool::add_color(Color p_color) {
@@ -161,7 +208,6 @@ void SurfaceTool::add_uv2(const Vector2 &p_uv2) {
void SurfaceTool::add_bones(const Vector<int> &p_bones) {
ERR_FAIL_COND(!begun);
- ERR_FAIL_COND(p_bones.size() != 4);
ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_BONES));
format |= Mesh::ARRAY_FORMAT_BONES;
@@ -171,8 +217,6 @@ void SurfaceTool::add_bones(const Vector<int> &p_bones) {
void SurfaceTool::add_weights(const Vector<float> &p_weights) {
ERR_FAIL_COND(!begun);
-
- ERR_FAIL_COND(p_weights.size() != 4);
ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_WEIGHTS));
format |= Mesh::ARRAY_FORMAT_WEIGHTS;
diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h
index a3b110f0d8..c55cade813 100644
--- a/scene/resources/surface_tool.h
+++ b/scene/resources/surface_tool.h
@@ -62,6 +62,14 @@ private:
static _FORCE_INLINE_ uint32_t hash(const Vertex &p_vtx);
};
+ struct WeightSort {
+ int index;
+ float weight;
+ bool operator<(const WeightSort &p_right) const {
+ return weight < p_right.weight;
+ }
+ };
+
bool begun;
bool first;
Mesh::PrimitiveType primitive;
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index fdb6f2ce09..4229147ba2 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -782,7 +782,7 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
} else if (in_type == VisualShaderNode::PORT_TYPE_VECTOR && out_type == VisualShaderNode::PORT_TYPE_SCALAR) {
inputs[i] = "vec3(" + src_var + ")";
} else if (in_type == VisualShaderNode::PORT_TYPE_BOOLEAN && out_type == VisualShaderNode::PORT_TYPE_VECTOR) {
- inputs[i] = "all(" + src_var + ")";
+ inputs[i] = "all(bvec3(" + src_var + "))";
} else if (in_type == VisualShaderNode::PORT_TYPE_BOOLEAN && out_type == VisualShaderNode::PORT_TYPE_SCALAR) {
inputs[i] = src_var + ">0.0?true:false";
} else if (in_type == VisualShaderNode::PORT_TYPE_SCALAR && out_type == VisualShaderNode::PORT_TYPE_BOOLEAN) {
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp
index dac999bf1d..d02902572c 100644
--- a/scene/resources/visual_shader_nodes.cpp
+++ b/scene/resources/visual_shader_nodes.cpp
@@ -2948,3 +2948,140 @@ String VisualShaderNodeCubeMapUniform::generate_code(Shader::Mode p_mode, Visual
VisualShaderNodeCubeMapUniform::VisualShaderNodeCubeMapUniform() {
}
+
+////////////// If
+
+String VisualShaderNodeIf::get_caption() const {
+ return "If";
+}
+
+int VisualShaderNodeIf::get_input_port_count() const {
+ return 6;
+}
+
+VisualShaderNodeIf::PortType VisualShaderNodeIf::get_input_port_type(int p_port) const {
+ if (p_port == 0 || p_port == 1 || p_port == 2) {
+ return PORT_TYPE_SCALAR;
+ }
+ return PORT_TYPE_VECTOR;
+}
+
+String VisualShaderNodeIf::get_input_port_name(int p_port) const {
+ switch (p_port) {
+ case 0:
+ return "a";
+ case 1:
+ return "b";
+ case 2:
+ return "tolerance";
+ case 3:
+ return "a == b";
+ case 4:
+ return "a > b";
+ case 5:
+ return "a < b";
+ default:
+ return "";
+ }
+}
+
+int VisualShaderNodeIf::get_output_port_count() const {
+ return 1;
+}
+
+VisualShaderNodeIf::PortType VisualShaderNodeIf::get_output_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR;
+}
+
+String VisualShaderNodeIf::get_output_port_name(int p_port) const {
+ return "result";
+}
+
+String VisualShaderNodeIf::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+
+ String code;
+ code += "\tif(abs(" + p_input_vars[0] + "-" + p_input_vars[1] + ")<" + p_input_vars[2] + ")\n"; // abs(a - b) < tolerance eg. a == b
+ code += "\t{\n";
+ code += "\t\t" + p_output_vars[0] + "=" + p_input_vars[3] + ";\n";
+ code += "\t}\n";
+ code += "\telse if(" + p_input_vars[0] + "<" + p_input_vars[1] + ")\n"; // a < b
+ code += "\t{\n";
+ code += "\t\t" + p_output_vars[0] + "=" + p_input_vars[5] + ";\n";
+ code += "\t}\n";
+ code += "\telse\n"; // a > b (or a >= b if abs(a - b) < tolerance is false)
+ code += "\t{\n";
+ code += "\t\t" + p_output_vars[0] + "=" + p_input_vars[4] + ";\n";
+ code += "\t}\n";
+ return code;
+}
+
+VisualShaderNodeIf::VisualShaderNodeIf() {
+ set_input_port_default_value(0, 0.0);
+ set_input_port_default_value(1, 0.0);
+ set_input_port_default_value(2, CMP_EPSILON);
+ set_input_port_default_value(3, Vector3(0.0, 0.0, 0.0));
+ set_input_port_default_value(4, Vector3(0.0, 0.0, 0.0));
+ set_input_port_default_value(5, Vector3(0.0, 0.0, 0.0));
+}
+
+////////////// Switch
+
+String VisualShaderNodeSwitch::get_caption() const {
+ return "Switch";
+}
+
+int VisualShaderNodeSwitch::get_input_port_count() const {
+ return 3;
+}
+
+VisualShaderNodeSwitch::PortType VisualShaderNodeSwitch::get_input_port_type(int p_port) const {
+ if (p_port == 0) {
+ return PORT_TYPE_BOOLEAN;
+ }
+ return PORT_TYPE_VECTOR;
+}
+
+String VisualShaderNodeSwitch::get_input_port_name(int p_port) const {
+ switch (p_port) {
+ case 0:
+ return "value";
+ case 1:
+ return "true";
+ case 2:
+ return "false";
+ default:
+ return "";
+ }
+}
+
+int VisualShaderNodeSwitch::get_output_port_count() const {
+ return 1;
+}
+
+VisualShaderNodeSwitch::PortType VisualShaderNodeSwitch::get_output_port_type(int p_port) const {
+ return PORT_TYPE_VECTOR;
+}
+
+String VisualShaderNodeSwitch::get_output_port_name(int p_port) const {
+ return "result";
+}
+
+String VisualShaderNodeSwitch::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+
+ String code;
+ code += "\tif(" + p_input_vars[0] + ")\n";
+ code += "\t{\n";
+ code += "\t\t" + p_output_vars[0] + "=" + p_input_vars[1] + ";\n";
+ code += "\t}\n";
+ code += "\telse\n";
+ code += "\t{\n";
+ code += "\t\t" + p_output_vars[0] + "=" + p_input_vars[2] + ";\n";
+ code += "\t}\n";
+ return code;
+}
+
+VisualShaderNodeSwitch::VisualShaderNodeSwitch() {
+ set_input_port_default_value(0, false);
+ set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0));
+ set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0));
+}
diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h
index 28ead64fe2..90c479bd48 100644
--- a/scene/resources/visual_shader_nodes.h
+++ b/scene/resources/visual_shader_nodes.h
@@ -1440,4 +1440,48 @@ public:
VisualShaderNodeCubeMapUniform();
};
+///////////////////////////////////////
+/// IF
+///////////////////////////////////////
+
+class VisualShaderNodeIf : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeIf, VisualShaderNode)
+public:
+ virtual String get_caption() const;
+
+ virtual int get_input_port_count() const;
+ virtual PortType get_input_port_type(int p_port) const;
+ virtual String get_input_port_name(int p_port) const;
+
+ virtual int get_output_port_count() const;
+ virtual PortType get_output_port_type(int p_port) const;
+ virtual String get_output_port_name(int p_port) const;
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const;
+
+ VisualShaderNodeIf();
+};
+
+///////////////////////////////////////
+/// SWITCH
+///////////////////////////////////////
+
+class VisualShaderNodeSwitch : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeSwitch, VisualShaderNode)
+public:
+ virtual String get_caption() const;
+
+ virtual int get_input_port_count() const;
+ virtual PortType get_input_port_type(int p_port) const;
+ virtual String get_input_port_name(int p_port) const;
+
+ virtual int get_output_port_count() const;
+ virtual PortType get_output_port_type(int p_port) const;
+ virtual String get_output_port_name(int p_port) const;
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const;
+
+ VisualShaderNodeSwitch();
+};
+
#endif // VISUAL_SHADER_NODES_H