diff options
48 files changed, 1569 insertions, 436 deletions
diff --git a/SConstruct b/SConstruct index 9c1644594f..f2c20ea91e 100644 --- a/SConstruct +++ b/SConstruct @@ -333,18 +333,20 @@ if selected_platform in platform_list: env.Prepend(CCFLAGS=['/std:c++17', '/permissive-']) # Enforce our minimal compiler version requirements - version = methods.get_compiler_version(env) - major = int(version[0]) if version is not None else -1 + cc_version = methods.get_compiler_version(env) or [-1, -1] + cc_version_major = cc_version[0] + cc_version_minor = cc_version[1] + if methods.using_gcc(env): - # GCC 8 has a regression in the support of guaranteed copy elision + # GCC 8 before 8.4 has a regression in the support of guaranteed copy elision # which causes a build failure: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86521 - if major == 8: - print("Detected GCC version 8, which is not supported due to a regression " - "in its C++17 guaranteed copy elision support. Use a newer GCC " - "version, or Clang 6 or later by passing \"use_llvm=yes\" to the " - "SCons command line.") + if cc_version_major == 8 and cc_version_minor < 4: + print("Detected GCC 8 version < 8.4, which is not supported due to a " + "regression in its C++17 guaranteed copy elision support. Use a " + "newer GCC version, or Clang 6 or later by passing \"use_llvm=yes\" " + "to the SCons command line.") sys.exit(255) - elif major < 7: + elif cc_version_major < 7: print("Detected GCC version older than 7, which does not fully support " "C++17. Supported versions are GCC 7, 9 and later. Use a newer GCC " "version, or Clang 6 or later by passing \"use_llvm=yes\" to the " @@ -355,15 +357,15 @@ if selected_platform in platform_list: # in https://en.wikipedia.org/wiki/Xcode#Toolchain_versions if env["platform"] == "osx" or env["platform"] == "iphone": vanilla = methods.is_vanilla_clang(env) - if vanilla and major < 6: + if vanilla and cc_version_major < 6: print("Detected Clang version older than 6, which does not fully support " "C++17. Supported versions are Clang 6 and later.") sys.exit(255) - elif not vanilla and major < 10: + elif not vanilla and cc_version_major < 10: print("Detected Apple Clang version older than 10, which does not fully " "support C++17. Supported versions are Apple Clang 10 and later.") sys.exit(255) - elif major < 6: + elif cc_version_major < 6: print("Detected Clang version older than 6, which does not fully support " "C++17. Supported versions are Clang 6 and later.") sys.exit(255) @@ -391,8 +393,7 @@ if selected_platform in platform_list: all_plus_warnings = ['-Wwrite-strings'] if methods.using_gcc(env): - version = methods.get_compiler_version(env) - if version != None and version[0] >= '7': + if cc_version_major >= 7: shadow_local_warning = ['-Wshadow-local'] if (env["warnings"] == 'extra'): @@ -405,8 +406,7 @@ if selected_platform in platform_list: '-Wstringop-overflow=4', '-Wlogical-op']) # -Wnoexcept was removed temporarily due to GH-36325. env.Append(CXXFLAGS=['-Wplacement-new=1']) - version = methods.get_compiler_version(env) - if version != None and version[0] >= '9': + if cc_version_major >= 9: env.Append(CCFLAGS=['-Wattribute-alias=2']) if methods.using_clang(env): env.Append(CCFLAGS=['-Wimplicit-fallthrough']) diff --git a/core/io/multiplayer_api.cpp b/core/io/multiplayer_api.cpp index 6a0eeea513..2aef0a3274 100644 --- a/core/io/multiplayer_api.cpp +++ b/core/io/multiplayer_api.cpp @@ -34,6 +34,10 @@ #include "scene/main/node.h" #include <stdint.h> +#define NODE_ID_COMPRESSION_SHIFT 3 +#define NAME_ID_COMPRESSION_SHIFT 5 +#define BYTE_ONLY_OR_NO_ARGS_SHIFT 6 + #ifdef DEBUG_ENABLED #include "core/os/os.h" #endif @@ -168,6 +172,16 @@ Ref<NetworkedMultiplayerPeer> MultiplayerAPI::get_network_peer() const { return network_peer; } +// Returns the packet size stripping the node path added when the node is not yet cached. +int get_packet_len(uint32_t p_node_target, int p_packet_len) { + if (p_node_target & 0x80000000) { + int ofs = p_node_target & 0x7FFFFFFF; + return p_packet_len - (p_packet_len - ofs); + } else { + return p_packet_len; + } +} + void MultiplayerAPI::_process_packet(int p_from, const uint8_t *p_packet, int p_packet_len) { ERR_FAIL_COND_MSG(root_node == NULL, "Multiplayer root node was not initialized. If you are using custom multiplayer, remember to set the root node via MultiplayerAPI.set_root_node before using it."); @@ -204,8 +218,8 @@ void MultiplayerAPI::_process_packet(int p_from, const uint8_t *p_packet, int p_ int name_id_offset = 1; ERR_FAIL_COND_MSG(p_packet_len < packet_min_size, "Invalid packet received. Size too small."); // Compute the meta size, which depends on the compression level. - int node_id_compression = (p_packet[0] & 24) >> 3; - int name_id_compression = (p_packet[0] & 32) >> 5; + int node_id_compression = (p_packet[0] & 24) >> NODE_ID_COMPRESSION_SHIFT; + int name_id_compression = (p_packet[0] & 32) >> NAME_ID_COMPRESSION_SHIFT; switch (node_id_compression) { case NETWORK_NODE_ID_COMPRESSION_8: @@ -250,6 +264,7 @@ void MultiplayerAPI::_process_packet(int p_from, const uint8_t *p_packet, int p_ // Unreachable, checked before. CRASH_NOW(); } + Node *node = _process_get_node(p_from, p_packet, node_target, p_packet_len); ERR_FAIL_COND_MSG(node == NULL, "Invalid packet received. Requested node was not found."); @@ -266,13 +281,14 @@ void MultiplayerAPI::_process_packet(int p_from, const uint8_t *p_packet, int p_ CRASH_NOW(); } + const int packet_len = get_packet_len(node_target, p_packet_len); if (packet_type == NETWORK_COMMAND_REMOTE_CALL) { - _process_rpc(node, name_id, p_from, p_packet, p_packet_len, packet_min_size); + _process_rpc(node, name_id, p_from, p_packet, packet_len, packet_min_size); } else { - _process_rset(node, name_id, p_from, p_packet, p_packet_len, packet_min_size); + _process_rset(node, name_id, p_from, p_packet, packet_len, packet_min_size); } } break; @@ -326,7 +342,7 @@ Node *MultiplayerAPI::_process_get_node(int p_from, const uint8_t *p_packet, uin void MultiplayerAPI::_process_rpc(Node *p_node, const uint16_t p_rpc_method_id, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset) { - ERR_FAIL_COND_MSG(p_offset >= p_packet_len, "Invalid packet received. Size too small."); + ERR_FAIL_COND_MSG(p_offset > p_packet_len, "Invalid packet received. Size too small."); // Check that remote can call the RPC on this node. StringName name = p_node->get_node_rpc_method(p_rpc_method_id); @@ -340,14 +356,30 @@ void MultiplayerAPI::_process_rpc(Node *p_node, const uint16_t p_rpc_method_id, bool can_call = _can_call_mode(p_node, rpc_mode, p_from); ERR_FAIL_COND_MSG(!can_call, "RPC '" + String(name) + "' is not allowed on node " + p_node->get_path() + " from: " + itos(p_from) + ". Mode is " + itos((int)rpc_mode) + ", master is " + itos(p_node->get_network_master()) + "."); - int argc = p_packet[p_offset]; + int argc = 0; + bool byte_only = false; + + const bool byte_only_or_no_args = ((p_packet[0] & 64) >> BYTE_ONLY_OR_NO_ARGS_SHIFT) == 1; + if (byte_only_or_no_args) { + if (p_offset < p_packet_len) { + // This packet contains only bytes. + argc = 1; + byte_only = true; + } else { + // This rpc calls a method without parameters. + } + } else { + // Normal variant, takes the argument count from the packet. + ERR_FAIL_COND_MSG(p_offset >= p_packet_len, "Invalid packet received. Size too small."); + argc = p_packet[p_offset]; + p_offset += 1; + } + Vector<Variant> args; Vector<const Variant *> argp; args.resize(argc); argp.resize(argc); - p_offset++; - #ifdef DEBUG_ENABLED if (profiling) { ObjectID id = p_node->get_instance_id(); @@ -356,16 +388,26 @@ void MultiplayerAPI::_process_rpc(Node *p_node, const uint16_t p_rpc_method_id, } #endif - for (int i = 0; i < argc; i++) { + if (byte_only) { + Vector<uint8_t> pure_data; + const int len = p_packet_len - p_offset; + pure_data.resize(len); + memcpy(pure_data.ptrw(), &p_packet[p_offset], len); + args.write[0] = pure_data; + argp.write[0] = &args[0]; + p_offset += len; + } else { + for (int i = 0; i < argc; i++) { - ERR_FAIL_COND_MSG(p_offset >= p_packet_len, "Invalid packet received. Size too small."); + ERR_FAIL_COND_MSG(p_offset >= p_packet_len, "Invalid packet received. Size too small."); - int vlen; - Error err = _decode_and_decompress_variant(args.write[i], &p_packet[p_offset], p_packet_len - p_offset, &vlen); - ERR_FAIL_COND_MSG(err != OK, "Invalid packet received. Unable to decode RPC argument."); + int vlen; + Error err = _decode_and_decompress_variant(args.write[i], &p_packet[p_offset], p_packet_len - p_offset, &vlen); + ERR_FAIL_COND_MSG(err != OK, "Invalid packet received. Unable to decode RPC argument."); - argp.write[i] = &args[i]; - p_offset += vlen; + argp.write[i] = &args[i]; + p_offset += vlen; + } } Callable::CallError ce; @@ -742,10 +784,12 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p // - `NetworkCommands` in the first three bits. // - `NetworkNodeIdCompression` in the next 2 bits. // - `NetworkNameIdCompression` in the next 1 bit. - // - So we still have the last two bits free! + // - `byte_only_or_no_args` in the next 1 bit. + // - So we still have the last bit free! uint8_t command_type = p_set ? NETWORK_COMMAND_REMOTE_SET : NETWORK_COMMAND_REMOTE_CALL; uint8_t node_id_compression = UINT8_MAX; uint8_t name_id_compression = UINT8_MAX; + bool byte_only_or_no_args = false; MAKE_ROOM(1); // The meta is composed along the way, so just set 0 for now. @@ -835,17 +879,28 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p ofs += 2; } - // Call arguments. - MAKE_ROOM(ofs + 1); - packet_cache.write[ofs] = p_argcount; - ofs += 1; - for (int i = 0; i < p_argcount; i++) { - int len(0); - Error err = _encode_and_compress_variant(*p_arg[i], NULL, len); - ERR_FAIL_COND_MSG(err != OK, "Unable to encode RPC argument. THIS IS LIKELY A BUG IN THE ENGINE!"); - MAKE_ROOM(ofs + len); - _encode_and_compress_variant(*p_arg[i], &(packet_cache.write[ofs]), len); - ofs += len; + if (p_argcount == 0) { + byte_only_or_no_args = true; + } else if (p_argcount == 1 && p_arg[0]->get_type() == Variant::PACKED_BYTE_ARRAY) { + byte_only_or_no_args = true; + // Special optimization when only the byte vector is sent. + const Vector<uint8_t> data = *p_arg[0]; + MAKE_ROOM(ofs + data.size()); + copymem(&(packet_cache.write[ofs]), data.ptr(), sizeof(uint8_t) * data.size()); + ofs += data.size(); + } else { + // Arguments + MAKE_ROOM(ofs + 1); + packet_cache.write[ofs] = p_argcount; + ofs += 1; + for (int i = 0; i < p_argcount; i++) { + int len(0); + Error err = _encode_and_compress_variant(*p_arg[i], NULL, len); + ERR_FAIL_COND_MSG(err != OK, "Unable to encode RPC argument. THIS IS LIKELY A BUG IN THE ENGINE!"); + MAKE_ROOM(ofs + len); + _encode_and_compress_variant(*p_arg[i], &(packet_cache.write[ofs]), len); + ofs += len; + } } } @@ -854,7 +909,7 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p ERR_FAIL_COND(name_id_compression > 1); // We can now set the meta - packet_cache.write[0] = command_type + (node_id_compression << 3) + (name_id_compression << 5); + packet_cache.write[0] = command_type + (node_id_compression << NODE_ID_COMPRESSION_SHIFT) + (name_id_compression << NAME_ID_COMPRESSION_SHIFT) + ((byte_only_or_no_args ? 1 : 0) << BYTE_ONLY_OR_NO_ARGS_SHIFT); #ifdef DEBUG_ENABLED if (profiling) { diff --git a/doc/classes/BoxContainer.xml b/doc/classes/BoxContainer.xml index 4b5d4c853a..0d8233e6ff 100644 --- a/doc/classes/BoxContainer.xml +++ b/doc/classes/BoxContainer.xml @@ -4,7 +4,7 @@ Base class for box containers. </brief_description> <description> - Arranges child controls vertically or horizontally, and rearranges the controls automatically when their minimum size changes. + Arranges child [Control] nodes vertically or horizontally, and rearranges them automatically when their minimum size changes. </description> <tutorials> </tutorials> @@ -15,13 +15,13 @@ <argument index="0" name="begin" type="bool"> </argument> <description> - Adds a control to the box as a spacer. If [code]true[/code], [code]begin[/code] will insert the spacer control in front of other children. + Adds a [Control] node to the box as a spacer. If [code]begin[/code] is [code]true[/code], it will insert the [Control] node in front of all other children. </description> </method> </methods> <members> <member name="alignment" type="int" setter="set_alignment" getter="get_alignment" enum="BoxContainer.AlignMode" default="0"> - The alignment of the container's children (must be one of [constant ALIGN_BEGIN], [constant ALIGN_CENTER] or [constant ALIGN_END]). + The alignment of the container's children (must be one of [constant ALIGN_BEGIN], [constant ALIGN_CENTER], or [constant ALIGN_END]). </member> </members> <constants> diff --git a/doc/classes/CanvasItem.xml b/doc/classes/CanvasItem.xml index e6251a1d66..dec7c907a4 100644 --- a/doc/classes/CanvasItem.xml +++ b/doc/classes/CanvasItem.xml @@ -260,7 +260,7 @@ <argument index="9" name="texture_repeat" type="int" enum="CanvasItem.TextureRepeat" default="0"> </argument> <description> - Draws a custom primitive. 1 point for a point, 2 points for a line, 3 points for a triangle and 4 points for a quad. + Draws a custom primitive. 1 point for a point, 2 points for a line, 3 points for a triangle, and 4 points for a quad. </description> </method> <method name="draw_rect"> diff --git a/doc/classes/ColorPicker.xml b/doc/classes/ColorPicker.xml index 0805a87d18..5ab929d911 100644 --- a/doc/classes/ColorPicker.xml +++ b/doc/classes/ColorPicker.xml @@ -4,7 +4,7 @@ Color picker control. </brief_description> <description> - [Control] node displaying a color picker widget. It's useful for selecting a color from an RGB/RGBA colorspace. + Displays a color picker widget. Useful for selecting a color from an RGB/RGBA colorspace. </description> <tutorials> </tutorials> diff --git a/doc/classes/NavigationServer.xml b/doc/classes/NavigationServer.xml index 5eb9f34ead..1f65a6004e 100644 --- a/doc/classes/NavigationServer.xml +++ b/doc/classes/NavigationServer.xml @@ -358,13 +358,15 @@ Control activation of this server. </description> </method> - <method name="step"> + <method name="process"> <return type="void"> </return> <argument index="0" name="delta_time" type="float"> </argument> <description> - Steps the server. This is not threadsafe and must be called in single thread. + Process the collision avoidance agents. + The result of this process is needed by the physics server, so this must be called in the main thread. + Note: This function is not thread safe. </description> </method> </methods> diff --git a/doc/classes/ScrollContainer.xml b/doc/classes/ScrollContainer.xml index 0b113bebe5..9c5634f43a 100644 --- a/doc/classes/ScrollContainer.xml +++ b/doc/classes/ScrollContainer.xml @@ -4,7 +4,9 @@ A helper node for displaying scrollable elements such as lists. </brief_description> <description> - A ScrollContainer node meant to contain a [Control] child. ScrollContainers will automatically create a scrollbar child ([HScrollBar], [VScrollBar], or both) when needed and will only draw the Control within the ScrollContainer area. Scrollbars will automatically be drawn at the right (for vertical) or bottom (for horizontal) and will enable dragging to move the viewable Control (and its children) within the ScrollContainer. Scrollbars will also automatically resize the grabber based on the [member Control.rect_min_size] of the Control relative to the ScrollContainer. Works great with a [Panel] control. You can set [code]EXPAND[/code] on the children's size flags, so they will upscale to the ScrollContainer's size if it's larger (scroll is invisible for the chosen dimension). + A ScrollContainer node meant to contain a [Control] child. + ScrollContainers will automatically create a scrollbar child ([HScrollBar], [VScrollBar], or both) when needed and will only draw the Control within the ScrollContainer area. Scrollbars will automatically be drawn at the right (for vertical) or bottom (for horizontal) and will enable dragging to move the viewable Control (and its children) within the ScrollContainer. Scrollbars will also automatically resize the grabber based on the [member Control.rect_min_size] of the Control relative to the ScrollContainer. + Works great with a [Panel] control. You can set [code]EXPAND[/code] on the children's size flags, so they will upscale to the ScrollContainer's size if it's larger (scroll is invisible for the chosen dimension). </description> <tutorials> </tutorials> diff --git a/doc/classes/VisualShaderNode.xml b/doc/classes/VisualShaderNode.xml index d3227f421e..72ce743656 100644 --- a/doc/classes/VisualShaderNode.xml +++ b/doc/classes/VisualShaderNode.xml @@ -61,19 +61,22 @@ <constant name="PORT_TYPE_SCALAR" value="0" enum="PortType"> Floating-point scalar. Translated to [code]float[/code] type in shader code. </constant> - <constant name="PORT_TYPE_VECTOR" value="1" enum="PortType"> + <constant name="PORT_TYPE_SCALAR_INT" value="1" enum="PortType"> + Integer scalar. Translated to [code]int[/code] type in shader code. + </constant> + <constant name="PORT_TYPE_VECTOR" value="2" enum="PortType"> 3D vector of floating-point values. Translated to [code]vec3[/code] type in shader code. </constant> - <constant name="PORT_TYPE_BOOLEAN" value="2" enum="PortType"> + <constant name="PORT_TYPE_BOOLEAN" value="3" enum="PortType"> Boolean type. Translated to [code]bool[/code] type in shader code. </constant> - <constant name="PORT_TYPE_TRANSFORM" value="3" enum="PortType"> + <constant name="PORT_TYPE_TRANSFORM" value="4" enum="PortType"> Transform type. Translated to [code]mat4[/code] type in shader code. </constant> - <constant name="PORT_TYPE_SAMPLER" value="4" enum="PortType"> + <constant name="PORT_TYPE_SAMPLER" value="5" enum="PortType"> Sampler type. Translated to reference of sampler uniform in shader code. Can only be used for input ports in non-uniform nodes. </constant> - <constant name="PORT_TYPE_MAX" value="5" enum="PortType"> + <constant name="PORT_TYPE_MAX" value="6" enum="PortType"> Represents the size of the [enum PortType] enum. </constant> </constants> diff --git a/doc/classes/VisualShaderNodeCompare.xml b/doc/classes/VisualShaderNodeCompare.xml index f207cba0a5..32f7be3ec3 100644 --- a/doc/classes/VisualShaderNodeCompare.xml +++ b/doc/classes/VisualShaderNodeCompare.xml @@ -50,7 +50,7 @@ Comparison for less than ([code]a < b[/code]). Cannot be used if [member type] set to [constant CTYPE_BOOLEAN] or [constant CTYPE_TRANSFORM]. </constant> <constant name="FUNC_LESS_THAN_EQUAL" value="5" enum="Function"> - Comparison for less than or equal ([code]a < b[/code]). Cannot be used if [member type] set to [constant CTYPE_BOOLEAN] or [constant CTYPE_TRANSFORM]. + Comparison for less than or equal ([code]a <= b[/code]). Cannot be used if [member type] set to [constant CTYPE_BOOLEAN] or [constant CTYPE_TRANSFORM]. </constant> <constant name="COND_ALL" value="0" enum="Condition"> The result will be true if all of component in vector satisfy the comparison condition. diff --git a/doc/classes/VisualShaderNodeScalarConstant.xml b/doc/classes/VisualShaderNodeFloatConstant.xml index f7b94d9e39..3ba9ff07d3 100644 --- a/doc/classes/VisualShaderNodeScalarConstant.xml +++ b/doc/classes/VisualShaderNodeFloatConstant.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeScalarConstant" inherits="VisualShaderNode" version="4.0"> +<class name="VisualShaderNodeFloatConstant" inherits="VisualShaderNode" version="4.0"> <brief_description> + A scalar floating-point constant to be used within the visual shader graph. </brief_description> <description> + Translated to [code]float[/code] in the shader language. </description> <tutorials> </tutorials> @@ -10,6 +12,7 @@ </methods> <members> <member name="constant" type="float" setter="set_constant" getter="get_constant" default="0.0"> + A floating-point constant which represents a state of this node. </member> </members> <constants> diff --git a/doc/classes/VisualShaderNodeFloatFunc.xml b/doc/classes/VisualShaderNodeFloatFunc.xml new file mode 100644 index 0000000000..bb7486e8cf --- /dev/null +++ b/doc/classes/VisualShaderNodeFloatFunc.xml @@ -0,0 +1,116 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeFloatFunc" inherits="VisualShaderNode" version="4.0"> + <brief_description> + A scalar floating-point function to be used within the visual shader graph. + </brief_description> + <description> + Accept a floating-point scalar ([code]x[/code]) to the input port and transform it according to [member function]. + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="function" type="int" setter="set_function" getter="get_function" enum="VisualShaderNodeFloatFunc.Function" default="13"> + A function to be applied to the scalar. See [enum Function] for options. + </member> + </members> + <constants> + <constant name="FUNC_SIN" value="0" enum="Function"> + Returns the sine of the parameter. Translates to [code]sin(x)[/code] in the Godot Shader Language. + </constant> + <constant name="FUNC_COS" value="1" enum="Function"> + Returns the cosine of the parameter. Translates to [code]cos(x)[/code] in the Godot Shader Language. + </constant> + <constant name="FUNC_TAN" value="2" enum="Function"> + Returns the tangent of the parameter. Translates to [code]tan(x)[/code] in the Godot Shader Language. + </constant> + <constant name="FUNC_ASIN" value="3" enum="Function"> + Returns the arc-sine of the parameter. Translates to [code]asin(x)[/code] in the Godot Shader Language. + </constant> + <constant name="FUNC_ACOS" value="4" enum="Function"> + Returns the arc-cosine of the parameter. Translates to [code]acos(x)[/code] in the Godot Shader Language. + </constant> + <constant name="FUNC_ATAN" value="5" enum="Function"> + Returns the arc-tangent of the parameter. Translates to [code]atan(x)[/code] in the Godot Shader Language. + </constant> + <constant name="FUNC_SINH" value="6" enum="Function"> + Returns the hyperbolic sine of the parameter. Translates to [code]sinh(x)[/code] in the Godot Shader Language. + </constant> + <constant name="FUNC_COSH" value="7" enum="Function"> + Returns the hyperbolic cosine of the parameter. Translates to [code]cosh(x)[/code] in the Godot Shader Language. + </constant> + <constant name="FUNC_TANH" value="8" enum="Function"> + Returns the hyperbolic tangent of the parameter. Translates to [code]tanh(x)[/code] in the Godot Shader Language. + </constant> + <constant name="FUNC_LOG" value="9" enum="Function"> + Returns the natural logarithm of the parameter. Translates to [code]log(x)[/code] in the Godot Shader Language. + </constant> + <constant name="FUNC_EXP" value="10" enum="Function"> + Returns the natural exponentiation of the parameter. Translates to [code]exp(x)[/code] in the Godot Shader Language. + </constant> + <constant name="FUNC_SQRT" value="11" enum="Function"> + Returns the square root of the parameter. Translates to [code]sqrt(x)[/code] in the Godot Shader Language. + </constant> + <constant name="FUNC_ABS" value="12" enum="Function"> + Returns the absolute value of the parameter. Translates to [code]abs(x)[/code] in the Godot Shader Language. + </constant> + <constant name="FUNC_SIGN" value="13" enum="Function"> + Extracts the sign of the parameter. Translates to [code]sign(x)[/code] in the Godot Shader Language. + </constant> + <constant name="FUNC_FLOOR" value="14" enum="Function"> + Finds the nearest integer less than or equal to the parameter. Translates to [code]floor(x)[/code] in the Godot Shader Language. + </constant> + <constant name="FUNC_ROUND" value="15" enum="Function"> + Finds the nearest integer to the parameter. Translates to [code]round(x)[/code] in the Godot Shader Language. + </constant> + <constant name="FUNC_CEIL" value="16" enum="Function"> + Finds the nearest integer that is greater than or equal to the parameter. Translates to [code]ceil(x)[/code] in the Godot Shader Language. + </constant> + <constant name="FUNC_FRAC" value="17" enum="Function"> + Computes the fractional part of the argument. Translates to [code]fract(x)[/code] in the Godot Shader Language. + </constant> + <constant name="FUNC_SATURATE" value="18" enum="Function"> + Clamps the value between [code]0.0[/code] and [code]1.0[/code] using [code]min(max(x, 0.0), 1.0)[/code]. + </constant> + <constant name="FUNC_NEGATE" value="19" enum="Function"> + Negates the [code]x[/code] using [code]-(x)[/code]. + </constant> + <constant name="FUNC_ACOSH" value="20" enum="Function"> + Returns the arc-hyperbolic-cosine of the parameter. Translates to [code]acosh(x)[/code] in the Godot Shader Language. + </constant> + <constant name="FUNC_ASINH" value="21" enum="Function"> + Returns the arc-hyperbolic-sine of the parameter. Translates to [code]asinh(x)[/code] in the Godot Shader Language. + </constant> + <constant name="FUNC_ATANH" value="22" enum="Function"> + Returns the arc-hyperbolic-tangent of the parameter. Translates to [code]atanh(x)[/code] in the Godot Shader Language. + </constant> + <constant name="FUNC_DEGREES" value="23" enum="Function"> + Convert a quantity in radians to degrees. Translates to [code]degrees(x)[/code] in the Godot Shader Language. + </constant> + <constant name="FUNC_EXP2" value="24" enum="Function"> + Returns 2 raised by the power of the parameter. Translates to [code]exp2(x)[/code] in the Godot Shader Language. + </constant> + <constant name="FUNC_INVERSE_SQRT" value="25" enum="Function"> + Returns the inverse of the square root of the parameter. Translates to [code]inversesqrt(x)[/code] in the Godot Shader Language. + </constant> + <constant name="FUNC_LOG2" value="26" enum="Function"> + Returns the base 2 logarithm of the parameter. Translates to [code]log2(x)[/code] in the Godot Shader Language. + </constant> + <constant name="FUNC_RADIANS" value="27" enum="Function"> + Convert a quantity in degrees to radians. Translates to [code]radians(x)[/code] in the Godot Shader Language. + </constant> + <constant name="FUNC_RECIPROCAL" value="28" enum="Function"> + Finds reciprocal value of dividing 1 by [code]x[/code] (i.e. [code]1 / x[/code]). + </constant> + <constant name="FUNC_ROUNDEVEN" value="29" enum="Function"> + Finds the nearest even integer to the parameter. Translates to [code]roundEven(x)[/code] in the Godot Shader Language. + </constant> + <constant name="FUNC_TRUNC" value="30" enum="Function"> + Returns a value equal to the nearest integer to [code]x[/code] whose absolute value is not larger than the absolute value of [code]x[/code]. Translates to [code]trunc(x)[/code] in the Godot Shader Language. + </constant> + <constant name="FUNC_ONEMINUS" value="31" enum="Function"> + Subtracts scalar [code]x[/code] from 1 (i.e. [code]1 - x[/code]). + </constant> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeFloatOp.xml b/doc/classes/VisualShaderNodeFloatOp.xml new file mode 100644 index 0000000000..2c9ebabb89 --- /dev/null +++ b/doc/classes/VisualShaderNodeFloatOp.xml @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeFloatOp" inherits="VisualShaderNode" version="4.0"> + <brief_description> + A floating-point scalar operator to be used within the visual shader graph. + </brief_description> + <description> + Applies [member operator] to two floating-point inputs: [code]a[/code] and [code]b[/code]. + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="operator" type="int" setter="set_operator" getter="get_operator" enum="VisualShaderNodeFloatOp.Operator" default="0"> + An operator to be applied to the inputs. See [enum Operator] for options. + </member> + </members> + <constants> + <constant name="OP_ADD" value="0" enum="Operator"> + Sums two numbers using [code]a + b[/code]. + </constant> + <constant name="OP_SUB" value="1" enum="Operator"> + Subtracts two numbers using [code]a - b[/code]. + </constant> + <constant name="OP_MUL" value="2" enum="Operator"> + Multiplies two numbers using [code]a * b[/code]. + </constant> + <constant name="OP_DIV" value="3" enum="Operator"> + Divides two numbers using [code]a / b[/code]. + </constant> + <constant name="OP_MOD" value="4" enum="Operator"> + Calculates the remainder of two numbers. Translates to [code]mod(a, b)[/code] in the Godot Shader Language. + </constant> + <constant name="OP_POW" value="5" enum="Operator"> + Raises the [code]a[/code] to the power of [code]b[/code]. Translates to [code]pow(a, b)[/code] in the Godot Shader Language. + </constant> + <constant name="OP_MAX" value="6" enum="Operator"> + Returns the greater of two numbers. Translates to [code]max(a, b)[/code] in the Godot Shader Language. + </constant> + <constant name="OP_MIN" value="7" enum="Operator"> + Returns the lesser of two numbers. Translates to [code]min(a, b)[/code] in the Godot Shader Language. + </constant> + <constant name="OP_ATAN2" value="8" enum="Operator"> + Returns the arc-tangent of the parameters. Translates to [code]atan(a, b)[/code] in the Godot Shader Language. + </constant> + <constant name="OP_STEP" value="9" enum="Operator"> + Generates a step function by comparing [code]b[/code](x) to [code]a[/code](edge). Returns 0.0 if [code]x[/code] is smaller than [code]edge[/code] and otherwise 1.0. Translates to [code]step(a, b)[/code] in the Godot Shader Language. + </constant> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeScalarUniform.xml b/doc/classes/VisualShaderNodeFloatUniform.xml index fab766d3f9..33ece8ac1b 100644 --- a/doc/classes/VisualShaderNodeScalarUniform.xml +++ b/doc/classes/VisualShaderNodeFloatUniform.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeScalarUniform" inherits="VisualShaderNodeUniform" version="4.0"> +<class name="VisualShaderNodeFloatUniform" inherits="VisualShaderNodeUniform" version="4.0"> <brief_description> - A scalar uniform to be used within the visual shader graph. + A scalar float uniform to be used within the visual shader graph. </brief_description> <description> Translated to [code]uniform float[/code] in the shader language. @@ -11,7 +11,7 @@ <methods> </methods> <members> - <member name="hint" type="int" setter="set_hint" getter="get_hint" enum="VisualShaderNodeScalarUniform.Hint" default="0"> + <member name="hint" type="int" setter="set_hint" getter="get_hint" enum="VisualShaderNodeFloatUniform.Hint" default="0"> A hint applied to the uniform, which controls the values it can take when set through the inspector. </member> <member name="max" type="float" setter="set_max" getter="get_max" default="1.0"> diff --git a/doc/classes/VisualShaderNodeIf.xml b/doc/classes/VisualShaderNodeIf.xml index 0a8fdcfd4d..1ebd945d42 100644 --- a/doc/classes/VisualShaderNodeIf.xml +++ b/doc/classes/VisualShaderNodeIf.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisualShaderNodeIf" inherits="VisualShaderNode" version="4.0"> <brief_description> + Compares two floating-point numbers in order to return a required vector within the visual shader graph. </brief_description> <description> + First two ports are scalar floatin-point numbers to compare, third is tolerance comparsion amount and last three ports represents a vectors returned if [code]a == b[/code], [code]a > b[/code] and [code]a < b[/code] respectivly. </description> <tutorials> </tutorials> diff --git a/doc/classes/VisualShaderNodeInput.xml b/doc/classes/VisualShaderNodeInput.xml index 1c8d8d84c4..ed629508d0 100644 --- a/doc/classes/VisualShaderNodeInput.xml +++ b/doc/classes/VisualShaderNodeInput.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="VisualShaderNodeInput" inherits="VisualShaderNode" version="4.0"> <brief_description> + Represents the input shader parameter within the visual shader graph. </brief_description> <description> </description> @@ -11,16 +12,19 @@ <return type="String"> </return> <description> + Returns a translated name of the current constant in the Godot Shader Language. eg. [code]"ALBEDO"[/code] if the [member input_name] equal to [code]"albedo"[/code]. </description> </method> </methods> <members> <member name="input_name" type="String" setter="set_input_name" getter="get_input_name" default=""[None]""> + One of the several input constants in lower-case style like: "vertex"([/code]VERTEX[code]) or "point_size"([code]POINT_SIZE[/code]). </member> </members> <signals> <signal name="input_type_changed"> <description> + Emitted when input is changed via [member input_name]. </description> </signal> </signals> diff --git a/doc/classes/VisualShaderNodeIntConstant.xml b/doc/classes/VisualShaderNodeIntConstant.xml new file mode 100644 index 0000000000..1c407b21ca --- /dev/null +++ b/doc/classes/VisualShaderNodeIntConstant.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeIntConstant" inherits="VisualShaderNode" version="4.0"> + <brief_description> + A scalar integer constant to be used within the visual shader graph. + </brief_description> + <description> + Translated to [code]int[/code] in the shader language. + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="constant" type="int" setter="set_constant" getter="get_constant" default="0"> + An integer constant which represents a state of this node. + </member> + </members> + <constants> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeIntFunc.xml b/doc/classes/VisualShaderNodeIntFunc.xml new file mode 100644 index 0000000000..4b5d4ca8d2 --- /dev/null +++ b/doc/classes/VisualShaderNodeIntFunc.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeIntFunc" inherits="VisualShaderNode" version="4.0"> + <brief_description> + A scalar integer function to be used within the visual shader graph. + </brief_description> + <description> + Accept an integer scalar ([code]x[/code]) to the input port and transform it according to [member function]. + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="function" type="int" setter="set_function" getter="get_function" enum="VisualShaderNodeIntFunc.Function" default="0"> + A function to be applied to the scalar. See [enum Function] for options. + </member> + </members> + <constants> + <constant name="FUNC_ABS" value="0" enum="Function"> + Returns the absolute value of the parameter. Translates to [code]abs(x)[/code] in the Godot Shader Language. + </constant> + <constant name="FUNC_CLAMP" value="1" enum="Function"> + Constrains a parameter between [code]min[/code] and [code]max[/code]. Translates to [code]clamp(x, min, max)[/code] in the Godot Shader Language. + </constant> + <constant name="FUNC_NEGATE" value="2" enum="Function"> + Negates the [code]x[/code] using [code]-(x)[/code]. + </constant> + <constant name="FUNC_SIGN" value="3" enum="Function"> + Extracts the sign of the parameter. Translates to [code]sign(x)[/code] in the Godot Shader Language. + </constant> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeIntOp.xml b/doc/classes/VisualShaderNodeIntOp.xml new file mode 100644 index 0000000000..fc9a0a9a0a --- /dev/null +++ b/doc/classes/VisualShaderNodeIntOp.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeIntOp" inherits="VisualShaderNode" version="4.0"> + <brief_description> + An integer scalar operator to be used within the visual shader graph. + </brief_description> + <description> + Applies [member operator] to two integer inputs: [code]a[/code] and [code]b[/code]. + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="operator" type="int" setter="set_operator" getter="get_operator" enum="VisualShaderNodeIntOp.Operator" default="0"> + An operator to be applied to the inputs. See [enum Operator] for options. + </member> + </members> + <constants> + <constant name="OP_ADD" value="0" enum="Operator"> + Sums two numbers using [code]a + b[/code]. + </constant> + <constant name="OP_SUB" value="1" enum="Operator"> + Subtracts two numbers using [code]a - b[/code]. + </constant> + <constant name="OP_MUL" value="2" enum="Operator"> + Multiplies two numbers using [code]a * b[/code]. + </constant> + <constant name="OP_DIV" value="3" enum="Operator"> + Divides two numbers using [code]a / b[/code]. + </constant> + <constant name="OP_MOD" value="4" enum="Operator"> + Calculates the remainder of two numbers using [code]a % b[/code]. + </constant> + <constant name="OP_MAX" value="5" enum="Operator"> + Returns the greater of two numbers. Translates to [code]max(a, b)[/code] in the Godot Shader Language. + </constant> + <constant name="OP_MIN" value="6" enum="Operator"> + Returns the lesser of two numbers. Translates to [code]max(a, b)[/code] in the Godot Shader Language. + </constant> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeIntUniform.xml b/doc/classes/VisualShaderNodeIntUniform.xml new file mode 100644 index 0000000000..8c7c288177 --- /dev/null +++ b/doc/classes/VisualShaderNodeIntUniform.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeIntUniform" inherits="VisualShaderNodeUniform" version="4.0"> + <brief_description> + A scalar integer uniform to be used within the visual shader graph. + </brief_description> + <description> + Translated to [code]uniform int[/code] in the shader language. + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="hint" type="int" setter="set_hint" getter="get_hint" enum="VisualShaderNodeIntUniform.Hint" default="0"> + A hint applied to the uniform, which controls the values it can take when set through the inspector. + </member> + <member name="max" type="int" setter="set_max" getter="get_max" default="100"> + Minimum value for range hints. Used if [member hint] is set to [constant HINT_RANGE] or [constant HINT_RANGE_STEP]. + </member> + <member name="min" type="int" setter="set_min" getter="get_min" default="0"> + Maximum value for range hints. Used if [member hint] is set to [constant HINT_RANGE] or [constant HINT_RANGE_STEP]. + </member> + <member name="step" type="int" setter="set_step" getter="get_step" default="1"> + Step (increment) value for the range hint with step. Used if [member hint] is set to [constant HINT_RANGE_STEP]. + </member> + </members> + <constants> + <constant name="HINT_NONE" value="0" enum="Hint"> + No hint used. + </constant> + <constant name="HINT_RANGE" value="1" enum="Hint"> + A range hint for scalar value, which limits possible input values between [member min] and [member max]. Translated to [code]hint_range(min, max)[/code] in shader code. + </constant> + <constant name="HINT_RANGE_STEP" value="2" enum="Hint"> + A range hint for scalar value with step, which limits possible input values between [member min] and [member max], with a step (increment) of [member step]). Translated to [code]hint_range(min, max, step)[/code] in shader code. + </constant> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeScalarFunc.xml b/doc/classes/VisualShaderNodeScalarFunc.xml deleted file mode 100644 index b306d198f6..0000000000 --- a/doc/classes/VisualShaderNodeScalarFunc.xml +++ /dev/null @@ -1,81 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeScalarFunc" inherits="VisualShaderNode" version="4.0"> - <brief_description> - </brief_description> - <description> - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <members> - <member name="function" type="int" setter="set_function" getter="get_function" enum="VisualShaderNodeScalarFunc.Function" default="13"> - </member> - </members> - <constants> - <constant name="FUNC_SIN" value="0" enum="Function"> - </constant> - <constant name="FUNC_COS" value="1" enum="Function"> - </constant> - <constant name="FUNC_TAN" value="2" enum="Function"> - </constant> - <constant name="FUNC_ASIN" value="3" enum="Function"> - </constant> - <constant name="FUNC_ACOS" value="4" enum="Function"> - </constant> - <constant name="FUNC_ATAN" value="5" enum="Function"> - </constant> - <constant name="FUNC_SINH" value="6" enum="Function"> - </constant> - <constant name="FUNC_COSH" value="7" enum="Function"> - </constant> - <constant name="FUNC_TANH" value="8" enum="Function"> - </constant> - <constant name="FUNC_LOG" value="9" enum="Function"> - </constant> - <constant name="FUNC_EXP" value="10" enum="Function"> - </constant> - <constant name="FUNC_SQRT" value="11" enum="Function"> - </constant> - <constant name="FUNC_ABS" value="12" enum="Function"> - </constant> - <constant name="FUNC_SIGN" value="13" enum="Function"> - </constant> - <constant name="FUNC_FLOOR" value="14" enum="Function"> - </constant> - <constant name="FUNC_ROUND" value="15" enum="Function"> - </constant> - <constant name="FUNC_CEIL" value="16" enum="Function"> - </constant> - <constant name="FUNC_FRAC" value="17" enum="Function"> - </constant> - <constant name="FUNC_SATURATE" value="18" enum="Function"> - </constant> - <constant name="FUNC_NEGATE" value="19" enum="Function"> - </constant> - <constant name="FUNC_ACOSH" value="20" enum="Function"> - </constant> - <constant name="FUNC_ASINH" value="21" enum="Function"> - </constant> - <constant name="FUNC_ATANH" value="22" enum="Function"> - </constant> - <constant name="FUNC_DEGREES" value="23" enum="Function"> - </constant> - <constant name="FUNC_EXP2" value="24" enum="Function"> - </constant> - <constant name="FUNC_INVERSE_SQRT" value="25" enum="Function"> - </constant> - <constant name="FUNC_LOG2" value="26" enum="Function"> - </constant> - <constant name="FUNC_RADIANS" value="27" enum="Function"> - </constant> - <constant name="FUNC_RECIPROCAL" value="28" enum="Function"> - </constant> - <constant name="FUNC_ROUNDEVEN" value="29" enum="Function"> - </constant> - <constant name="FUNC_TRUNC" value="30" enum="Function"> - </constant> - <constant name="FUNC_ONEMINUS" value="31" enum="Function"> - </constant> - </constants> -</class> diff --git a/doc/classes/VisualShaderNodeScalarOp.xml b/doc/classes/VisualShaderNodeScalarOp.xml deleted file mode 100644 index f13f16cdd2..0000000000 --- a/doc/classes/VisualShaderNodeScalarOp.xml +++ /dev/null @@ -1,37 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualShaderNodeScalarOp" inherits="VisualShaderNode" version="4.0"> - <brief_description> - </brief_description> - <description> - </description> - <tutorials> - </tutorials> - <methods> - </methods> - <members> - <member name="operator" type="int" setter="set_operator" getter="get_operator" enum="VisualShaderNodeScalarOp.Operator" default="0"> - </member> - </members> - <constants> - <constant name="OP_ADD" value="0" enum="Operator"> - </constant> - <constant name="OP_SUB" value="1" enum="Operator"> - </constant> - <constant name="OP_MUL" value="2" enum="Operator"> - </constant> - <constant name="OP_DIV" value="3" enum="Operator"> - </constant> - <constant name="OP_MOD" value="4" enum="Operator"> - </constant> - <constant name="OP_POW" value="5" enum="Operator"> - </constant> - <constant name="OP_MAX" value="6" enum="Operator"> - </constant> - <constant name="OP_MIN" value="7" enum="Operator"> - </constant> - <constant name="OP_ATAN2" value="8" enum="Operator"> - </constant> - <constant name="OP_STEP" value="9" enum="Operator"> - </constant> - </constants> -</class> diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 9742cadfd3..8758fbcfc9 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -2480,6 +2480,9 @@ void AnimationTrackEdit::_path_entered(const String &p_text) { bool AnimationTrackEdit::_is_value_key_valid(const Variant &p_key_value, Variant::Type &r_valid_type) const { + if (root == nullptr) + return false; + RES res; Vector<StringName> leftover_path; Node *node = root->get_node_and_resource(animation->track_get_path(track), res, leftover_path); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index b632e7594c..9cc6134f27 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -6147,7 +6147,7 @@ EditorNode::EditorNode() { ED_SHORTCUT("editor/next_tab", TTR("Next tab"), KEY_MASK_CMD + KEY_TAB); ED_SHORTCUT("editor/prev_tab", TTR("Previous tab"), KEY_MASK_CMD + KEY_MASK_SHIFT + KEY_TAB); - ED_SHORTCUT("editor/filter_files", TTR("Filter Files..."), KEY_MASK_ALT + KEY_MASK_CMD + KEY_P); + ED_SHORTCUT("editor/filter_files", TTR("Filter Files..."), KEY_MASK_CMD + KEY_MASK_ALT + KEY_P); PopupMenu *p; file_menu->set_tooltip(TTR("Operations with scene files.")); @@ -6162,13 +6162,14 @@ EditorNode::EditorNode() { p->add_separator(); p->add_shortcut(ED_SHORTCUT("editor/save_scene", TTR("Save Scene"), KEY_MASK_CMD + KEY_S), FILE_SAVE_SCENE); - p->add_shortcut(ED_SHORTCUT("editor/save_scene_as", TTR("Save Scene As..."), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_S), FILE_SAVE_AS_SCENE); - p->add_shortcut(ED_SHORTCUT("editor/save_all_scenes", TTR("Save All Scenes"), KEY_MASK_ALT + KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_S), FILE_SAVE_ALL_SCENES); + p->add_shortcut(ED_SHORTCUT("editor/save_scene_as", TTR("Save Scene As..."), KEY_MASK_CMD + KEY_MASK_SHIFT + KEY_S), FILE_SAVE_AS_SCENE); + p->add_shortcut(ED_SHORTCUT("editor/save_all_scenes", TTR("Save All Scenes"), KEY_MASK_CMD + KEY_MASK_SHIFT + KEY_MASK_ALT + KEY_S), FILE_SAVE_ALL_SCENES); p->add_separator(); + p->add_shortcut(ED_SHORTCUT("editor/quick_open", TTR("Quick Open..."), KEY_MASK_SHIFT + KEY_MASK_ALT + KEY_O), FILE_QUICK_OPEN); - p->add_shortcut(ED_SHORTCUT("editor/quick_open_scene", TTR("Quick Open Scene..."), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_O), FILE_QUICK_OPEN_SCENE); - p->add_shortcut(ED_SHORTCUT("editor/quick_open_script", TTR("Quick Open Script..."), KEY_MASK_ALT + KEY_MASK_CMD + KEY_O), FILE_QUICK_OPEN_SCRIPT); + p->add_shortcut(ED_SHORTCUT("editor/quick_open_scene", TTR("Quick Open Scene..."), KEY_MASK_CMD + KEY_MASK_SHIFT + KEY_O), FILE_QUICK_OPEN_SCENE); + p->add_shortcut(ED_SHORTCUT("editor/quick_open_script", TTR("Quick Open Script..."), KEY_MASK_CMD + KEY_MASK_ALT + KEY_O), FILE_QUICK_OPEN_SCRIPT); p->add_separator(); PopupMenu *pm_export = memnew(PopupMenu); @@ -6181,11 +6182,11 @@ EditorNode::EditorNode() { p->add_separator(); p->add_shortcut(ED_SHORTCUT("editor/undo", TTR("Undo"), KEY_MASK_CMD + KEY_Z), EDIT_UNDO, true); - p->add_shortcut(ED_SHORTCUT("editor/redo", TTR("Redo"), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_Z), EDIT_REDO, true); + p->add_shortcut(ED_SHORTCUT("editor/redo", TTR("Redo"), KEY_MASK_CMD + KEY_MASK_SHIFT + KEY_Z), EDIT_REDO, true); p->add_separator(); p->add_shortcut(ED_SHORTCUT("editor/revert_scene", TTR("Revert Scene")), EDIT_REVERT); - p->add_shortcut(ED_SHORTCUT("editor/close_scene", TTR("Close Scene"), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_W), FILE_CLOSE); + p->add_shortcut(ED_SHORTCUT("editor/close_scene", TTR("Close Scene"), KEY_MASK_CMD + KEY_MASK_SHIFT + KEY_W), FILE_CLOSE); recent_scenes = memnew(PopupMenu); recent_scenes->set_name("RecentScenes"); @@ -6237,7 +6238,7 @@ EditorNode::EditorNode() { #ifdef OSX_ENABLED p->add_shortcut(ED_SHORTCUT("editor/quit_to_project_list", TTR("Quit to Project List"), KEY_MASK_SHIFT + KEY_MASK_ALT + KEY_Q), RUN_PROJECT_MANAGER, true); #else - p->add_shortcut(ED_SHORTCUT("editor/quit_to_project_list", TTR("Quit to Project List"), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_Q), RUN_PROJECT_MANAGER, true); + p->add_shortcut(ED_SHORTCUT("editor/quit_to_project_list", TTR("Quit to Project List"), KEY_MASK_CMD + KEY_MASK_SHIFT + KEY_Q), RUN_PROJECT_MANAGER, true); #endif menu_hb->add_spacer(); diff --git a/editor/import/resource_importer_texture_atlas.cpp b/editor/import/resource_importer_texture_atlas.cpp index 4291d6f2d7..3172cc7279 100644 --- a/editor/import/resource_importer_texture_atlas.cpp +++ b/editor/import/resource_importer_texture_atlas.cpp @@ -143,8 +143,8 @@ static void _plot_triangle(Vector2 *vertices, const Vector2 &p_offset, bool p_tr int px = xi, py = yi; int sx = px, sy = py; - sx = CLAMP(sx, 0, src_width); - sy = CLAMP(sy, 0, src_height); + sx = CLAMP(sx, 0, src_width - 1); + sy = CLAMP(sy, 0, src_height - 1); Color color = p_src_image->get_pixel(sx, sy); if (p_transposed) { SWAP(px, py); @@ -165,8 +165,8 @@ static void _plot_triangle(Vector2 *vertices, const Vector2 &p_offset, bool p_tr for (int xi = (xf < width ? int(xf) : width - 1); xi >= (xt > 0 ? xt : 0); xi--) { int px = xi, py = yi; int sx = px, sy = py; - sx = CLAMP(sx, 0, src_width); - sy = CLAMP(sy, 0, src_height); + sx = CLAMP(sx, 0, src_width - 1); + sy = CLAMP(sy, 0, src_height - 1); Color color = p_src_image->get_pixel(sx, sy); if (p_transposed) { SWAP(px, py); diff --git a/editor/plugins/mesh_instance_editor_plugin.cpp b/editor/plugins/mesh_instance_editor_plugin.cpp index 182a8600e4..37cf16de58 100644 --- a/editor/plugins/mesh_instance_editor_plugin.cpp +++ b/editor/plugins/mesh_instance_editor_plugin.cpp @@ -455,7 +455,7 @@ MeshInstanceEditor::MeshInstanceEditor() { options->get_popup()->add_separator(); options->get_popup()->add_item(TTR("Create Trimesh Collision Sibling"), MENU_OPTION_CREATE_TRIMESH_COLLISION_SHAPE); options->get_popup()->set_item_tooltip(options->get_popup()->get_item_count() - 1, TTR("Creates a polygon-based collision shape.\nThis is the most accurate (but slowest) option for collision detection.")); - options->get_popup()->add_item(TTR("Create Single Convex Collision Siblings"), MENU_OPTION_CREATE_SINGLE_CONVEX_COLLISION_SHAPE); + options->get_popup()->add_item(TTR("Create Single Convex Collision Sibling"), MENU_OPTION_CREATE_SINGLE_CONVEX_COLLISION_SHAPE); options->get_popup()->set_item_tooltip(options->get_popup()->get_item_count() - 1, TTR("Creates a single convex collision shape.\nThis is the fastest (but least accurate) option for collision detection.")); options->get_popup()->add_item(TTR("Create Multiple Convex Collision Siblings"), MENU_OPTION_CREATE_MULTIPLE_CONVEX_COLLISION_SHAPES); options->get_popup()->set_item_tooltip(options->get_popup()->get_item_count() - 1, TTR("Creates a polygon-based collision shape.\nThis is a performance middle-ground between the two above options.")); diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 568e484cac..2fb23f6a84 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -35,6 +35,7 @@ #include "core/os/input.h" #include "core/os/keyboard.h" #include "core/project_settings.h" +#include "core/version.h" #include "editor/editor_log.h" #include "editor/editor_properties.h" #include "editor/editor_scale.h" @@ -75,6 +76,12 @@ void VisualShaderEditor::edit(VisualShader *p_visual_shader) { if (!visual_shader->is_connected_compat("changed", this, "_update_preview")) { visual_shader->connect_compat("changed", this, "_update_preview"); } +#ifndef DISABLE_DEPRECATED + String version = VERSION_BRANCH; + if (visual_shader->get_version() != version) { + visual_shader->update_version(version); + } +#endif visual_shader->set_graph_offset(graph->get_scroll_ofs() / EDSCALE); } else { if (visual_shader.is_valid()) { @@ -380,6 +387,9 @@ void VisualShaderEditor::_update_options_menu() { case VisualShaderNode::PORT_TYPE_SCALAR: item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("float", "EditorIcons")); break; + case VisualShaderNode::PORT_TYPE_SCALAR_INT: + item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("int", "EditorIcons")); + break; case VisualShaderNode::PORT_TYPE_VECTOR: item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_icon("Vector3", "EditorIcons")); break; @@ -428,14 +438,22 @@ void VisualShaderEditor::_update_created_node(GraphNode *node) { if (EditorSettings::get_singleton()->get("interface/theme/use_graph_node_headers")) { Ref<StyleBoxFlat> sb = node->get_stylebox("frame", "GraphNode"); Color c = sb->get_border_color(); - Color mono_color = ((c.r + c.g + c.b) / 3) < 0.7 ? Color(1.0, 1.0, 1.0) : Color(0.0, 0.0, 0.0); + Color ic; + Color mono_color; + if (((c.r + c.g + c.b) / 3) < 0.7) { + mono_color = Color(1.0, 1.0, 1.0); + ic = Color(0.0, 0.0, 0.0, 0.7); + } else { + mono_color = Color(0.0, 0.0, 0.0); + ic = Color(1.0, 1.0, 1.0, 0.7); + } mono_color.a = 0.85; c = mono_color; node->add_color_override("title_color", c); c.a = 0.7; node->add_color_override("close_color", c); - node->add_color_override("resizer_color", c); + node->add_color_override("resizer_color", ic); } } @@ -462,12 +480,13 @@ void VisualShaderEditor::_update_graph() { } } - static const Color type_color[5] = { - Color(0.38, 0.85, 0.96), // scalar + static const Color type_color[6] = { + Color(0.38, 0.85, 0.96), // scalar (float) + Color(0.49, 0.78, 0.94), // scalar (int) Color(0.84, 0.49, 0.93), // vector Color(0.55, 0.65, 0.94), // boolean Color(0.96, 0.66, 0.43), // transform - Color(1.0, 1.0, 0.0) // sampler + Color(1.0, 1.0, 0.0), // sampler }; List<VisualShader::Connection> connections; @@ -528,7 +547,8 @@ void VisualShaderEditor::_update_graph() { } Ref<VisualShaderNodeUniform> uniform = vsnode; - Ref<VisualShaderNodeScalarUniform> scalar_uniform = vsnode; + Ref<VisualShaderNodeFloatUniform> float_uniform = vsnode; + Ref<VisualShaderNodeIntUniform> int_uniform = vsnode; if (uniform.is_valid()) { graph->add_child(node); _update_created_node(node); @@ -543,7 +563,7 @@ void VisualShaderEditor::_update_graph() { //shortcut VisualShaderNode::PortType port_right = vsnode->get_output_port_type(0); node->set_slot(0, false, VisualShaderNode::PORT_TYPE_SCALAR, Color(), true, port_right, type_color[port_right]); - if (!scalar_uniform.is_valid()) { + if (!float_uniform.is_valid() && !int_uniform.is_valid()) { continue; } } @@ -557,13 +577,13 @@ void VisualShaderEditor::_update_graph() { } } - if (custom_editor && !scalar_uniform.is_valid() && vsnode->get_output_port_count() > 0 && vsnode->get_output_port_name(0) == "" && (vsnode->get_input_port_count() == 0 || vsnode->get_input_port_name(0) == "")) { + if (custom_editor && !float_uniform.is_valid() && !int_uniform.is_valid() && vsnode->get_output_port_count() > 0 && vsnode->get_output_port_name(0) == "" && (vsnode->get_input_port_count() == 0 || vsnode->get_input_port_name(0) == "")) { //will be embedded in first port } else if (custom_editor) { port_offset++; node->add_child(custom_editor); - if (scalar_uniform.is_valid()) { + if (float_uniform.is_valid() || int_uniform.is_valid()) { custom_editor->call_deferred("_show_prop_names", true); continue; } @@ -670,7 +690,8 @@ void VisualShaderEditor::_update_graph() { if (is_group) { OptionButton *type_box = memnew(OptionButton); hb->add_child(type_box); - type_box->add_item(TTR("Scalar")); + type_box->add_item(TTR("Float")); + type_box->add_item(TTR("Int")); type_box->add_item(TTR("Vector")); type_box->add_item(TTR("Boolean")); type_box->add_item(TTR("Transform")); @@ -732,7 +753,8 @@ void VisualShaderEditor::_update_graph() { OptionButton *type_box = memnew(OptionButton); hb->add_child(type_box); - type_box->add_item(TTR("Scalar")); + type_box->add_item(TTR("Float")); + type_box->add_item(TTR("Int")); type_box->add_item(TTR("Vector")); type_box->add_item(TTR("Boolean")); type_box->add_item(TTR("Transform")); @@ -1295,7 +1317,7 @@ VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) { VisualShaderNode *vsn = Object::cast_to<VisualShaderNode>(ClassDB::instance(add_options[p_idx].type)); ERR_FAIL_COND_V(!vsn, NULL); - VisualShaderNodeScalarConstant *constant = Object::cast_to<VisualShaderNodeScalarConstant>(vsn); + VisualShaderNodeFloatConstant *constant = Object::cast_to<VisualShaderNodeFloatConstant>(vsn); if (constant) { if ((int)add_options[p_idx].value != -1) @@ -1334,16 +1356,28 @@ VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) { colorFunc->set_function((VisualShaderNodeColorFunc::Function)p_op_idx); } - VisualShaderNodeScalarOp *scalarOp = Object::cast_to<VisualShaderNodeScalarOp>(vsn); + VisualShaderNodeFloatOp *floatOp = Object::cast_to<VisualShaderNodeFloatOp>(vsn); + + if (floatOp) { + floatOp->set_operator((VisualShaderNodeFloatOp::Operator)p_op_idx); + } + + VisualShaderNodeIntOp *intOp = Object::cast_to<VisualShaderNodeIntOp>(vsn); + + if (intOp) { + intOp->set_operator((VisualShaderNodeIntOp::Operator)p_op_idx); + } + + VisualShaderNodeFloatFunc *floatFunc = Object::cast_to<VisualShaderNodeFloatFunc>(vsn); - if (scalarOp) { - scalarOp->set_operator((VisualShaderNodeScalarOp::Operator)p_op_idx); + if (floatFunc) { + floatFunc->set_function((VisualShaderNodeFloatFunc::Function)p_op_idx); } - VisualShaderNodeScalarFunc *scalarFunc = Object::cast_to<VisualShaderNodeScalarFunc>(vsn); + VisualShaderNodeIntFunc *intFunc = Object::cast_to<VisualShaderNodeIntFunc>(vsn); - if (scalarFunc) { - scalarFunc->set_function((VisualShaderNodeScalarFunc::Function)p_op_idx); + if (intFunc) { + intFunc->set_function((VisualShaderNodeIntFunc::Function)p_op_idx); } VisualShaderNodeVectorOp *vecOp = Object::cast_to<VisualShaderNodeVectorOp>(vsn); @@ -1575,8 +1609,29 @@ void VisualShaderEditor::_graph_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> mb = p_event; - if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_RIGHT) - _show_members_dialog(true); + if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_RIGHT) { + List<int> to_change; + for (int i = 0; i < graph->get_child_count(); i++) { + GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i)); + if (gn) { + if (gn->is_selected() && gn->is_close_button_visible()) { + to_change.push_back(gn->get_name().operator String().to_int()); + } + } + } + if (to_change.empty() && copy_nodes_buffer.empty()) { + _show_members_dialog(true); + } else { + popup_menu->set_item_disabled(NodeMenuOptions::COPY, to_change.empty()); + popup_menu->set_item_disabled(NodeMenuOptions::PASTE, copy_nodes_buffer.empty()); + popup_menu->set_item_disabled(NodeMenuOptions::DELETE, to_change.empty()); + popup_menu->set_item_disabled(NodeMenuOptions::DUPLICATE, to_change.empty()); + menu_point = graph->get_local_mouse_position(); + Point2 gpos = Input::get_singleton()->get_mouse_position(); + popup_menu->set_position(gpos); + popup_menu->popup(); + } + } } void VisualShaderEditor::_show_members_dialog(bool at_mouse_pos) { @@ -1874,7 +1929,7 @@ void VisualShaderEditor::_copy_nodes() { _dup_copy_nodes(copy_type, copy_nodes_buffer, copy_nodes_excluded_buffer); } -void VisualShaderEditor::_paste_nodes() { +void VisualShaderEditor::_paste_nodes(bool p_use_custom_position, const Vector2 &p_custom_position) { if (copy_nodes_buffer.empty()) return; @@ -1885,12 +1940,19 @@ void VisualShaderEditor::_paste_nodes() { float scale = graph->get_zoom(); - _dup_paste_nodes(type, copy_type, copy_nodes_buffer, copy_nodes_excluded_buffer, (graph->get_scroll_ofs() / scale + graph->get_local_mouse_position() / scale - selection_center), false); + Vector2 mpos; + if (p_use_custom_position) { + mpos = p_custom_position; + } else { + mpos = graph->get_local_mouse_position(); + } + + _dup_paste_nodes(type, copy_type, copy_nodes_buffer, copy_nodes_excluded_buffer, (graph->get_scroll_ofs() / scale + mpos / scale - selection_center), false); _dup_update_excluded(type, copy_nodes_excluded_buffer); // to prevent selection of previous copies at new paste } -void VisualShaderEditor::_on_nodes_delete() { +void VisualShaderEditor::_delete_nodes() { VisualShader::Type type = VisualShader::Type(edit_type->get_selected()); List<int> to_erase; @@ -2076,6 +2138,26 @@ void VisualShaderEditor::_tools_menu_option(int p_idx) { } } +void VisualShaderEditor::_node_menu_id_pressed(int p_idx) { + switch (p_idx) { + case NodeMenuOptions::ADD: + _show_members_dialog(true); + break; + case NodeMenuOptions::COPY: + _copy_nodes(); + break; + case NodeMenuOptions::PASTE: + _paste_nodes(true, menu_point); + break; + case NodeMenuOptions::DELETE: + _delete_nodes(); + break; + case NodeMenuOptions::DUPLICATE: + _duplicate_nodes(); + break; + } +} + Variant VisualShaderEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from) { if (p_from == members) { @@ -2214,7 +2296,7 @@ void VisualShaderEditor::_bind_methods() { ClassDB::bind_method("_node_selected", &VisualShaderEditor::_node_selected); ClassDB::bind_method("_scroll_changed", &VisualShaderEditor::_scroll_changed); ClassDB::bind_method("_delete_request", &VisualShaderEditor::_delete_request); - ClassDB::bind_method("_on_nodes_delete", &VisualShaderEditor::_on_nodes_delete); + ClassDB::bind_method("_delete_nodes", &VisualShaderEditor::_delete_nodes); ClassDB::bind_method("_node_changed", &VisualShaderEditor::_node_changed); ClassDB::bind_method("_edit_port_default_input", &VisualShaderEditor::_edit_port_default_input); ClassDB::bind_method("_port_edited", &VisualShaderEditor::_port_edited); @@ -2257,6 +2339,8 @@ void VisualShaderEditor::_bind_methods() { ClassDB::bind_method("_member_unselected", &VisualShaderEditor::_member_unselected); ClassDB::bind_method("_member_create", &VisualShaderEditor::_member_create); ClassDB::bind_method("_member_cancel", &VisualShaderEditor::_member_cancel); + + ClassDB::bind_method("_node_menu_id_pressed", &VisualShaderEditor::_node_menu_id_pressed); } VisualShaderEditor *VisualShaderEditor::singleton = NULL; @@ -2290,6 +2374,7 @@ VisualShaderEditor::VisualShaderEditor() { main_box->add_child(graph); graph->set_drag_forwarding(this); graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_SCALAR); + graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_SCALAR_INT); graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_BOOLEAN); graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_VECTOR); graph->add_valid_right_disconnect_type(VisualShaderNode::PORT_TYPE_TRANSFORM); @@ -2303,17 +2388,24 @@ VisualShaderEditor::VisualShaderEditor() { graph->connect_compat("duplicate_nodes_request", this, "_duplicate_nodes"); graph->connect_compat("copy_nodes_request", this, "_copy_nodes"); graph->connect_compat("paste_nodes_request", this, "_paste_nodes"); - graph->connect_compat("delete_nodes_request", this, "_on_nodes_delete"); + graph->connect_compat("delete_nodes_request", this, "_delete_nodes"); graph->connect_compat("gui_input", this, "_graph_gui_input"); graph->connect_compat("connection_to_empty", this, "_connection_to_empty"); graph->connect_compat("connection_from_empty", this, "_connection_from_empty"); graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_SCALAR); + graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_SCALAR_INT); graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_VECTOR); graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR, VisualShaderNode::PORT_TYPE_BOOLEAN); + graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR_INT, VisualShaderNode::PORT_TYPE_SCALAR_INT); + graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR_INT, VisualShaderNode::PORT_TYPE_SCALAR); + graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR_INT, VisualShaderNode::PORT_TYPE_VECTOR); + graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_SCALAR_INT, VisualShaderNode::PORT_TYPE_BOOLEAN); graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_SCALAR); + graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_SCALAR_INT); graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_VECTOR); graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_VECTOR, VisualShaderNode::PORT_TYPE_BOOLEAN); graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_BOOLEAN, VisualShaderNode::PORT_TYPE_SCALAR); + graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_BOOLEAN, VisualShaderNode::PORT_TYPE_SCALAR_INT); graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_BOOLEAN, VisualShaderNode::PORT_TYPE_VECTOR); graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_BOOLEAN, VisualShaderNode::PORT_TYPE_BOOLEAN); graph->add_valid_connection_type(VisualShaderNode::PORT_TYPE_TRANSFORM, VisualShaderNode::PORT_TYPE_TRANSFORM); @@ -2365,6 +2457,20 @@ VisualShaderEditor::VisualShaderEditor() { error_text->set_visible(false); /////////////////////////////////////// + // POPUP MENU + /////////////////////////////////////// + + popup_menu = memnew(PopupMenu); + add_child(popup_menu); + popup_menu->add_item("Add Node", NodeMenuOptions::ADD); + popup_menu->add_separator(); + popup_menu->add_item("Copy", NodeMenuOptions::COPY); + popup_menu->add_item("Paste", NodeMenuOptions::PASTE); + popup_menu->add_item("Delete", NodeMenuOptions::DELETE); + popup_menu->add_item("Duplicate", NodeMenuOptions::DUPLICATE); + popup_menu->connect_compat("id_pressed", this, "_node_menu_id_pressed"); + + /////////////////////////////////////// // SHADER NODES TREE /////////////////////////////////////// @@ -2602,7 +2708,7 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("CustomAlpha", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "custom_alpha"), "custom_alpha", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); add_options.push_back(AddOption("Delta", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "delta"), "delta", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); add_options.push_back(AddOption("EmissionTransform", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "emission_transform"), "emission_transform", VisualShaderNode::PORT_TYPE_TRANSFORM, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Index", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "index"), "index", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Index", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "index"), "index", VisualShaderNode::PORT_TYPE_SCALAR_INT, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); add_options.push_back(AddOption("LifeTime", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "lifetime"), "lifetime", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); add_options.push_back(AddOption("Restart", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "restart"), "restart", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); add_options.push_back(AddOption("Time", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); @@ -2611,71 +2717,84 @@ VisualShaderEditor::VisualShaderEditor() { // SCALAR - add_options.push_back(AddOption("ScalarFunc", "Scalar", "Common", "VisualShaderNodeScalarFunc", TTR("Scalar function."), -1, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("ScalarOp", "Scalar", "Common", "VisualShaderNodeScalarOp", TTR("Scalar operator."), -1, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("FloatFunc", "Scalar", "Common", "VisualShaderNodeFloatFunc", TTR("Float function."), -1, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("IntFunc", "Scalar", "Common", "VisualShaderNodeIntFunc", TTR("Integer function."), -1, VisualShaderNode::PORT_TYPE_SCALAR_INT)); + add_options.push_back(AddOption("FloatOp", "Scalar", "Common", "VisualShaderNodeFloatOp", TTR("Float operator."), -1, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("IntOp", "Scalar", "Common", "VisualShaderNodeIntOp", TTR("Integer operator."), -1, VisualShaderNode::PORT_TYPE_SCALAR_INT)); //CONSTANTS - add_options.push_back(AddOption("E", "Scalar", "Constants", "VisualShaderNodeScalarConstant", TTR("E constant (2.718282). Represents the base of the natural logarithm."), -1, VisualShaderNode::PORT_TYPE_SCALAR, -1, -1, Math_E)); - add_options.push_back(AddOption("Epsilon", "Scalar", "Constants", "VisualShaderNodeScalarConstant", TTR("Epsilon constant (0.00001). Smallest possible scalar number."), -1, VisualShaderNode::PORT_TYPE_SCALAR, -1, -1, CMP_EPSILON)); - add_options.push_back(AddOption("Phi", "Scalar", "Constants", "VisualShaderNodeScalarConstant", TTR("Phi constant (1.618034). Golden ratio."), -1, VisualShaderNode::PORT_TYPE_SCALAR, -1, -1, 1.618034f)); - add_options.push_back(AddOption("Pi/4", "Scalar", "Constants", "VisualShaderNodeScalarConstant", TTR("Pi/4 constant (0.785398) or 45 degrees."), -1, VisualShaderNode::PORT_TYPE_SCALAR, -1, -1, Math_PI / 4)); - add_options.push_back(AddOption("Pi/2", "Scalar", "Constants", "VisualShaderNodeScalarConstant", TTR("Pi/2 constant (1.570796) or 90 degrees."), -1, VisualShaderNode::PORT_TYPE_SCALAR, -1, -1, Math_PI / 2)); - add_options.push_back(AddOption("Pi", "Scalar", "Constants", "VisualShaderNodeScalarConstant", TTR("Pi constant (3.141593) or 180 degrees."), -1, VisualShaderNode::PORT_TYPE_SCALAR, -1, -1, Math_PI)); - add_options.push_back(AddOption("Tau", "Scalar", "Constants", "VisualShaderNodeScalarConstant", TTR("Tau constant (6.283185) or 360 degrees."), -1, VisualShaderNode::PORT_TYPE_SCALAR, -1, -1, Math_TAU)); - add_options.push_back(AddOption("Sqrt2", "Scalar", "Constants", "VisualShaderNodeScalarConstant", TTR("Sqrt2 constant (1.414214). Square root of 2."), -1, VisualShaderNode::PORT_TYPE_SCALAR, -1, -1, Math_SQRT2)); + add_options.push_back(AddOption("E", "Scalar", "Constants", "VisualShaderNodeFloatConstant", TTR("E constant (2.718282). Represents the base of the natural logarithm."), -1, VisualShaderNode::PORT_TYPE_SCALAR, -1, -1, Math_E)); + add_options.push_back(AddOption("Epsilon", "Scalar", "Constants", "VisualShaderNodeFloatConstant", TTR("Epsilon constant (0.00001). Smallest possible scalar number."), -1, VisualShaderNode::PORT_TYPE_SCALAR, -1, -1, CMP_EPSILON)); + add_options.push_back(AddOption("Phi", "Scalar", "Constants", "VisualShaderNodeFloatConstant", TTR("Phi constant (1.618034). Golden ratio."), -1, VisualShaderNode::PORT_TYPE_SCALAR, -1, -1, 1.618034f)); + add_options.push_back(AddOption("Pi/4", "Scalar", "Constants", "VisualShaderNodeFloatConstant", TTR("Pi/4 constant (0.785398) or 45 degrees."), -1, VisualShaderNode::PORT_TYPE_SCALAR, -1, -1, Math_PI / 4)); + add_options.push_back(AddOption("Pi/2", "Scalar", "Constants", "VisualShaderNodeFloatConstant", TTR("Pi/2 constant (1.570796) or 90 degrees."), -1, VisualShaderNode::PORT_TYPE_SCALAR, -1, -1, Math_PI / 2)); + add_options.push_back(AddOption("Pi", "Scalar", "Constants", "VisualShaderNodeFloatConstant", TTR("Pi constant (3.141593) or 180 degrees."), -1, VisualShaderNode::PORT_TYPE_SCALAR, -1, -1, Math_PI)); + add_options.push_back(AddOption("Tau", "Scalar", "Constants", "VisualShaderNodeFloatConstant", TTR("Tau constant (6.283185) or 360 degrees."), -1, VisualShaderNode::PORT_TYPE_SCALAR, -1, -1, Math_TAU)); + add_options.push_back(AddOption("Sqrt2", "Scalar", "Constants", "VisualShaderNodeFloatConstant", TTR("Sqrt2 constant (1.414214). Square root of 2."), -1, VisualShaderNode::PORT_TYPE_SCALAR, -1, -1, Math_SQRT2)); // FUNCTIONS - add_options.push_back(AddOption("Abs", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the absolute value of the parameter."), VisualShaderNodeScalarFunc::FUNC_ABS, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("ACos", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the arc-cosine of the parameter."), VisualShaderNodeScalarFunc::FUNC_ACOS, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("ACosH", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the inverse hyperbolic cosine of the parameter."), VisualShaderNodeScalarFunc::FUNC_ACOSH, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("ASin", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the arc-sine of the parameter."), VisualShaderNodeScalarFunc::FUNC_ASIN, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("ASinH", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the inverse hyperbolic sine of the parameter."), VisualShaderNodeScalarFunc::FUNC_ASINH, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("ATan", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the arc-tangent of the parameter."), VisualShaderNodeScalarFunc::FUNC_ATAN, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("ATan2", "Scalar", "Functions", "VisualShaderNodeScalarOp", TTR("Returns the arc-tangent of the parameters."), VisualShaderNodeScalarOp::OP_ATAN2, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("ATanH", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the inverse hyperbolic tangent of the parameter."), VisualShaderNodeScalarFunc::FUNC_ATANH, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Ceil", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Finds the nearest integer that is greater than or equal to the parameter."), VisualShaderNodeScalarFunc::FUNC_CEIL, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Abs", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the absolute value of the parameter."), VisualShaderNodeFloatFunc::FUNC_ABS, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Abs", "Scalar", "Functions", "VisualShaderNodeIntFunc", TTR("Returns the absolute value of the parameter."), VisualShaderNodeIntFunc::FUNC_ABS, VisualShaderNode::PORT_TYPE_SCALAR_INT)); + add_options.push_back(AddOption("ACos", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the arc-cosine of the parameter."), VisualShaderNodeFloatFunc::FUNC_ACOS, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("ACosH", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the inverse hyperbolic cosine of the parameter."), VisualShaderNodeFloatFunc::FUNC_ACOSH, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("ASin", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the arc-sine of the parameter."), VisualShaderNodeFloatFunc::FUNC_ASIN, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("ASinH", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the inverse hyperbolic sine of the parameter."), VisualShaderNodeFloatFunc::FUNC_ASINH, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("ATan", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the arc-tangent of the parameter."), VisualShaderNodeFloatFunc::FUNC_ATAN, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("ATan2", "Scalar", "Functions", "VisualShaderNodeFloatOp", TTR("Returns the arc-tangent of the parameters."), VisualShaderNodeFloatOp::OP_ATAN2, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("ATanH", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the inverse hyperbolic tangent of the parameter."), VisualShaderNodeFloatFunc::FUNC_ATANH, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Ceil", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Finds the nearest integer that is greater than or equal to the parameter."), VisualShaderNodeFloatFunc::FUNC_CEIL, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Clamp", "Scalar", "Functions", "VisualShaderNodeScalarClamp", TTR("Constrains a value to lie between two further values."), -1, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Cos", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the cosine of the parameter."), VisualShaderNodeScalarFunc::FUNC_COS, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("CosH", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the hyperbolic cosine of the parameter."), VisualShaderNodeScalarFunc::FUNC_COSH, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Degrees", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Converts a quantity in radians to degrees."), VisualShaderNodeScalarFunc::FUNC_DEGREES, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Exp", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Base-e Exponential."), VisualShaderNodeScalarFunc::FUNC_EXP, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Exp2", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Base-2 Exponential."), VisualShaderNodeScalarFunc::FUNC_EXP2, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Floor", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Finds the nearest integer less than or equal to the parameter."), VisualShaderNodeScalarFunc::FUNC_FLOOR, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Fract", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Computes the fractional part of the argument."), VisualShaderNodeScalarFunc::FUNC_FRAC, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("InverseSqrt", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the inverse of the square root of the parameter."), VisualShaderNodeScalarFunc::FUNC_INVERSE_SQRT, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Log", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Natural logarithm."), VisualShaderNodeScalarFunc::FUNC_LOG, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Log2", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Base-2 logarithm."), VisualShaderNodeScalarFunc::FUNC_LOG2, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Max", "Scalar", "Functions", "VisualShaderNodeScalarOp", TTR("Returns the greater of two values."), VisualShaderNodeScalarOp::OP_MAX, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Min", "Scalar", "Functions", "VisualShaderNodeScalarOp", TTR("Returns the lesser of two values."), VisualShaderNodeScalarOp::OP_MIN, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Clamp", "Scalar", "Functions", "VisualShaderNodeIntFunc", TTR("Constrains a value to lie between two further values."), VisualShaderNodeIntFunc::FUNC_CLAMP, VisualShaderNode::PORT_TYPE_SCALAR_INT)); + add_options.push_back(AddOption("Cos", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the cosine of the parameter."), VisualShaderNodeFloatFunc::FUNC_COS, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("CosH", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the hyperbolic cosine of the parameter."), VisualShaderNodeFloatFunc::FUNC_COSH, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Degrees", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Converts a quantity in radians to degrees."), VisualShaderNodeFloatFunc::FUNC_DEGREES, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Exp", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Base-e Exponential."), VisualShaderNodeFloatFunc::FUNC_EXP, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Exp2", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Base-2 Exponential."), VisualShaderNodeFloatFunc::FUNC_EXP2, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Floor", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Finds the nearest integer less than or equal to the parameter."), VisualShaderNodeFloatFunc::FUNC_FLOOR, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Fract", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Computes the fractional part of the argument."), VisualShaderNodeFloatFunc::FUNC_FRAC, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("InverseSqrt", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the inverse of the square root of the parameter."), VisualShaderNodeFloatFunc::FUNC_INVERSE_SQRT, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Log", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Natural logarithm."), VisualShaderNodeFloatFunc::FUNC_LOG, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Log2", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Base-2 logarithm."), VisualShaderNodeFloatFunc::FUNC_LOG2, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Max", "Scalar", "Functions", "VisualShaderNodeFloatOp", TTR("Returns the greater of two values."), VisualShaderNodeFloatOp::OP_MAX, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Min", "Scalar", "Functions", "VisualShaderNodeFloatOp", TTR("Returns the lesser of two values."), VisualShaderNodeFloatOp::OP_MIN, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Mix", "Scalar", "Functions", "VisualShaderNodeScalarInterp", TTR("Linear interpolation between two scalars."), -1, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Negate", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the opposite value of the parameter."), VisualShaderNodeScalarFunc::FUNC_NEGATE, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("OneMinus", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("1.0 - scalar"), VisualShaderNodeScalarFunc::FUNC_ONEMINUS, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Pow", "Scalar", "Functions", "VisualShaderNodeScalarOp", TTR("Returns the value of the first parameter raised to the power of the second."), VisualShaderNodeScalarOp::OP_POW, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Radians", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Converts a quantity in degrees to radians."), VisualShaderNodeScalarFunc::FUNC_RADIANS, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Reciprocal", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("1.0 / scalar"), VisualShaderNodeScalarFunc::FUNC_RECIPROCAL, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Round", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Finds the nearest integer to the parameter."), VisualShaderNodeScalarFunc::FUNC_ROUND, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("RoundEven", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Finds the nearest even integer to the parameter."), VisualShaderNodeScalarFunc::FUNC_ROUNDEVEN, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Saturate", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Clamps the value between 0.0 and 1.0."), VisualShaderNodeScalarFunc::FUNC_SATURATE, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Sign", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Extracts the sign of the parameter."), VisualShaderNodeScalarFunc::FUNC_SIGN, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Sin", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the sine of the parameter."), VisualShaderNodeScalarFunc::FUNC_SIN, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("SinH", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the hyperbolic sine of the parameter."), VisualShaderNodeScalarFunc::FUNC_SINH, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Sqrt", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the square root of the parameter."), VisualShaderNodeScalarFunc::FUNC_SQRT, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Negate", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the opposite value of the parameter."), VisualShaderNodeFloatFunc::FUNC_NEGATE, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Negate", "Scalar", "Functions", "VisualShaderNodeIntFunc", TTR("Returns the opposite value of the parameter."), VisualShaderNodeIntFunc::FUNC_NEGATE, VisualShaderNode::PORT_TYPE_SCALAR_INT)); + add_options.push_back(AddOption("OneMinus", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("1.0 - scalar"), VisualShaderNodeFloatFunc::FUNC_ONEMINUS, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Pow", "Scalar", "Functions", "VisualShaderNodeFloatOp", TTR("Returns the value of the first parameter raised to the power of the second."), VisualShaderNodeFloatOp::OP_POW, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Radians", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Converts a quantity in degrees to radians."), VisualShaderNodeFloatFunc::FUNC_RADIANS, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Reciprocal", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("1.0 / scalar"), VisualShaderNodeFloatFunc::FUNC_RECIPROCAL, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Round", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Finds the nearest integer to the parameter."), VisualShaderNodeFloatFunc::FUNC_ROUND, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("RoundEven", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Finds the nearest even integer to the parameter."), VisualShaderNodeFloatFunc::FUNC_ROUNDEVEN, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Saturate", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Clamps the value between 0.0 and 1.0."), VisualShaderNodeFloatFunc::FUNC_SATURATE, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Sign", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Extracts the sign of the parameter."), VisualShaderNodeFloatFunc::FUNC_SIGN, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Sign", "Scalar", "Functions", "VisualShaderNodeIntFunc", TTR("Extracts the sign of the parameter."), VisualShaderNodeIntFunc::FUNC_SIGN, VisualShaderNode::PORT_TYPE_SCALAR_INT)); + add_options.push_back(AddOption("Sin", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the sine of the parameter."), VisualShaderNodeFloatFunc::FUNC_SIN, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("SinH", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the hyperbolic sine of the parameter."), VisualShaderNodeFloatFunc::FUNC_SINH, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Sqrt", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the square root of the parameter."), VisualShaderNodeFloatFunc::FUNC_SQRT, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("SmoothStep", "Scalar", "Functions", "VisualShaderNodeScalarSmoothStep", TTR("SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge0' and 1.0 if x is larger than 'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 using Hermite polynomials."), -1, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Step", "Scalar", "Functions", "VisualShaderNodeScalarOp", TTR("Step function( scalar(edge), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), VisualShaderNodeScalarOp::OP_STEP, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Tan", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the tangent of the parameter."), VisualShaderNodeScalarFunc::FUNC_TAN, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("TanH", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the hyperbolic tangent of the parameter."), VisualShaderNodeScalarFunc::FUNC_TANH, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Trunc", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Finds the truncated value of the parameter."), VisualShaderNodeScalarFunc::FUNC_TRUNC, VisualShaderNode::PORT_TYPE_SCALAR)); - - add_options.push_back(AddOption("Add", "Scalar", "Operators", "VisualShaderNodeScalarOp", TTR("Adds scalar to scalar."), VisualShaderNodeScalarOp::OP_ADD, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Divide", "Scalar", "Operators", "VisualShaderNodeScalarOp", TTR("Divides scalar by scalar."), VisualShaderNodeScalarOp::OP_DIV, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Multiply", "Scalar", "Operators", "VisualShaderNodeScalarOp", TTR("Multiplies scalar by scalar."), VisualShaderNodeScalarOp::OP_MUL, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Remainder", "Scalar", "Operators", "VisualShaderNodeScalarOp", TTR("Returns the remainder of the two scalars."), VisualShaderNodeScalarOp::OP_MOD, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Subtract", "Scalar", "Operators", "VisualShaderNodeScalarOp", TTR("Subtracts scalar from scalar."), VisualShaderNodeScalarOp::OP_SUB, VisualShaderNode::PORT_TYPE_SCALAR)); - - add_options.push_back(AddOption("ScalarConstant", "Scalar", "Variables", "VisualShaderNodeScalarConstant", TTR("Scalar constant."), -1, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("ScalarUniform", "Scalar", "Variables", "VisualShaderNodeScalarUniform", TTR("Scalar uniform."), -1, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Step", "Scalar", "Functions", "VisualShaderNodeFloatOp", TTR("Step function( scalar(edge), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."), VisualShaderNodeFloatOp::OP_STEP, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Tan", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the tangent of the parameter."), VisualShaderNodeFloatFunc::FUNC_TAN, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("TanH", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the hyperbolic tangent of the parameter."), VisualShaderNodeFloatFunc::FUNC_TANH, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Trunc", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Finds the truncated value of the parameter."), VisualShaderNodeFloatFunc::FUNC_TRUNC, VisualShaderNode::PORT_TYPE_SCALAR)); + + add_options.push_back(AddOption("Add", "Scalar", "Operators", "VisualShaderNodeFloatOp", TTR("Sums two floating-point scalars."), VisualShaderNodeFloatOp::OP_ADD, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Add", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Sums two integer scalars."), VisualShaderNodeIntOp::OP_ADD, VisualShaderNode::PORT_TYPE_SCALAR_INT)); + add_options.push_back(AddOption("Divide", "Scalar", "Operators", "VisualShaderNodeFloatOp", TTR("Divides two floating-point scalars."), VisualShaderNodeFloatOp::OP_DIV, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Divide", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Divides two integer scalars."), VisualShaderNodeIntOp::OP_DIV, VisualShaderNode::PORT_TYPE_SCALAR_INT)); + add_options.push_back(AddOption("Multiply", "Scalar", "Operators", "VisualShaderNodeFloatOp", TTR("Multiplies two floating-point scalars."), VisualShaderNodeFloatOp::OP_MUL, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Multiply", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Multiplies two integer scalars."), VisualShaderNodeIntOp::OP_MUL, VisualShaderNode::PORT_TYPE_SCALAR_INT)); + add_options.push_back(AddOption("Remainder", "Scalar", "Operators", "VisualShaderNodeFloatOp", TTR("Returns the remainder of the two floating-point scalars."), VisualShaderNodeFloatOp::OP_MOD, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Remainder", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Returns the remainder of the two integer scalars."), VisualShaderNodeIntOp::OP_MOD, VisualShaderNode::PORT_TYPE_SCALAR_INT)); + add_options.push_back(AddOption("Subtract", "Scalar", "Operators", "VisualShaderNodeFloatOp", TTR("Subtracts two floating-point scalars."), VisualShaderNodeFloatOp::OP_SUB, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Subtract", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Subtracts two integer scalars."), VisualShaderNodeIntOp::OP_SUB, VisualShaderNode::PORT_TYPE_SCALAR_INT)); + + add_options.push_back(AddOption("FloatConstant", "Scalar", "Variables", "VisualShaderNodeFloatConstant", TTR("Scalar floating-point constant."), -1, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("IntConstant", "Scalar", "Variables", "VisualShaderNodeIntConstant", TTR("Scalar integer constant."), -1, VisualShaderNode::PORT_TYPE_SCALAR_INT)); + add_options.push_back(AddOption("FloatUniform", "Scalar", "Variables", "VisualShaderNodeFloatUniform", TTR("Scalar floating-point uniform."), -1, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("IntUniform", "Scalar", "Variables", "VisualShaderNodeIntUniform", TTR("Scalar integer uniform."), -1, VisualShaderNode::PORT_TYPE_SCALAR_INT)); // TEXTURES @@ -2881,8 +3000,9 @@ public: void setup(const Ref<VisualShaderNodeInput> &p_input) { input = p_input; - Ref<Texture2D> type_icon[5] = { + Ref<Texture2D> type_icon[6] = { EditorNode::get_singleton()->get_gui_base()->get_icon("float", "EditorIcons"), + EditorNode::get_singleton()->get_gui_base()->get_icon("int", "EditorIcons"), EditorNode::get_singleton()->get_gui_base()->get_icon("Vector3", "EditorIcons"), EditorNode::get_singleton()->get_gui_base()->get_icon("bool", "EditorIcons"), EditorNode::get_singleton()->get_gui_base()->get_icon("Transform", "EditorIcons"), diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index 8919690ada..8756fe9fe9 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -81,6 +81,7 @@ class VisualShaderEditor : public VBoxContainer { bool saved_node_pos_dirty; ConfirmationDialog *members_dialog; + PopupMenu *popup_menu; MenuButton *tools; bool preview_showed; @@ -90,6 +91,15 @@ class VisualShaderEditor : public VBoxContainer { COLLAPSE_ALL }; + enum NodeMenuOptions { + ADD, + SEPARATOR, // ignore + COPY, + PASTE, + DELETE, + DUPLICATE, + }; + Tree *members; AcceptDialog *alert; LineEdit *node_filter; @@ -181,7 +191,7 @@ class VisualShaderEditor : public VBoxContainer { void _node_selected(Object *p_node); void _delete_request(int); - void _on_nodes_delete(); + void _delete_nodes(); void _removed_from_graph(); @@ -216,7 +226,7 @@ class VisualShaderEditor : public VBoxContainer { void _clear_buffer(); void _copy_nodes(); - void _paste_nodes(); + void _paste_nodes(bool p_use_custom_position = false, const Vector2 &p_custom_position = Vector2()); Vector<Ref<VisualShaderNodePlugin> > plugins; @@ -250,6 +260,9 @@ class VisualShaderEditor : public VBoxContainer { void _member_create(); void _member_cancel(); + Vector2 menu_point; + void _node_menu_id_pressed(int p_idx); + Variant get_drag_data_fw(const Point2 &p_point, Control *p_from); bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const; void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from); diff --git a/main/main.cpp b/main/main.cpp index e3747fc48c..d8a9cc87a7 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -203,6 +203,7 @@ void finalize_physics() { void initialize_navigation_server() { ERR_FAIL_COND(navigation_server != NULL); + navigation_server = NavigationServerManager::new_default_server(); navigation_2d_server = memnew(Navigation2DServer); } @@ -210,6 +211,7 @@ void initialize_navigation_server() { void finalize_navigation_server() { memdelete(navigation_server); navigation_server = NULL; + memdelete(navigation_2d_server); navigation_2d_server = NULL; } @@ -2037,9 +2039,9 @@ bool Main::iteration() { break; } - message_queue->flush(); + NavigationServer::get_singleton_mut()->process(frame_slice * time_scale); - NavigationServer::get_singleton_mut()->step(frame_slice * time_scale); + message_queue->flush(); PhysicsServer::get_singleton()->step(frame_slice * time_scale); diff --git a/methods.py b/methods.py index 5fdcc2c4b4..3f03e6bbd2 100644 --- a/methods.py +++ b/methods.py @@ -557,16 +557,19 @@ def is_vanilla_clang(env): def get_compiler_version(env): - if using_gcc(env): - version = decode_utf8(subprocess.check_output([env['CXX'], '-dumpversion']).strip()) - elif using_clang(env): - # Not using -dumpversion as it used to return 4.2.1: https://reviews.llvm.org/D56803 + """ + Returns an array of version numbers as ints: [major, minor, patch]. + The return array should have at least two values (major, minor). + """ + if not env.msvc: + # Not using -dumpversion as some GCC distros only return major, and + # Clang used to return hardcoded 4.2.1: # https://reviews.llvm.org/D56803 version = decode_utf8(subprocess.check_output([env['CXX'], '--version']).strip()) else: # TODO: Implement for MSVC return None - match = re.search('[0-9][0-9.]*', version) + match = re.search('[0-9]+\.[0-9.]+', version) if match is not None: - return match.group().split('.') + return list(map(int, match.group().split('.'))) else: return None diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp index 0e4c4b4731..f6df97f11d 100644 --- a/modules/bullet/space_bullet.cpp +++ b/modules/bullet/space_bullet.cpp @@ -726,9 +726,6 @@ void SpaceBullet::check_ghost_overlaps() { other_body_shape = static_cast<btCollisionShape *>(otherObject->get_bt_shape(z)); - if (other_body_shape->isConcave()) - continue; - btTransform other_shape_transform(otherObject->get_bt_shape_transform(z)); other_shape_transform.getOrigin() *= other_body_scale; diff --git a/modules/gdnavigation/gd_navigation_server.cpp b/modules/gdnavigation/gd_navigation_server.cpp index 1f1783802d..4129d1f65a 100644 --- a/modules/gdnavigation/gd_navigation_server.cpp +++ b/modules/gdnavigation/gd_navigation_server.cpp @@ -121,6 +121,7 @@ GdNavigationServer::GdNavigationServer() : } GdNavigationServer::~GdNavigationServer() { + flush_queries(); memdelete(operations_mutex); memdelete(commands_mutex); } @@ -474,12 +475,9 @@ void GdNavigationServer::set_active(bool p_active) const { mut_this->operations_mutex->unlock(); } -void GdNavigationServer::step(real_t p_delta_time) { - if (!active) { - return; - } - - // With c++ we can't be 100% sure this is called in single thread so use the mutex. +void GdNavigationServer::flush_queries() { + // In c++ we can't be sure that this is performed in the main thread + // even with mutable functions. commands_mutex->lock(); operations_mutex->lock(); for (size_t i(0); i < commands.size(); i++) { @@ -489,13 +487,24 @@ void GdNavigationServer::step(real_t p_delta_time) { commands.clear(); operations_mutex->unlock(); commands_mutex->unlock(); +} + +void GdNavigationServer::process(real_t p_delta_time) { + flush_queries(); - // These are internal operations so don't need to be shielded. + if (!active) { + return; + } + + // In c++ we can't be sure that this is performed in the main thread + // even with mutable functions. + operations_mutex->lock(); for (int i(0); i < active_maps.size(); i++) { active_maps[i]->sync(); active_maps[i]->step(p_delta_time); active_maps[i]->dispatch_callbacks(); } + operations_mutex->unlock(); } #undef COMMAND_1 diff --git a/modules/gdnavigation/gd_navigation_server.h b/modules/gdnavigation/gd_navigation_server.h index 7fa5979c31..0400acf1a3 100644 --- a/modules/gdnavigation/gd_navigation_server.h +++ b/modules/gdnavigation/gd_navigation_server.h @@ -131,7 +131,9 @@ public: COMMAND_1(free, RID, p_object); virtual void set_active(bool p_active) const; - virtual void step(real_t p_delta_time); + + void flush_queries(); + virtual void process(real_t p_delta_time); }; #undef COMMAND_1 diff --git a/modules/gdscript/language_server/gdscript_workspace.cpp b/modules/gdscript/language_server/gdscript_workspace.cpp index 1c0590cff1..ea54784f96 100644 --- a/modules/gdscript/language_server/gdscript_workspace.cpp +++ b/modules/gdscript/language_server/gdscript_workspace.cpp @@ -33,8 +33,11 @@ #include "../gdscript_parser.h" #include "core/project_settings.h" #include "core/script_language.h" +#include "editor/editor_file_system.h" #include "editor/editor_help.h" +#include "editor/editor_node.h" #include "gdscript_language_protocol.h" +#include "scene/resources/packed_scene.h" void GDScriptWorkspace::_bind_methods() { ClassDB::bind_method(D_METHOD("symbol"), &GDScriptWorkspace::symbol); @@ -373,6 +376,46 @@ void GDScriptWorkspace::publish_diagnostics(const String &p_path) { GDScriptLanguageProtocol::get_singleton()->notify_client("textDocument/publishDiagnostics", params); } +void GDScriptWorkspace::_get_owners(EditorFileSystemDirectory *efsd, String p_path, List<String> &owners) { + if (!efsd) + return; + + for (int i = 0; i < efsd->get_subdir_count(); i++) { + _get_owners(efsd->get_subdir(i), p_path, owners); + } + + for (int i = 0; i < efsd->get_file_count(); i++) { + + Vector<String> deps = efsd->get_file_deps(i); + bool found = false; + for (int j = 0; j < deps.size(); j++) { + if (deps[j] == p_path) { + found = true; + break; + } + } + if (!found) + continue; + + owners.push_back(efsd->get_file_path(i)); + } +} + +Node *GDScriptWorkspace::_get_owner_node(String p_path) { + Node *owner_node = NULL; + List<String> owners; + + _get_owners(EditorFileSystem::get_singleton()->get_filesystem(), p_path, owners); + + if (owners.size() > 0) { + NodePath owner_path = owners[0]; + Ref<PackedScene> owner_res = ResourceLoader::load(owner_path); + owner_node = owner_res->instance(PackedScene::GEN_EDIT_STATE_DISABLED); + } + + return owner_node; +} + void GDScriptWorkspace::completion(const lsp::CompletionParams &p_params, List<ScriptCodeCompletionOption> *r_options) { String path = get_file_path(p_params.textDocument.uri); @@ -380,8 +423,12 @@ void GDScriptWorkspace::completion(const lsp::CompletionParams &p_params, List<S bool forced = false; if (const ExtendGDScriptParser *parser = get_parse_result(path)) { + Node *owner_node = _get_owner_node(path); String code = parser->get_text_for_completion(p_params.position); - GDScriptLanguage::get_singleton()->complete_code(code, path, NULL, r_options, forced, call_hint); + GDScriptLanguage::get_singleton()->complete_code(code, path, owner_node, r_options, forced, call_hint); + if (owner_node) { + memdelete(owner_node); + } } } diff --git a/modules/gdscript/language_server/gdscript_workspace.h b/modules/gdscript/language_server/gdscript_workspace.h index 146a5cb7c9..8b46d345d9 100644 --- a/modules/gdscript/language_server/gdscript_workspace.h +++ b/modules/gdscript/language_server/gdscript_workspace.h @@ -33,12 +33,17 @@ #include "../gdscript_parser.h" #include "core/variant.h" +#include "editor/editor_file_system.h" #include "gdscript_extend_parser.h" #include "lsp.hpp" class GDScriptWorkspace : public Reference { GDCLASS(GDScriptWorkspace, Reference); +private: + void _get_owners(EditorFileSystemDirectory *efsd, String p_path, List<String> &owners); + Node *_get_owner_node(String p_path); + protected: static void _bind_methods(); void remove_cache_parser(const String &p_path); diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index 8d58cb9c4d..0bbef066a4 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -623,16 +623,24 @@ void VisualScriptEditor::_update_graph(int p_only_id) { sbf = EditorNode::get_singleton()->get_theme_base()->get_theme()->get_stylebox("comment", "GraphNode"); Color c = sbf->get_border_color(); + Color ic = c; c.a = 1; if (EditorSettings::get_singleton()->get("interface/theme/use_graph_node_headers")) { - Color mono_color = ((c.r + c.g + c.b) / 3) < 0.7 ? Color(1.0, 1.0, 1.0) : Color(0.0, 0.0, 0.0); + Color mono_color; + if (((c.r + c.g + c.b) / 3) < 0.7) { + mono_color = Color(1.0, 1.0, 1.0); + ic = Color(0.0, 0.0, 0.0, 0.7); + } else { + mono_color = Color(0.0, 0.0, 0.0); + ic = Color(1.0, 1.0, 1.0, 0.7); + } mono_color.a = 0.85; c = mono_color; } gnode->add_color_override("title_color", c); c.a = 0.7; gnode->add_color_override("close_color", c); - gnode->add_color_override("resizer_color", c); + gnode->add_color_override("resizer_color", ic); gnode->add_style_override("frame", sbf); } diff --git a/platform/server/detect.py b/platform/server/detect.py index d82df77957..ef94dc436c 100644 --- a/platform/server/detect.py +++ b/platform/server/detect.py @@ -32,6 +32,7 @@ def get_opts(): return [ BoolVariable('use_llvm', 'Use the LLVM compiler', False), BoolVariable('use_static_cpp', 'Link libgcc and libstdc++ statically for better portability', False), + BoolVariable('use_coverage', 'Test Godot coverage', False), BoolVariable('use_ubsan', 'Use LLVM/GCC compiler undefined behavior sanitizer (UBSAN)', False), BoolVariable('use_asan', 'Use LLVM/GCC compiler address sanitizer (ASAN))', False), BoolVariable('use_lsan', 'Use LLVM/GCC compiler leak sanitizer (LSAN))', False), @@ -99,6 +100,9 @@ def configure(env): env.Append(CPPDEFINES=['TYPED_METHOD_BIND']) env.extra_suffix = ".llvm" + env.extra_suffix + if env['use_coverage']: + env.Append(CCFLAGS=['-ftest-coverage', '-fprofile-arcs']) + env.Append(LINKFLAGS=['-ftest-coverage', '-fprofile-arcs']) if env['use_ubsan'] or env['use_asan'] or env['use_lsan'] or env['use_tsan']: env.extra_suffix += "s" diff --git a/platform/x11/detect.py b/platform/x11/detect.py index 9d5affcb3c..cd22ee9ff6 100644 --- a/platform/x11/detect.py +++ b/platform/x11/detect.py @@ -61,6 +61,7 @@ def get_opts(): BoolVariable('use_lld', 'Use the LLD linker', False), BoolVariable('use_thinlto', 'Use ThinLTO', False), BoolVariable('use_static_cpp', 'Link libgcc and libstdc++ statically for better portability', False), + BoolVariable('use_coverage', 'Test Godot coverage', False), BoolVariable('use_ubsan', 'Use LLVM/GCC compiler undefined behavior sanitizer (UBSAN)', False), BoolVariable('use_asan', 'Use LLVM/GCC compiler address sanitizer (ASAN))', False), BoolVariable('use_lsan', 'Use LLVM/GCC compiler leak sanitizer (LSAN))', False), @@ -141,6 +142,10 @@ def configure(env): print("Using LLD with GCC is not supported yet, try compiling with 'use_llvm=yes'.") sys.exit(255) + if env['use_coverage']: + env.Append(CCFLAGS=['-ftest-coverage', '-fprofile-arcs']) + env.Append(LINKFLAGS=['-ftest-coverage', '-fprofile-arcs']) + if env['use_ubsan'] or env['use_asan'] or env['use_lsan'] or env['use_tsan']: env.extra_suffix += "s" @@ -179,18 +184,10 @@ def configure(env): env.Append(CCFLAGS=['-pipe']) env.Append(LINKFLAGS=['-pipe']) - # Check for gcc version >= 6 before adding -no-pie - if using_gcc(env): - version = get_compiler_version(env) - if version != None and version[0] >= '6': - env.Append(CCFLAGS=['-fpie']) - env.Append(LINKFLAGS=['-no-pie']) - # Do the same for clang should be fine with Clang 4 and higher - if using_clang(env): - version = get_compiler_version(env) - if version != None and version[0] >= '4': - env.Append(CCFLAGS=['-fpie']) - env.Append(LINKFLAGS=['-no-pie']) + # -fpie and -no-pie is supported on GCC 6+ and Clang 4+, both below our + # minimal requirements. + env.Append(CCFLAGS=['-fpie']) + env.Append(LINKFLAGS=['-no-pie']) ## Dependencies diff --git a/scene/2d/navigation_2d.cpp b/scene/2d/navigation_2d.cpp index e91560a7e0..bbabfa16c7 100644 --- a/scene/2d/navigation_2d.cpp +++ b/scene/2d/navigation_2d.cpp @@ -88,3 +88,7 @@ Navigation2D::Navigation2D() { set_cell_size(10); // Ten pixels set_edge_connection_margin(100); } + +Navigation2D::~Navigation2D() { + Navigation2DServer::get_singleton()->free(map); +} diff --git a/scene/2d/navigation_2d.h b/scene/2d/navigation_2d.h index 16e20d8f9b..5520f5006e 100644 --- a/scene/2d/navigation_2d.h +++ b/scene/2d/navigation_2d.h @@ -66,6 +66,7 @@ public: RID get_closest_point_owner(const Vector2 &p_point) const; Navigation2D(); + ~Navigation2D(); }; #endif // NAVIGATION_2D_H diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 0d3ab36852..fb8396e4ff 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -358,11 +358,20 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { [[fallthrough]]; } case KEY_LEFT: { - #ifndef APPLE_STYLE_KEYS - if (!k->get_alt()) + if (!k->get_alt()) { #endif + if (selection.enabled && !k->get_shift()) { + set_cursor_position(selection.begin); + deselect(); + handled = true; + break; + } + shift_selection_check_pre(k->get_shift()); +#ifndef APPLE_STYLE_KEYS + } +#endif #ifdef APPLE_STYLE_KEYS if (k->get_command()) { @@ -405,8 +414,20 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { [[fallthrough]]; } case KEY_RIGHT: { +#ifndef APPLE_STYLE_KEYS + if (!k->get_alt()) { +#endif + if (selection.enabled && !k->get_shift()) { + set_cursor_position(selection.end); + deselect(); + handled = true; + break; + } - shift_selection_check_pre(k->get_shift()); + shift_selection_check_pre(k->get_shift()); +#ifndef APPLE_STYLE_KEYS + } +#endif #ifdef APPLE_STYLE_KEYS if (k->get_command()) { diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 7ffead9b86..6288598ce2 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -488,17 +488,20 @@ void register_scene_types() { ClassDB::register_class<VisualShaderNodeInput>(); ClassDB::register_virtual_class<VisualShaderNodeOutput>(); ClassDB::register_class<VisualShaderNodeGroupBase>(); - ClassDB::register_class<VisualShaderNodeScalarConstant>(); + ClassDB::register_class<VisualShaderNodeFloatConstant>(); + ClassDB::register_class<VisualShaderNodeIntConstant>(); ClassDB::register_class<VisualShaderNodeBooleanConstant>(); ClassDB::register_class<VisualShaderNodeColorConstant>(); ClassDB::register_class<VisualShaderNodeVec3Constant>(); ClassDB::register_class<VisualShaderNodeTransformConstant>(); - ClassDB::register_class<VisualShaderNodeScalarOp>(); + ClassDB::register_class<VisualShaderNodeFloatOp>(); + ClassDB::register_class<VisualShaderNodeIntOp>(); ClassDB::register_class<VisualShaderNodeVectorOp>(); ClassDB::register_class<VisualShaderNodeColorOp>(); ClassDB::register_class<VisualShaderNodeTransformMult>(); ClassDB::register_class<VisualShaderNodeTransformVecMult>(); - ClassDB::register_class<VisualShaderNodeScalarFunc>(); + ClassDB::register_class<VisualShaderNodeFloatFunc>(); + ClassDB::register_class<VisualShaderNodeIntFunc>(); ClassDB::register_class<VisualShaderNodeVectorFunc>(); ClassDB::register_class<VisualShaderNodeColorFunc>(); ClassDB::register_class<VisualShaderNodeTransformFunc>(); @@ -527,7 +530,8 @@ void register_scene_types() { ClassDB::register_class<VisualShaderNodeTexture>(); ClassDB::register_class<VisualShaderNodeCubemap>(); ClassDB::register_virtual_class<VisualShaderNodeUniform>(); - ClassDB::register_class<VisualShaderNodeScalarUniform>(); + ClassDB::register_class<VisualShaderNodeFloatUniform>(); + ClassDB::register_class<VisualShaderNodeIntUniform>(); ClassDB::register_class<VisualShaderNodeBooleanUniform>(); ClassDB::register_class<VisualShaderNodeColorUniform>(); ClassDB::register_class<VisualShaderNodeVec3Uniform>(); @@ -738,6 +742,10 @@ void register_scene_types() { ClassDB::add_compatibility_class("SpatialMaterial", "StandardMaterial3D"); ClassDB::add_compatibility_class("Mesh", "ArrayMesh"); ClassDB::add_compatibility_class("AnimationTreePlayer", "AnimationTree"); + ClassDB::add_compatibility_class("VisualShaderNodeScalarConstant", "VisualShaderNodeFloatConstant"); + ClassDB::add_compatibility_class("VisualShaderNodeScalarUniform", "VisualShaderNodeFloatUniform"); + ClassDB::add_compatibility_class("VisualShaderNodeScalarOp", "VisualShaderNodeFloatOp"); + ClassDB::add_compatibility_class("VisualShaderNodeScalarFunc", "VisualShaderNodeFloatFunc"); #endif OS::get_singleton()->yield(); //may take time to init diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index 0989df479d..556d299198 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -32,6 +32,7 @@ #include "core/vmap.h" #include "servers/visual/shader_types.h" +#include "visual_shader_nodes.h" bool VisualShaderNode::is_simple_decl() const { return simple_decl; @@ -127,6 +128,7 @@ void VisualShaderNode::_bind_methods() { ADD_SIGNAL(MethodInfo("editor_refresh_request")); BIND_ENUM_CONSTANT(PORT_TYPE_SCALAR); + BIND_ENUM_CONSTANT(PORT_TYPE_SCALAR_INT); BIND_ENUM_CONSTANT(PORT_TYPE_VECTOR); BIND_ENUM_CONSTANT(PORT_TYPE_BOOLEAN); BIND_ENUM_CONSTANT(PORT_TYPE_TRANSFORM); @@ -284,6 +286,49 @@ VisualShaderNodeCustom::VisualShaderNodeCustom() { ///////////////////////////////////////////////////////// +void VisualShader::set_version(const String &p_version) { + version = p_version; +} + +String VisualShader::get_version() const { + return version; +} + +void VisualShader::update_version(const String &p_new_version) { + if (version == "") { + for (int i = 0; i < TYPE_MAX; i++) { + for (Map<int, Node>::Element *E = graph[i].nodes.front(); E; E = E->next()) { + Ref<VisualShaderNodeExpression> expression = Object::cast_to<VisualShaderNodeExpression>(E->get().node.ptr()); + if (expression.is_valid()) { + for (int j = 0; j < expression->get_input_port_count(); j++) { + int type = expression->get_input_port_type(j); + if (type > 0) { // + PORT_TYPE_SCALAR_INT + type += 1; + } + expression->set_input_port_type(j, type); + } + for (int j = 0; j < expression->get_output_port_count(); j++) { + int type = expression->get_output_port_type(j); + if (type > 0) { // + PORT_TYPE_SCALAR_INT + type += 1; + } + expression->set_output_port_type(j, type); + } + } + Ref<VisualShaderNodeCompare> compare = Object::cast_to<VisualShaderNodeCompare>(E->get().node.ptr()); + if (compare.is_valid()) { + int ctype = int(compare->get_comparison_type()); + if (int(ctype) > 0) { // + PORT_TYPE_SCALAR_INT + ctype += 1; + } + compare->set_comparison_type(VisualShaderNodeCompare::ComparisonType(ctype)); + } + } + } + } + set_version(p_new_version); +} + void VisualShader::add_node(Type p_type, const Ref<VisualShaderNode> &p_node, const Vector2 &p_position, int p_id) { ERR_FAIL_COND(p_node.is_null()); ERR_FAIL_COND(p_id < 2); @@ -469,7 +514,7 @@ bool VisualShader::can_connect_nodes(Type p_type, int p_from_node, int p_from_po } bool VisualShader::is_port_types_compatible(int p_a, int p_b) const { - return MAX(0, p_a - 2) == (MAX(0, p_b - 2)); + return MAX(0, p_a - 3) == (MAX(0, p_b - 3)); } void VisualShader::connect_nodes_forced(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) { @@ -697,9 +742,11 @@ String VisualShader::generate_preview_shader(Type p_type, int p_node, int p_port ERR_FAIL_COND_V(err != OK, String()); if (node->get_output_port_type(p_port) == VisualShaderNode::PORT_TYPE_SCALAR) { - code += "\tCOLOR.rgb = vec3( n_out" + itos(p_node) + "p" + itos(p_port) + " );\n"; + code += "\tCOLOR.rgb = vec3(n_out" + itos(p_node) + "p" + itos(p_port) + " );\n"; + } else if (node->get_output_port_type(p_port) == VisualShaderNode::PORT_TYPE_SCALAR_INT) { + code += "\tCOLOR.rgb = vec3(float(n_out" + itos(p_node) + "p" + itos(p_port) + "));\n"; } else if (node->get_output_port_type(p_port) == VisualShaderNode::PORT_TYPE_BOOLEAN) { - code += "\tCOLOR.rgb = vec3( n_out" + itos(p_node) + "p" + itos(p_port) + " ? 1.0 : 0.0 );\n"; + code += "\tCOLOR.rgb = vec3(n_out" + itos(p_node) + "p" + itos(p_port) + " ? 1.0 : 0.0);\n"; } else { code += "\tCOLOR.rgb = n_out" + itos(p_node) + "p" + itos(p_port) + ";\n"; } @@ -984,8 +1031,8 @@ bool VisualShader::_get(const StringName &p_name, Variant &r_ret) const { } return false; } -void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const { +void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const { //mode p_list->push_back(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Spatial,CanvasItem,Particles")); //render modes @@ -994,7 +1041,6 @@ void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const { Set<String> toggles; for (int i = 0; i < ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader_mode)).size(); i++) { - String mode = ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader_mode))[i]; int idx = 0; bool in_enum = false; @@ -1019,7 +1065,6 @@ void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const { } for (Map<String, String>::Element *E = blend_mode_enums.front(); E; E = E->next()) { - p_list->push_back(PropertyInfo(Variant::INT, "modes/" + E->key(), PROPERTY_HINT_ENUM, E->get())); } @@ -1112,24 +1157,40 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui inputs[i] = src_var; } else if (in_type == VisualShaderNode::PORT_TYPE_SCALAR && out_type == VisualShaderNode::PORT_TYPE_VECTOR) { inputs[i] = "dot(" + src_var + ", vec3(0.333333, 0.333333, 0.333333))"; + } else if (in_type == VisualShaderNode::PORT_TYPE_SCALAR_INT && out_type == VisualShaderNode::PORT_TYPE_VECTOR) { + inputs[i] = "dot(float(" + src_var + "), vec3(0.333333, 0.333333, 0.333333))"; } 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_VECTOR && out_type == VisualShaderNode::PORT_TYPE_SCALAR_INT) { + inputs[i] = "vec3(float(" + src_var + "))"; } else if (in_type == VisualShaderNode::PORT_TYPE_BOOLEAN && out_type == VisualShaderNode::PORT_TYPE_VECTOR) { 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_BOOLEAN && out_type == VisualShaderNode::PORT_TYPE_SCALAR_INT) { + inputs[i] = src_var + " > 0 ? true : false"; } else if (in_type == VisualShaderNode::PORT_TYPE_SCALAR && out_type == VisualShaderNode::PORT_TYPE_BOOLEAN) { inputs[i] = src_var + " ? 1.0 : 0.0"; + } else if (in_type == VisualShaderNode::PORT_TYPE_SCALAR_INT && out_type == VisualShaderNode::PORT_TYPE_BOOLEAN) { + inputs[i] = src_var + " ? 1 : 0"; } else if (in_type == VisualShaderNode::PORT_TYPE_VECTOR && out_type == VisualShaderNode::PORT_TYPE_BOOLEAN) { inputs[i] = "vec3(" + src_var + " ? 1.0 : 0.0)"; + } else if (in_type == VisualShaderNode::PORT_TYPE_SCALAR && out_type == VisualShaderNode::PORT_TYPE_SCALAR_INT) { + inputs[i] = "float(" + src_var + ")"; + } else if (in_type == VisualShaderNode::PORT_TYPE_SCALAR_INT && out_type == VisualShaderNode::PORT_TYPE_SCALAR) { + inputs[i] = "int(" + src_var + ")"; } } else { Variant defval = vsnode->get_input_port_default_value(i); - if (defval.get_type() == Variant::FLOAT || defval.get_type() == Variant::INT) { + if (defval.get_type() == Variant::FLOAT) { float val = defval; inputs[i] = "n_in" + itos(node) + "p" + itos(i); code += "\tfloat " + inputs[i] + " = " + vformat("%.5f", val) + ";\n"; + } else if (defval.get_type() == Variant::INT) { + int val = defval; + inputs[i] = "n_in" + itos(node) + "p" + itos(i); + code += "\tint " + inputs[i] + " = " + itos(val) + ";\n"; } else if (defval.get_type() == Variant::BOOL) { bool val = defval; inputs[i] = "n_in" + itos(node) + "p" + itos(i); @@ -1169,6 +1230,7 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui String var_name = "n_out" + itos(node) + "p" + itos(i); switch (vsnode->get_output_port_type(i)) { case VisualShaderNode::PORT_TYPE_SCALAR: outputs[i] = "float " + var_name; break; + case VisualShaderNode::PORT_TYPE_SCALAR_INT: outputs[i] = "int " + var_name; break; case VisualShaderNode::PORT_TYPE_VECTOR: outputs[i] = "vec3 " + var_name; break; case VisualShaderNode::PORT_TYPE_BOOLEAN: outputs[i] = "bool " + var_name; break; case VisualShaderNode::PORT_TYPE_TRANSFORM: outputs[i] = "mat4 " + var_name; break; @@ -1182,6 +1244,7 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui outputs[i] = "n_out" + itos(node) + "p" + itos(i); switch (vsnode->get_output_port_type(i)) { case VisualShaderNode::PORT_TYPE_SCALAR: code += String() + "\tfloat " + outputs[i] + ";\n"; break; + case VisualShaderNode::PORT_TYPE_SCALAR_INT: code += String() + "\tint " + outputs[i] + ";\n"; break; case VisualShaderNode::PORT_TYPE_VECTOR: code += String() + "\tvec3 " + outputs[i] + ";\n"; break; case VisualShaderNode::PORT_TYPE_BOOLEAN: code += String() + "\tbool " + outputs[i] + ";\n"; break; case VisualShaderNode::PORT_TYPE_TRANSFORM: code += String() + "\tmat4 " + outputs[i] + ";\n"; break; @@ -1411,6 +1474,9 @@ void VisualShader::_bind_methods() { ClassDB::bind_method(D_METHOD("get_node_connections", "type"), &VisualShader::_get_node_connections); + ClassDB::bind_method(D_METHOD("set_version", "version"), &VisualShader::set_version); + ClassDB::bind_method(D_METHOD("get_version"), &VisualShader::get_version); + ClassDB::bind_method(D_METHOD("set_graph_offset", "offset"), &VisualShader::set_graph_offset); ClassDB::bind_method(D_METHOD("get_graph_offset"), &VisualShader::get_graph_offset); @@ -1420,6 +1486,7 @@ void VisualShader::_bind_methods() { ClassDB::bind_method(D_METHOD("_input_type_changed"), &VisualShader::_input_type_changed); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "graph_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_graph_offset", "get_graph_offset"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "version", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_version", "get_version"); BIND_ENUM_CONSTANT(TYPE_VERTEX); BIND_ENUM_CONSTANT(TYPE_FRAGMENT); @@ -1575,7 +1642,7 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "delta", "DELTA" }, { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "lifetime", "LIFETIME" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "index", "float(INDEX)" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR_INT, "index", "INDEX" }, { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "emission_transform", "EMISSION_TRANSFORM" }, { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, @@ -1683,17 +1750,20 @@ String VisualShaderNodeInput::generate_code(Shader::Mode p_mode, VisualShader::T switch (get_output_port_type(0)) { case PORT_TYPE_SCALAR: { code = "\t" + p_output_vars[0] + " = 0.0;\n"; - } break; //default (none found) is scalar + } break; + case PORT_TYPE_SCALAR_INT: { + code = "\t" + p_output_vars[0] + " = 0;\n"; + } break; case PORT_TYPE_VECTOR: { code = "\t" + p_output_vars[0] + " = vec3(0.0);\n"; - } break; //default (none found) is scalar + } break; case PORT_TYPE_TRANSFORM: { code = "\t" + p_output_vars[0] + " = mat4( vec4(1.0,0.0,0.0,0.0), vec4(0.0,1.0,0.0,0.0), vec4(0.0,0.0,1.0,0.0), vec4(0.0,0.0,0.0,1.0) );\n"; - } break; //default (none found) is scalar + } break; case PORT_TYPE_BOOLEAN: { code = "\t" + p_output_vars[0] + " = false;\n"; } break; - default: + default: //default (none found) is scalar break; } } @@ -2625,6 +2695,9 @@ String VisualShaderNodeExpression::generate_code(Shader::Mode p_mode, VisualShad case PORT_TYPE_SCALAR: tk = "0.0"; break; + case PORT_TYPE_SCALAR_INT: + tk = "0"; + break; case PORT_TYPE_VECTOR: tk = "vec3(0.0, 0.0, 0.0)"; break; diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h index 1ee75a4cb7..450dcfa081 100644 --- a/scene/resources/visual_shader.h +++ b/scene/resources/visual_shader.h @@ -41,6 +41,10 @@ class VisualShaderNode; class VisualShader : public Shader { GDCLASS(VisualShader, Shader); + friend class VisualShaderNodeVersionChecker; + + String version = ""; + public: enum Type { TYPE_VERTEX, @@ -118,6 +122,11 @@ protected: void _get_property_list(List<PropertyInfo> *p_list) const; public: + void set_version(const String &p_version); + String get_version() const; + + void update_version(const String &p_new_version); + enum { NODE_ID_INVALID = -1, NODE_ID_OUTPUT = 0, @@ -182,6 +191,7 @@ protected: public: enum PortType { PORT_TYPE_SCALAR, + PORT_TYPE_SCALAR_INT, PORT_TYPE_VECTOR, PORT_TYPE_BOOLEAN, PORT_TYPE_TRANSFORM, diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index 2c0b83b5c3..2064ca10f3 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -30,66 +30,127 @@ #include "visual_shader_nodes.h" -////////////// Scalar +////////////// Scalar(Float) -String VisualShaderNodeScalarConstant::get_caption() const { - return "Scalar"; +String VisualShaderNodeFloatConstant::get_caption() const { + return "ScalarFloat"; } -int VisualShaderNodeScalarConstant::get_input_port_count() const { +int VisualShaderNodeFloatConstant::get_input_port_count() const { return 0; } -VisualShaderNodeScalarConstant::PortType VisualShaderNodeScalarConstant::get_input_port_type(int p_port) const { +VisualShaderNodeFloatConstant::PortType VisualShaderNodeFloatConstant::get_input_port_type(int p_port) const { return PORT_TYPE_SCALAR; } -String VisualShaderNodeScalarConstant::get_input_port_name(int p_port) const { +String VisualShaderNodeFloatConstant::get_input_port_name(int p_port) const { return String(); } -int VisualShaderNodeScalarConstant::get_output_port_count() const { +int VisualShaderNodeFloatConstant::get_output_port_count() const { return 1; } -VisualShaderNodeScalarConstant::PortType VisualShaderNodeScalarConstant::get_output_port_type(int p_port) const { +VisualShaderNodeFloatConstant::PortType VisualShaderNodeFloatConstant::get_output_port_type(int p_port) const { return PORT_TYPE_SCALAR; } -String VisualShaderNodeScalarConstant::get_output_port_name(int p_port) const { +String VisualShaderNodeFloatConstant::get_output_port_name(int p_port) const { return ""; //no output port means the editor will be used as port } -String VisualShaderNodeScalarConstant::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 VisualShaderNodeFloatConstant::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { return "\t" + p_output_vars[0] + " = " + vformat("%.6f", constant) + ";\n"; } -void VisualShaderNodeScalarConstant::set_constant(float p_value) { +void VisualShaderNodeFloatConstant::set_constant(float p_value) { constant = p_value; emit_changed(); } -float VisualShaderNodeScalarConstant::get_constant() const { +float VisualShaderNodeFloatConstant::get_constant() const { return constant; } -Vector<StringName> VisualShaderNodeScalarConstant::get_editable_properties() const { +Vector<StringName> VisualShaderNodeFloatConstant::get_editable_properties() const { Vector<StringName> props; props.push_back("constant"); return props; } -void VisualShaderNodeScalarConstant::_bind_methods() { +void VisualShaderNodeFloatConstant::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_constant", "value"), &VisualShaderNodeScalarConstant::set_constant); - ClassDB::bind_method(D_METHOD("get_constant"), &VisualShaderNodeScalarConstant::get_constant); + ClassDB::bind_method(D_METHOD("set_constant", "value"), &VisualShaderNodeFloatConstant::set_constant); + ClassDB::bind_method(D_METHOD("get_constant"), &VisualShaderNodeFloatConstant::get_constant); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "constant"), "set_constant", "get_constant"); } -VisualShaderNodeScalarConstant::VisualShaderNodeScalarConstant() { +VisualShaderNodeFloatConstant::VisualShaderNodeFloatConstant() { + constant = 0.0; +} + +////////////// Scalar(Int) + +String VisualShaderNodeIntConstant::get_caption() const { + return "ScalarInt"; +} + +int VisualShaderNodeIntConstant::get_input_port_count() const { + return 0; +} + +VisualShaderNodeIntConstant::PortType VisualShaderNodeIntConstant::get_input_port_type(int p_port) const { + return PORT_TYPE_SCALAR_INT; +} + +String VisualShaderNodeIntConstant::get_input_port_name(int p_port) const { + return String(); +} + +int VisualShaderNodeIntConstant::get_output_port_count() const { + return 1; +} + +VisualShaderNodeIntConstant::PortType VisualShaderNodeIntConstant::get_output_port_type(int p_port) const { + return PORT_TYPE_SCALAR_INT; +} + +String VisualShaderNodeIntConstant::get_output_port_name(int p_port) const { + return ""; //no output port means the editor will be used as port +} + +String VisualShaderNodeIntConstant::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + return "\t" + p_output_vars[0] + " = " + itos(constant) + ";\n"; +} + +void VisualShaderNodeIntConstant::set_constant(int p_value) { + constant = p_value; + emit_changed(); +} + +int VisualShaderNodeIntConstant::get_constant() const { + return constant; +} + +Vector<StringName> VisualShaderNodeIntConstant::get_editable_properties() const { + Vector<StringName> props; + props.push_back("constant"); + return props; +} + +void VisualShaderNodeIntConstant::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_constant", "value"), &VisualShaderNodeIntConstant::set_constant); + ClassDB::bind_method(D_METHOD("get_constant"), &VisualShaderNodeIntConstant::get_constant); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "constant"), "set_constant", "get_constant"); +} + +VisualShaderNodeIntConstant::VisualShaderNodeIntConstant() { constant = 0; } @@ -936,37 +997,37 @@ VisualShaderNodeCubemap::VisualShaderNodeCubemap() { simple_decl = false; } -////////////// Scalar Op +////////////// Float Op -String VisualShaderNodeScalarOp::get_caption() const { - return "ScalarOp"; +String VisualShaderNodeFloatOp::get_caption() const { + return "FloatOp"; } -int VisualShaderNodeScalarOp::get_input_port_count() const { +int VisualShaderNodeFloatOp::get_input_port_count() const { return 2; } -VisualShaderNodeScalarOp::PortType VisualShaderNodeScalarOp::get_input_port_type(int p_port) const { +VisualShaderNodeFloatOp::PortType VisualShaderNodeFloatOp::get_input_port_type(int p_port) const { return PORT_TYPE_SCALAR; } -String VisualShaderNodeScalarOp::get_input_port_name(int p_port) const { +String VisualShaderNodeFloatOp::get_input_port_name(int p_port) const { return p_port == 0 ? "a" : "b"; } -int VisualShaderNodeScalarOp::get_output_port_count() const { +int VisualShaderNodeFloatOp::get_output_port_count() const { return 1; } -VisualShaderNodeScalarOp::PortType VisualShaderNodeScalarOp::get_output_port_type(int p_port) const { +VisualShaderNodeFloatOp::PortType VisualShaderNodeFloatOp::get_output_port_type(int p_port) const { return PORT_TYPE_SCALAR; } -String VisualShaderNodeScalarOp::get_output_port_name(int p_port) const { +String VisualShaderNodeFloatOp::get_output_port_name(int p_port) const { return "op"; //no output port means the editor will be used as port } -String VisualShaderNodeScalarOp::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 VisualShaderNodeFloatOp::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 = "\t" + p_output_vars[0] + " = "; switch (op) { @@ -986,27 +1047,27 @@ String VisualShaderNodeScalarOp::generate_code(Shader::Mode p_mode, VisualShader return code; } -void VisualShaderNodeScalarOp::set_operator(Operator p_op) { +void VisualShaderNodeFloatOp::set_operator(Operator p_op) { op = p_op; emit_changed(); } -VisualShaderNodeScalarOp::Operator VisualShaderNodeScalarOp::get_operator() const { +VisualShaderNodeFloatOp::Operator VisualShaderNodeFloatOp::get_operator() const { return op; } -Vector<StringName> VisualShaderNodeScalarOp::get_editable_properties() const { +Vector<StringName> VisualShaderNodeFloatOp::get_editable_properties() const { Vector<StringName> props; props.push_back("operator"); return props; } -void VisualShaderNodeScalarOp::_bind_methods() { +void VisualShaderNodeFloatOp::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeScalarOp::set_operator); - ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeScalarOp::get_operator); + ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeFloatOp::set_operator); + ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeFloatOp::get_operator); ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Add,Sub,Multiply,Divide,Remainder,Power,Max,Min,Atan2,Step"), "set_operator", "get_operator"); @@ -1022,12 +1083,97 @@ void VisualShaderNodeScalarOp::_bind_methods() { BIND_ENUM_CONSTANT(OP_STEP); } -VisualShaderNodeScalarOp::VisualShaderNodeScalarOp() { +VisualShaderNodeFloatOp::VisualShaderNodeFloatOp() { op = OP_ADD; set_input_port_default_value(0, 0.0); set_input_port_default_value(1, 0.0); } +////////////// Integer Op + +String VisualShaderNodeIntOp::get_caption() const { + return "IntOp"; +} + +int VisualShaderNodeIntOp::get_input_port_count() const { + return 2; +} + +VisualShaderNodeIntOp::PortType VisualShaderNodeIntOp::get_input_port_type(int p_port) const { + return PORT_TYPE_SCALAR_INT; +} + +String VisualShaderNodeIntOp::get_input_port_name(int p_port) const { + return p_port == 0 ? "a" : "b"; +} + +int VisualShaderNodeIntOp::get_output_port_count() const { + return 1; +} + +VisualShaderNodeIntOp::PortType VisualShaderNodeIntOp::get_output_port_type(int p_port) const { + return PORT_TYPE_SCALAR_INT; +} + +String VisualShaderNodeIntOp::get_output_port_name(int p_port) const { + return "op"; //no output port means the editor will be used as port +} + +String VisualShaderNodeIntOp::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 = "\t" + p_output_vars[0] + " = "; + switch (op) { + + case OP_ADD: code += p_input_vars[0] + " + " + p_input_vars[1] + ";\n"; break; + case OP_SUB: code += p_input_vars[0] + " - " + p_input_vars[1] + ";\n"; break; + case OP_MUL: code += p_input_vars[0] + " * " + p_input_vars[1] + ";\n"; break; + case OP_DIV: code += p_input_vars[0] + " / " + p_input_vars[1] + ";\n"; break; + case OP_MOD: code += p_input_vars[0] + " % " + p_input_vars[1] + ";\n"; break; + case OP_MAX: code += "max(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break; + case OP_MIN: code += "min(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break; + } + + return code; +} + +void VisualShaderNodeIntOp::set_operator(Operator p_op) { + + op = p_op; + emit_changed(); +} + +VisualShaderNodeIntOp::Operator VisualShaderNodeIntOp::get_operator() const { + return op; +} + +Vector<StringName> VisualShaderNodeIntOp::get_editable_properties() const { + Vector<StringName> props; + props.push_back("operator"); + return props; +} + +void VisualShaderNodeIntOp::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeIntOp::set_operator); + ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeIntOp::get_operator); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Add,Sub,Multiply,Divide,Remainder,Max,Min"), "set_operator", "get_operator"); + + BIND_ENUM_CONSTANT(OP_ADD); + BIND_ENUM_CONSTANT(OP_SUB); + BIND_ENUM_CONSTANT(OP_MUL); + BIND_ENUM_CONSTANT(OP_DIV); + BIND_ENUM_CONSTANT(OP_MOD); + BIND_ENUM_CONSTANT(OP_MAX); + BIND_ENUM_CONSTANT(OP_MIN); +} + +VisualShaderNodeIntOp::VisualShaderNodeIntOp() { + op = OP_ADD; + set_input_port_default_value(0, 0); + set_input_port_default_value(1, 0); +} + ////////////// Vector Op String VisualShaderNodeVectorOp::get_caption() const { @@ -1462,37 +1608,37 @@ VisualShaderNodeTransformVecMult::VisualShaderNodeTransformVecMult() { set_input_port_default_value(1, Vector3()); } -////////////// Scalar Func +////////////// Float Func -String VisualShaderNodeScalarFunc::get_caption() const { - return "ScalarFunc"; +String VisualShaderNodeFloatFunc::get_caption() const { + return "FloatFunc"; } -int VisualShaderNodeScalarFunc::get_input_port_count() const { +int VisualShaderNodeFloatFunc::get_input_port_count() const { return 1; } -VisualShaderNodeScalarFunc::PortType VisualShaderNodeScalarFunc::get_input_port_type(int p_port) const { +VisualShaderNodeFloatFunc::PortType VisualShaderNodeFloatFunc::get_input_port_type(int p_port) const { return PORT_TYPE_SCALAR; } -String VisualShaderNodeScalarFunc::get_input_port_name(int p_port) const { +String VisualShaderNodeFloatFunc::get_input_port_name(int p_port) const { return ""; } -int VisualShaderNodeScalarFunc::get_output_port_count() const { +int VisualShaderNodeFloatFunc::get_output_port_count() const { return 1; } -VisualShaderNodeScalarFunc::PortType VisualShaderNodeScalarFunc::get_output_port_type(int p_port) const { +VisualShaderNodeFloatFunc::PortType VisualShaderNodeFloatFunc::get_output_port_type(int p_port) const { return PORT_TYPE_SCALAR; } -String VisualShaderNodeScalarFunc::get_output_port_name(int p_port) const { +String VisualShaderNodeFloatFunc::get_output_port_name(int p_port) const { return ""; //no output port means the editor will be used as port } -String VisualShaderNodeScalarFunc::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 VisualShaderNodeFloatFunc::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 { static const char *scalar_func_id[FUNC_ONEMINUS + 1] = { "sin($)", @@ -1532,27 +1678,27 @@ String VisualShaderNodeScalarFunc::generate_code(Shader::Mode p_mode, VisualShad return "\t" + p_output_vars[0] + " = " + String(scalar_func_id[func]).replace("$", p_input_vars[0]) + ";\n"; } -void VisualShaderNodeScalarFunc::set_function(Function p_func) { +void VisualShaderNodeFloatFunc::set_function(Function p_func) { func = p_func; emit_changed(); } -VisualShaderNodeScalarFunc::Function VisualShaderNodeScalarFunc::get_function() const { +VisualShaderNodeFloatFunc::Function VisualShaderNodeFloatFunc::get_function() const { return func; } -Vector<StringName> VisualShaderNodeScalarFunc::get_editable_properties() const { +Vector<StringName> VisualShaderNodeFloatFunc::get_editable_properties() const { Vector<StringName> props; props.push_back("function"); return props; } -void VisualShaderNodeScalarFunc::_bind_methods() { +void VisualShaderNodeFloatFunc::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeScalarFunc::set_function); - ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeScalarFunc::get_function); + ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeFloatFunc::set_function); + ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeFloatFunc::get_function); ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Sin,Cos,Tan,ASin,ACos,ATan,SinH,CosH,TanH,Log,Exp,Sqrt,Abs,Sign,Floor,Round,Ceil,Frac,Saturate,Negate,ACosH,ASinH,ATanH,Degrees,Exp2,InverseSqrt,Log2,Radians,Reciprocal,RoundEven,Trunc,OneMinus"), "set_function", "get_function"); @@ -1590,11 +1736,108 @@ void VisualShaderNodeScalarFunc::_bind_methods() { BIND_ENUM_CONSTANT(FUNC_ONEMINUS); } -VisualShaderNodeScalarFunc::VisualShaderNodeScalarFunc() { +VisualShaderNodeFloatFunc::VisualShaderNodeFloatFunc() { func = FUNC_SIGN; set_input_port_default_value(0, 0.0); } +////////////// Int Func + +String VisualShaderNodeIntFunc::get_caption() const { + return "IntFunc"; +} + +int VisualShaderNodeIntFunc::get_input_port_count() const { + if (func == FUNC_CLAMP) { + return 3; + } + return 1; +} + +VisualShaderNodeIntFunc::PortType VisualShaderNodeIntFunc::get_input_port_type(int p_port) const { + return PORT_TYPE_SCALAR_INT; +} + +String VisualShaderNodeIntFunc::get_input_port_name(int p_port) const { + if (func == FUNC_CLAMP) { + if (p_port == 0) { + return ""; + } else if (p_port == 1) { + return "min"; + } else if (p_port == 2) { + return "max"; + } + } + return ""; +} + +int VisualShaderNodeIntFunc::get_output_port_count() const { + return 1; +} + +VisualShaderNodeIntFunc::PortType VisualShaderNodeIntFunc::get_output_port_type(int p_port) const { + return PORT_TYPE_SCALAR_INT; +} + +String VisualShaderNodeIntFunc::get_output_port_name(int p_port) const { + return ""; //no output port means the editor will be used as port +} + +String VisualShaderNodeIntFunc::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 { + if (func == FUNC_CLAMP) { + return "\t" + p_output_vars[0] + " = clamp(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; + } + + static const char *int_func_id[FUNC_SIGN + 1] = { + "abs($)", + "", + "-($)", + "sign($)" + }; + + return "\t" + p_output_vars[0] + " = " + String(int_func_id[func]).replace("$", p_input_vars[0]) + ";\n"; +} + +void VisualShaderNodeIntFunc::set_function(Function p_func) { + if (func != p_func) { + if (p_func == FUNC_CLAMP) { + set_input_port_default_value(1, 0); + set_input_port_default_value(2, 0); + } + } + func = p_func; + emit_changed(); +} + +VisualShaderNodeIntFunc::Function VisualShaderNodeIntFunc::get_function() const { + + return func; +} + +Vector<StringName> VisualShaderNodeIntFunc::get_editable_properties() const { + Vector<StringName> props; + props.push_back("function"); + return props; +} + +void VisualShaderNodeIntFunc::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeIntFunc::set_function); + ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeIntFunc::get_function); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Abs,Clamp,Negate,Sign"), "set_function", "get_function"); + + BIND_ENUM_CONSTANT(FUNC_ABS); + BIND_ENUM_CONSTANT(FUNC_CLAMP); + BIND_ENUM_CONSTANT(FUNC_NEGATE); + BIND_ENUM_CONSTANT(FUNC_SIGN); +} + +VisualShaderNodeIntFunc::VisualShaderNodeIntFunc() { + func = FUNC_SIGN; + set_input_port_default_value(0, 0); +} + ////////////// Vector Func String VisualShaderNodeVectorFunc::get_caption() const { @@ -3008,37 +3251,37 @@ VisualShaderNodeTransformDecompose::VisualShaderNodeTransformDecompose() { set_input_port_default_value(0, Transform()); } -////////////// Scalar Uniform +////////////// Float Uniform -String VisualShaderNodeScalarUniform::get_caption() const { - return "ScalarUniform"; +String VisualShaderNodeFloatUniform::get_caption() const { + return "FloatUniform"; } -int VisualShaderNodeScalarUniform::get_input_port_count() const { +int VisualShaderNodeFloatUniform::get_input_port_count() const { return 0; } -VisualShaderNodeScalarUniform::PortType VisualShaderNodeScalarUniform::get_input_port_type(int p_port) const { +VisualShaderNodeFloatUniform::PortType VisualShaderNodeFloatUniform::get_input_port_type(int p_port) const { return PORT_TYPE_SCALAR; } -String VisualShaderNodeScalarUniform::get_input_port_name(int p_port) const { +String VisualShaderNodeFloatUniform::get_input_port_name(int p_port) const { return String(); } -int VisualShaderNodeScalarUniform::get_output_port_count() const { +int VisualShaderNodeFloatUniform::get_output_port_count() const { return 1; } -VisualShaderNodeScalarUniform::PortType VisualShaderNodeScalarUniform::get_output_port_type(int p_port) const { +VisualShaderNodeFloatUniform::PortType VisualShaderNodeFloatUniform::get_output_port_type(int p_port) const { return PORT_TYPE_SCALAR; } -String VisualShaderNodeScalarUniform::get_output_port_name(int p_port) const { +String VisualShaderNodeFloatUniform::get_output_port_name(int p_port) const { return ""; //no output port means the editor will be used as port } -String VisualShaderNodeScalarUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { +String VisualShaderNodeFloatUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { if (hint == HINT_RANGE) { return "uniform float " + get_uniform_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ");\n"; } else if (hint == HINT_RANGE_STEP) { @@ -3047,58 +3290,58 @@ String VisualShaderNodeScalarUniform::generate_global(Shader::Mode p_mode, Visua return "uniform float " + get_uniform_name() + ";\n"; } -String VisualShaderNodeScalarUniform::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 VisualShaderNodeFloatUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n"; } -void VisualShaderNodeScalarUniform::set_hint(Hint p_hint) { +void VisualShaderNodeFloatUniform::set_hint(Hint p_hint) { hint = p_hint; emit_changed(); } -VisualShaderNodeScalarUniform::Hint VisualShaderNodeScalarUniform::get_hint() const { +VisualShaderNodeFloatUniform::Hint VisualShaderNodeFloatUniform::get_hint() const { return hint; } -void VisualShaderNodeScalarUniform::set_min(float p_value) { +void VisualShaderNodeFloatUniform::set_min(float p_value) { hint_range_min = p_value; emit_changed(); } -float VisualShaderNodeScalarUniform::get_min() const { +float VisualShaderNodeFloatUniform::get_min() const { return hint_range_min; } -void VisualShaderNodeScalarUniform::set_max(float p_value) { +void VisualShaderNodeFloatUniform::set_max(float p_value) { hint_range_max = p_value; emit_changed(); } -float VisualShaderNodeScalarUniform::get_max() const { +float VisualShaderNodeFloatUniform::get_max() const { return hint_range_max; } -void VisualShaderNodeScalarUniform::set_step(float p_value) { +void VisualShaderNodeFloatUniform::set_step(float p_value) { hint_range_step = p_value; emit_changed(); } -float VisualShaderNodeScalarUniform::get_step() const { +float VisualShaderNodeFloatUniform::get_step() const { return hint_range_step; } -void VisualShaderNodeScalarUniform::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_hint", "hint"), &VisualShaderNodeScalarUniform::set_hint); - ClassDB::bind_method(D_METHOD("get_hint"), &VisualShaderNodeScalarUniform::get_hint); +void VisualShaderNodeFloatUniform::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_hint", "hint"), &VisualShaderNodeFloatUniform::set_hint); + ClassDB::bind_method(D_METHOD("get_hint"), &VisualShaderNodeFloatUniform::get_hint); - ClassDB::bind_method(D_METHOD("set_min", "value"), &VisualShaderNodeScalarUniform::set_min); - ClassDB::bind_method(D_METHOD("get_min"), &VisualShaderNodeScalarUniform::get_min); + ClassDB::bind_method(D_METHOD("set_min", "value"), &VisualShaderNodeFloatUniform::set_min); + ClassDB::bind_method(D_METHOD("get_min"), &VisualShaderNodeFloatUniform::get_min); - ClassDB::bind_method(D_METHOD("set_max", "value"), &VisualShaderNodeScalarUniform::set_max); - ClassDB::bind_method(D_METHOD("get_max"), &VisualShaderNodeScalarUniform::get_max); + ClassDB::bind_method(D_METHOD("set_max", "value"), &VisualShaderNodeFloatUniform::set_max); + ClassDB::bind_method(D_METHOD("get_max"), &VisualShaderNodeFloatUniform::get_max); - ClassDB::bind_method(D_METHOD("set_step", "value"), &VisualShaderNodeScalarUniform::set_step); - ClassDB::bind_method(D_METHOD("get_step"), &VisualShaderNodeScalarUniform::get_step); + ClassDB::bind_method(D_METHOD("set_step", "value"), &VisualShaderNodeFloatUniform::set_step); + ClassDB::bind_method(D_METHOD("get_step"), &VisualShaderNodeFloatUniform::get_step); ADD_PROPERTY(PropertyInfo(Variant::INT, "hint", PROPERTY_HINT_ENUM, "None,Range,Range+Step"), "set_hint", "get_hint"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "min"), "set_min", "get_min"); @@ -3110,7 +3353,7 @@ void VisualShaderNodeScalarUniform::_bind_methods() { BIND_ENUM_CONSTANT(HINT_RANGE_STEP); } -Vector<StringName> VisualShaderNodeScalarUniform::get_editable_properties() const { +Vector<StringName> VisualShaderNodeFloatUniform::get_editable_properties() const { Vector<StringName> props; props.push_back("hint"); if (hint == HINT_RANGE || hint == HINT_RANGE_STEP) { @@ -3123,13 +3366,135 @@ Vector<StringName> VisualShaderNodeScalarUniform::get_editable_properties() cons return props; } -VisualShaderNodeScalarUniform::VisualShaderNodeScalarUniform() { +VisualShaderNodeFloatUniform::VisualShaderNodeFloatUniform() { hint = HINT_NONE; hint_range_min = 0.0; hint_range_max = 1.0; hint_range_step = 0.1; } +////////////// Integer Uniform + +String VisualShaderNodeIntUniform::get_caption() const { + return "IntUniform"; +} + +int VisualShaderNodeIntUniform::get_input_port_count() const { + return 0; +} + +VisualShaderNodeIntUniform::PortType VisualShaderNodeIntUniform::get_input_port_type(int p_port) const { + return PORT_TYPE_SCALAR_INT; +} + +String VisualShaderNodeIntUniform::get_input_port_name(int p_port) const { + return String(); +} + +int VisualShaderNodeIntUniform::get_output_port_count() const { + return 1; +} + +VisualShaderNodeIntUniform::PortType VisualShaderNodeIntUniform::get_output_port_type(int p_port) const { + return PORT_TYPE_SCALAR_INT; +} + +String VisualShaderNodeIntUniform::get_output_port_name(int p_port) const { + return ""; //no output port means the editor will be used as port +} + +String VisualShaderNodeIntUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + if (hint == HINT_RANGE) { + return "uniform int " + get_uniform_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ");\n"; + } else if (hint == HINT_RANGE_STEP) { + return "uniform int " + get_uniform_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ", " + rtos(hint_range_step) + ");\n"; + } + return "uniform int " + get_uniform_name() + ";\n"; +} + +String VisualShaderNodeIntUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n"; +} + +void VisualShaderNodeIntUniform::set_hint(Hint p_hint) { + hint = p_hint; + emit_changed(); +} + +VisualShaderNodeIntUniform::Hint VisualShaderNodeIntUniform::get_hint() const { + return hint; +} + +void VisualShaderNodeIntUniform::set_min(int p_value) { + hint_range_min = p_value; + emit_changed(); +} + +int VisualShaderNodeIntUniform::get_min() const { + return hint_range_min; +} + +void VisualShaderNodeIntUniform::set_max(int p_value) { + hint_range_max = p_value; + emit_changed(); +} + +int VisualShaderNodeIntUniform::get_max() const { + return hint_range_max; +} + +void VisualShaderNodeIntUniform::set_step(int p_value) { + hint_range_step = p_value; + emit_changed(); +} + +int VisualShaderNodeIntUniform::get_step() const { + return hint_range_step; +} + +void VisualShaderNodeIntUniform::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_hint", "hint"), &VisualShaderNodeIntUniform::set_hint); + ClassDB::bind_method(D_METHOD("get_hint"), &VisualShaderNodeIntUniform::get_hint); + + ClassDB::bind_method(D_METHOD("set_min", "value"), &VisualShaderNodeIntUniform::set_min); + ClassDB::bind_method(D_METHOD("get_min"), &VisualShaderNodeIntUniform::get_min); + + ClassDB::bind_method(D_METHOD("set_max", "value"), &VisualShaderNodeIntUniform::set_max); + ClassDB::bind_method(D_METHOD("get_max"), &VisualShaderNodeIntUniform::get_max); + + ClassDB::bind_method(D_METHOD("set_step", "value"), &VisualShaderNodeIntUniform::set_step); + ClassDB::bind_method(D_METHOD("get_step"), &VisualShaderNodeIntUniform::get_step); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "hint", PROPERTY_HINT_ENUM, "None,Range,Range+Step"), "set_hint", "get_hint"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "min"), "set_min", "get_min"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "max"), "set_max", "get_max"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "step"), "set_step", "get_step"); + + BIND_ENUM_CONSTANT(HINT_NONE); + BIND_ENUM_CONSTANT(HINT_RANGE); + BIND_ENUM_CONSTANT(HINT_RANGE_STEP); +} + +Vector<StringName> VisualShaderNodeIntUniform::get_editable_properties() const { + Vector<StringName> props; + props.push_back("hint"); + if (hint == HINT_RANGE || hint == HINT_RANGE_STEP) { + props.push_back("min"); + props.push_back("max"); + } + if (hint == HINT_RANGE_STEP) { + props.push_back("step"); + } + return props; +} + +VisualShaderNodeIntUniform::VisualShaderNodeIntUniform() { + hint = HINT_NONE; + hint_range_min = 0; + hint_range_max = 100; + hint_range_step = 1; +} + ////////////// Boolean Uniform String VisualShaderNodeBooleanUniform::get_caption() const { @@ -3968,6 +4333,8 @@ VisualShaderNodeCompare::PortType VisualShaderNodeCompare::get_input_port_type(i switch (ctype) { case CTYPE_SCALAR: return PORT_TYPE_SCALAR; + case CTYPE_SCALAR_INT: + return PORT_TYPE_SCALAR_INT; case CTYPE_VECTOR: return PORT_TYPE_VECTOR; case CTYPE_BOOLEAN: @@ -4046,10 +4413,14 @@ String VisualShaderNodeCompare::generate_code(Shader::Mode p_mode, VisualShader: } else if (func == FUNC_NOT_EQUAL) { code += "\t" + p_output_vars[0] + " = !(abs(" + p_input_vars[0] + " - " + p_input_vars[1] + ") < " + p_input_vars[2] + ");"; } else { - code += "\t" + p_output_vars[0] + " = " + (p_input_vars[0] + "$" + p_input_vars[1]).replace("$", ops[func]) + ";\n"; + code += "\t" + p_output_vars[0] + " = " + (p_input_vars[0] + " $ " + p_input_vars[1]).replace("$", ops[func]) + ";\n"; } break; + case CTYPE_SCALAR_INT: + code += "\t" + p_output_vars[0] + " = " + (p_input_vars[0] + " $ " + p_input_vars[1]).replace("$", ops[func]) + ";\n"; + break; + case CTYPE_VECTOR: code += "\t{\n"; code += "\t\tbvec3 _bv = " + String(funcs[func]).replace("$", p_input_vars[0] + ", " + p_input_vars[1]) + ";\n"; @@ -4085,6 +4456,11 @@ void VisualShaderNodeCompare::set_comparison_type(ComparisonType p_type) { set_input_port_default_value(1, 0.0); simple_decl = true; break; + case CTYPE_SCALAR_INT: + set_input_port_default_value(0, 0); + set_input_port_default_value(1, 0); + simple_decl = true; + break; case CTYPE_VECTOR: set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0)); @@ -4151,11 +4527,12 @@ void VisualShaderNodeCompare::_bind_methods() { ClassDB::bind_method(D_METHOD("set_condition", "condition"), &VisualShaderNodeCompare::set_condition); ClassDB::bind_method(D_METHOD("get_condition"), &VisualShaderNodeCompare::get_condition); - ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, "Scalar,Vector,Boolean,Transform"), "set_comparison_type", "get_comparison_type"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, "Float,Int,Vector,Boolean,Transform"), "set_comparison_type", "get_comparison_type"); ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "a == b,a != b,a > b,a >= b,a < b,a <= b"), "set_function", "get_function"); ADD_PROPERTY(PropertyInfo(Variant::INT, "condition", PROPERTY_HINT_ENUM, "All,Any"), "set_condition", "get_condition"); BIND_ENUM_CONSTANT(CTYPE_SCALAR); + BIND_ENUM_CONSTANT(CTYPE_SCALAR_INT); BIND_ENUM_CONSTANT(CTYPE_VECTOR); BIND_ENUM_CONSTANT(CTYPE_BOOLEAN); BIND_ENUM_CONSTANT(CTYPE_TRANSFORM); diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h index 85782bc509..035e39230c 100644 --- a/scene/resources/visual_shader_nodes.h +++ b/scene/resources/visual_shader_nodes.h @@ -37,8 +37,8 @@ /// CONSTANTS /////////////////////////////////////// -class VisualShaderNodeScalarConstant : public VisualShaderNode { - GDCLASS(VisualShaderNodeScalarConstant, VisualShaderNode); +class VisualShaderNodeFloatConstant : public VisualShaderNode { + GDCLASS(VisualShaderNodeFloatConstant, VisualShaderNode); float constant; protected: @@ -62,7 +62,37 @@ public: virtual Vector<StringName> get_editable_properties() const; - VisualShaderNodeScalarConstant(); + VisualShaderNodeFloatConstant(); +}; + +/////////////////////////////////////// + +class VisualShaderNodeIntConstant : public VisualShaderNode { + GDCLASS(VisualShaderNodeIntConstant, VisualShaderNode); + int constant; + +protected: + static void _bind_methods(); + +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; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + + void set_constant(int p_value); + int get_constant() const; + + virtual Vector<StringName> get_editable_properties() const; + + VisualShaderNodeIntConstant(); }; /////////////////////////////////////// @@ -314,8 +344,8 @@ VARIANT_ENUM_CAST(VisualShaderNodeCubemap::Source) /// OPS /////////////////////////////////////// -class VisualShaderNodeScalarOp : public VisualShaderNode { - GDCLASS(VisualShaderNodeScalarOp, VisualShaderNode); +class VisualShaderNodeFloatOp : public VisualShaderNode { + GDCLASS(VisualShaderNodeFloatOp, VisualShaderNode); public: enum Operator { @@ -354,10 +384,52 @@ public: virtual Vector<StringName> get_editable_properties() const; - VisualShaderNodeScalarOp(); + VisualShaderNodeFloatOp(); }; -VARIANT_ENUM_CAST(VisualShaderNodeScalarOp::Operator) +VARIANT_ENUM_CAST(VisualShaderNodeFloatOp::Operator) + +class VisualShaderNodeIntOp : public VisualShaderNode { + GDCLASS(VisualShaderNodeIntOp, VisualShaderNode); + +public: + enum Operator { + OP_ADD, + OP_SUB, + OP_MUL, + OP_DIV, + OP_MOD, + OP_MAX, + OP_MIN, + }; + +protected: + Operator op; + + static void _bind_methods(); + +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; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + + void set_operator(Operator p_op); + Operator get_operator() const; + + virtual Vector<StringName> get_editable_properties() const; + + VisualShaderNodeIntOp(); +}; + +VARIANT_ENUM_CAST(VisualShaderNodeIntOp::Operator) class VisualShaderNodeVectorOp : public VisualShaderNode { GDCLASS(VisualShaderNodeVectorOp, VisualShaderNode); @@ -539,11 +611,11 @@ public: VARIANT_ENUM_CAST(VisualShaderNodeTransformVecMult::Operator) /////////////////////////////////////// -/// SCALAR FUNC +/// FLOAT FUNC /////////////////////////////////////// -class VisualShaderNodeScalarFunc : public VisualShaderNode { - GDCLASS(VisualShaderNodeScalarFunc, VisualShaderNode); +class VisualShaderNodeFloatFunc : public VisualShaderNode { + GDCLASS(VisualShaderNodeFloatFunc, VisualShaderNode); public: enum Function { @@ -604,10 +676,53 @@ public: virtual Vector<StringName> get_editable_properties() const; - VisualShaderNodeScalarFunc(); + VisualShaderNodeFloatFunc(); +}; + +VARIANT_ENUM_CAST(VisualShaderNodeFloatFunc::Function) + +/////////////////////////////////////// +/// INT FUNC +/////////////////////////////////////// + +class VisualShaderNodeIntFunc : public VisualShaderNode { + GDCLASS(VisualShaderNodeIntFunc, VisualShaderNode); + +public: + enum Function { + FUNC_ABS, + FUNC_CLAMP, + FUNC_NEGATE, + FUNC_SIGN, + }; + +protected: + Function func; + + static void _bind_methods(); + +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; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + + void set_function(Function p_func); + Function get_function() const; + + virtual Vector<StringName> get_editable_properties() const; + + VisualShaderNodeIntFunc(); }; -VARIANT_ENUM_CAST(VisualShaderNodeScalarFunc::Function) +VARIANT_ENUM_CAST(VisualShaderNodeIntFunc::Function) /////////////////////////////////////// /// VECTOR FUNC @@ -1297,8 +1412,8 @@ public: /// UNIFORMS /////////////////////////////////////// -class VisualShaderNodeScalarUniform : public VisualShaderNodeUniform { - GDCLASS(VisualShaderNodeScalarUniform, VisualShaderNodeUniform); +class VisualShaderNodeFloatUniform : public VisualShaderNodeUniform { + GDCLASS(VisualShaderNodeFloatUniform, VisualShaderNodeUniform); public: enum Hint { @@ -1344,10 +1459,62 @@ public: virtual Vector<StringName> get_editable_properties() const; - VisualShaderNodeScalarUniform(); + VisualShaderNodeFloatUniform(); +}; + +VARIANT_ENUM_CAST(VisualShaderNodeFloatUniform::Hint) + +class VisualShaderNodeIntUniform : public VisualShaderNodeUniform { + GDCLASS(VisualShaderNodeIntUniform, VisualShaderNodeUniform); + +public: + enum Hint { + HINT_NONE, + HINT_RANGE, + HINT_RANGE_STEP, + }; + +private: + Hint hint; + int hint_range_min; + int hint_range_max; + int hint_range_step; + +protected: + static void _bind_methods(); + +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_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) 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; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + + void set_hint(Hint p_hint); + Hint get_hint() const; + + void set_min(int p_value); + int get_min() const; + + void set_max(int p_value); + int get_max() const; + + void set_step(int p_value); + int get_step() const; + + virtual Vector<StringName> get_editable_properties() const; + + VisualShaderNodeIntUniform(); }; -VARIANT_ENUM_CAST(VisualShaderNodeScalarUniform::Hint) +VARIANT_ENUM_CAST(VisualShaderNodeIntUniform::Hint) /////////////////////////////////////// @@ -1669,9 +1836,10 @@ class VisualShaderNodeCompare : public VisualShaderNode { public: enum ComparisonType { CTYPE_SCALAR, + CTYPE_SCALAR_INT, CTYPE_VECTOR, CTYPE_BOOLEAN, - CTYPE_TRANSFORM + CTYPE_TRANSFORM, }; enum Function { diff --git a/servers/navigation_server.cpp b/servers/navigation_server.cpp index f31795fb35..f2b727ac47 100644 --- a/servers/navigation_server.cpp +++ b/servers/navigation_server.cpp @@ -75,7 +75,7 @@ void NavigationServer::_bind_methods() { ClassDB::bind_method(D_METHOD("free", "object"), &NavigationServer::free); ClassDB::bind_method(D_METHOD("set_active", "active"), &NavigationServer::set_active); - ClassDB::bind_method(D_METHOD("step", "delta_time"), &NavigationServer::step); + ClassDB::bind_method(D_METHOD("process", "delta_time"), &NavigationServer::process); } const NavigationServer *NavigationServer::get_singleton() { diff --git a/servers/navigation_server.h b/servers/navigation_server.h index d4d95d72d4..2587e53ab2 100644 --- a/servers/navigation_server.h +++ b/servers/navigation_server.h @@ -175,9 +175,11 @@ public: /// Control activation of this server. virtual void set_active(bool p_active) const = 0; - /// Step the server - /// NOTE: This function is not Threadsafe and MUST be called in single thread. - virtual void step(real_t delta_time) = 0; + /// Process the collision avoidance agents. + /// The result of this process is needed by the physics server, + /// so this must be called in the main thread. + /// Note: This function is not thread safe. + virtual void process(real_t delta_time) = 0; NavigationServer(); virtual ~NavigationServer(); diff --git a/servers/visual/rasterizer_rd/rasterizer_scene_high_end_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_scene_high_end_rd.cpp index a33c94fbcd..dd6bece11d 100644 --- a/servers/visual/rasterizer_rd/rasterizer_scene_high_end_rd.cpp +++ b/servers/visual/rasterizer_rd/rasterizer_scene_high_end_rd.cpp @@ -1894,8 +1894,16 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor if (draw_sky) { RENDER_TIMESTAMP("Render Sky"); + + CameraMatrix projection = p_cam_projection; + if (p_reflection_probe.is_valid()) { + CameraMatrix correction; + correction.set_depth_correction(true); + projection = correction * p_cam_projection; + } + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(opaque_framebuffer, RD::INITIAL_ACTION_CONTINUE, can_continue ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, can_continue ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ); - _draw_sky(draw_list, RD::get_singleton()->framebuffer_get_format(opaque_framebuffer), p_environment, p_cam_projection, p_cam_transform, 1.0); + _draw_sky(draw_list, RD::get_singleton()->framebuffer_get_format(opaque_framebuffer), p_environment, projection, p_cam_transform, 1.0); RD::get_singleton()->draw_list_end(); if (using_separate_specular && !can_continue) { |