diff options
68 files changed, 533 insertions, 262 deletions
diff --git a/core/project_settings.cpp b/core/project_settings.cpp index 99a23bbee1..5dedff3a71 100644 --- a/core/project_settings.cpp +++ b/core/project_settings.cpp @@ -288,9 +288,28 @@ void ProjectSettings::_convert_to_last_version() { } } +/* + * This method is responsible for loading a project.godot file and/or data file + * using the following merit order: + * - If using NetworkClient, try to lookup project file or fail. + * - If --main-pack was passed by the user (`p_main_pack`), load it or fail. + * - Search for .pck file matching binary name. There are two possibilities: + * o exec_path.get_basename() + '.pck' (e.g. 'win_game.exe' -> 'win_game.pck') + * o exec_path + '.pck' (e.g. 'linux_game' -> 'linux_game.pck') + * For each tentative, if the file exists, load it or fail. + * - On relevant platforms (Android/iOS), lookup project file in OS resource path. + * If found, load it or fail. + * - Lookup project file in passed `p_path` (--path passed by the user), i.e. we + * are running from source code. + * If not found and `p_upwards` is true (--upwards passed by the user), look for + * project files in parent folders up to the system root (used to run a game + * from command line while in a subfolder). + * If a project file is found, load it or fail. + * If nothing was found, error out. + */ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bool p_upwards) { - //If looking for files in network, just use network! + // If looking for files in a network client, use it directly if (FileAccessNetworkClient::get_singleton()) { @@ -302,9 +321,7 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bo return err; } - String exec_path = OS::get_singleton()->get_executable_path(); - - //Attempt with a passed main pack first + // Attempt with a user-defined main pack first if (p_main_pack != "") { @@ -320,25 +337,39 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bo return err; } - //Attempt with execname.pck + // Attempt with exec_name.pck + // (This is the usual case when distributing a Godot game.) + + // Based on the OS, it can be the exec path + '.pck' (Linux w/o extension, macOS in .app bundle) + // or the exec path's basename + '.pck' (Windows). + // We need to test both possibilities as extensions for Linux binaries are optional + // (so both 'mygame.bin' and 'mygame' should be able to find 'mygame.pck'). + + String exec_path = OS::get_singleton()->get_executable_path(); + if (exec_path != "") { bool found = false; - // get our filename without our path (note, using exec_path.get_file before get_basename anymore because not all file systems have dots in their file names!) - String filebase_name = exec_path.get_file().get_basename(); + String exec_dir = exec_path.get_base_dir(); + String exec_filename = exec_path.get_file(); + String exec_basename = exec_filename.get_basename(); + + // Try to load data pack at the location of the executable + // As mentioned above, we have two potential names to attempt - // try to open at the location of executable - String datapack_name = exec_path.get_base_dir().plus_file(filebase_name) + ".pck"; - if (_load_resource_pack(datapack_name)) { + if (_load_resource_pack(exec_dir.plus_file(exec_basename + ".pck")) || + _load_resource_pack(exec_dir.plus_file(exec_filename + ".pck"))) { found = true; } else { - datapack_name = filebase_name + ".pck"; - if (_load_resource_pack(datapack_name)) { + // If we couldn't find them next to the executable, we attempt + // the current working directory. Same story, two tests. + if (_load_resource_pack(exec_basename + ".pck") || + _load_resource_pack(exec_filename + ".pck")) { found = true; } } - // if we opened our package, try and load our project... + // If we opened our package, try and load our project if (found) { Error err = _load_settings_text_or_binary("res://project.godot", "res://project.binary"); if (err == OK) { @@ -350,17 +381,15 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bo } } - //Try to use the filesystem for files, according to OS. (only Android -when reading from pck- and iOS use this) - if (OS::get_singleton()->get_resource_dir() != "") { - //OS will call Globals->get_resource_path which will be empty if not overridden! - //if the OS would rather use somewhere else, then it will not be empty. + // Try to use the filesystem for files, according to OS. (only Android -when reading from pck- and iOS use this) + if (OS::get_singleton()->get_resource_dir() != "") { + // OS will call ProjectSettings->get_resource_path which will be empty if not overridden! + // If the OS would rather use a specific location, then it will not be empty. resource_path = OS::get_singleton()->get_resource_dir().replace("\\", "/"); - if (resource_path.length() && resource_path[resource_path.length() - 1] == '/') + if (resource_path != "" && resource_path[resource_path.length() - 1] == '/') { resource_path = resource_path.substr(0, resource_path.length() - 1); // chop end - - // data.pck and data.zip are deprecated and no longer supported, apologies. - // make sure this is loaded from the resource path + } Error err = _load_settings_text_or_binary("res://project.godot", "res://project.binary"); if (err == OK) { @@ -371,21 +400,19 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bo return err; } - //Nothing was found, try to find a project.godot somewhere! + // Nothing was found, try to find a project file in provided path (`p_path`) + // or, if requested (`p_upwards`) in parent directories. DirAccess *d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); ERR_FAIL_COND_V(!d, ERR_CANT_CREATE); - d->change_dir(p_path); - String candidate = d->get_current_dir(); String current_dir = d->get_current_dir(); - + String candidate = current_dir; bool found = false; Error err; while (true) { - err = _load_settings_text_or_binary(current_dir.plus_file("project.godot"), current_dir.plus_file("project.binary")); if (err == OK) { // Optional, we don't mind if it fails @@ -396,10 +423,10 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bo } if (p_upwards) { - // Try to load settings ascending through dirs shape! + // Try to load settings ascending through parent directories d->change_dir(".."); if (d->get_current_dir() == current_dir) - break; //not doing anything useful + break; // not doing anything useful current_dir = d->get_current_dir(); } else { break; @@ -416,6 +443,8 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bo if (resource_path.length() && resource_path[resource_path.length() - 1] == '/') resource_path = resource_path.substr(0, resource_path.length() - 1); // chop end + // If we're loading a project.godot from source code, we can operate some + // ProjectSettings conversions if need be. _convert_to_last_version(); return OK; diff --git a/doc/classes/Input.xml b/doc/classes/Input.xml index 10ec15b99d..0e6e54c8fd 100644 --- a/doc/classes/Input.xml +++ b/doc/classes/Input.xml @@ -123,7 +123,7 @@ <argument index="0" name="button_index" type="int"> </argument> <description> - Receives a [code]JOY_BUTTON_*[/code] Enum and returns it's equivalent name as a string. + Receives a [code]JOY_BUTTON_*[/code] Enum and returns its equivalent name as a string. </description> </method> <method name="get_joy_guid" qualifiers="const"> diff --git a/doc/classes/NavigationPolygon.xml b/doc/classes/NavigationPolygon.xml index b29e19e5d8..4ede80b98c 100644 --- a/doc/classes/NavigationPolygon.xml +++ b/doc/classes/NavigationPolygon.xml @@ -1,8 +1,27 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="NavigationPolygon" inherits="Resource" category="Core" version="3.1"> <brief_description> + A node that has methods to draw outlines or use indices of vertices to create navigation polygons. </brief_description> <description> + There are two ways to create polygons. Either by using the [method add_outline] method or using the [method add_polygon] method. + Using [method add_outline]: + [code] + var polygon = NavigationPolygon.new() + var outline = PoolVector2Array([Vector2(0, 0), Vector2(0, 50), Vector2(50, 50), Vector2(50, 0)]) + polygon.add_outline(outline) + polygon.make_polygons_from_outlines() + $NavigationPolygonInstance.navpoly = polygon + [/code] + Using [method add_polygon] and indices of the vertices array. + [code] + var polygon = NavigationPolygon.new() + var vertices = PoolVector2Array([Vector2(0, 0), Vector2(0, 50), Vector2(50, 50), Vector2(50, 0)]) + polygon.set_vertices(vertices) + var indices = PoolIntArray(0, 3, 1) + polygon.add_polygon(indices) + $NavigationPolygonInstance.navpoly = polygon + [/code] </description> <tutorials> </tutorials> @@ -15,6 +34,7 @@ <argument index="0" name="outline" type="PoolVector2Array"> </argument> <description> + Appends a [PoolVector2Array] that contains the vertices of an outline to the internal array that contains all the outlines. You have to call [method make_polygons_from_outlines] in order for this array to be converted to polygons that the engine will use. </description> </method> <method name="add_outline_at_index"> @@ -25,6 +45,7 @@ <argument index="1" name="index" type="int"> </argument> <description> + Adds a [PoolVector2Array] that contains the vertices of an outline to the internal array that contains all the outlines at a fixed position. You have to call [method make_polygons_from_outlines] in order for this array to be converted to polygons that the engine will use. </description> </method> <method name="add_polygon"> @@ -33,18 +54,21 @@ <argument index="0" name="polygon" type="PoolIntArray"> </argument> <description> + Adds a polygon using the indices of the vertices you get when calling [method get_vertices]. </description> </method> <method name="clear_outlines"> <return type="void"> </return> <description> + Clears the array of the outlines, but it doesn't clear the vertices and the polygons that were created by them. </description> </method> <method name="clear_polygons"> <return type="void"> </return> <description> + Clears the array of polygons, but it doesn't clear the array of outlines and vertices. </description> </method> <method name="get_outline" qualifiers="const"> @@ -53,12 +77,14 @@ <argument index="0" name="idx" type="int"> </argument> <description> + Returns a [PoolVector2Array] containing the vertices of an outline that was created in the editor or by script. </description> </method> <method name="get_outline_count" qualifiers="const"> <return type="int"> </return> <description> + Returns the number of outlines that were created in the editor or by script. </description> </method> <method name="get_polygon"> @@ -67,24 +93,28 @@ <argument index="0" name="idx" type="int"> </argument> <description> + Returns a [PoolIntArray] containing the indices of the vertices of a created polygon. </description> </method> <method name="get_polygon_count" qualifiers="const"> <return type="int"> </return> <description> + Returns the count of all polygons. </description> </method> <method name="get_vertices" qualifiers="const"> <return type="PoolVector2Array"> </return> <description> + Returns a [PoolVector2Array] containing all the vertices being used to create the polygons. </description> </method> <method name="make_polygons_from_outlines"> <return type="void"> </return> <description> + Creates polygons from the outlines added in the editor or by script. </description> </method> <method name="remove_outline"> @@ -93,6 +123,7 @@ <argument index="0" name="idx" type="int"> </argument> <description> + Removes an outline created in the editor or by script. You have to call [method make_polygons_from_outlines] for the polygons to update. </description> </method> <method name="set_outline"> @@ -103,6 +134,7 @@ <argument index="1" name="outline" type="PoolVector2Array"> </argument> <description> + Changes an outline created in the editor or by script. You have to call [method make_polygons_from_outlines] for the polygons to update. </description> </method> <method name="set_vertices"> @@ -111,6 +143,7 @@ <argument index="0" name="vertices" type="PoolVector2Array"> </argument> <description> + Sets the vertices that can be then indexed to create polygons with the [method add_polygon] method. </description> </method> </methods> diff --git a/doc/classes/PathFollow2D.xml b/doc/classes/PathFollow2D.xml index f9940dab2f..515c921d0d 100644 --- a/doc/classes/PathFollow2D.xml +++ b/doc/classes/PathFollow2D.xml @@ -23,6 +23,7 @@ The node's offset along the curve. </member> <member name="lookahead" type="float" setter="set_lookahead" getter="get_lookahead"> + How far to look ahead of the curve to calculate the tangent if the node is rotating. E.g. shorter lookaheads will lead to faster rotations. Default value: [code]4[/code]. </member> <member name="loop" type="bool" setter="set_loop" getter="has_loop"> If [code]true[/code], any offset outside the path's length will wrap around, instead of stopping at the ends. Use it for cyclic paths. diff --git a/doc/classes/PhysicsServer.xml b/doc/classes/PhysicsServer.xml index f79baea0be..c836414dd2 100644 --- a/doc/classes/PhysicsServer.xml +++ b/doc/classes/PhysicsServer.xml @@ -1260,7 +1260,7 @@ The higher, the stronger. </constant> <constant name="PIN_JOINT_IMPULSE_CLAMP" value="2" enum="PinJointParam"> - If above 0, this value is the maximum value for an impulse that this Joint puts on it's ends. + If above 0, this value is the maximum value for an impulse that this Joint puts on its ends. </constant> <constant name="HINGE_JOINT_BIAS" value="0" enum="HingeJointParam"> The speed with which the two bodies get pulled together when they move in different directions. diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 4516fc522a..dfecff9050 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -182,7 +182,7 @@ Name of the project. It is used from both project manager and by the exporters. Overriding this as name.locale allows setting it in multiple languages. </member> <member name="application/config/use_custom_user_dir" type="bool" setter="" getter=""> - Allow the project to save to it's own custom user dir (in AppData on windows or ~/.config on unixes). This setting only works for desktop exporters. A name must be set in the "custom_user_dir_name" setting for this to take effect. + Allow the project to save to its own custom user dir (in AppData on windows or ~/.config on unixes). This setting only works for desktop exporters. A name must be set in the "custom_user_dir_name" setting for this to take effect. </member> <member name="application/run/disable_stderr" type="bool" setter="" getter=""> Disable printing to stderr on exported build. @@ -691,7 +691,7 @@ <member name="rendering/quality/reflections/high_quality_ggx.mobile" type="bool" setter="" getter=""> </member> <member name="rendering/quality/reflections/texture_array_reflections" type="bool" setter="" getter=""> - For reflection probes and panorama backgrounds (sky), use a texure array instead of mipmaps. This reduces jitter noise on reflections, but costs more performance and memory. + For reflection probes and panorama backgrounds (sky), use a texture array instead of mipmaps. This reduces jitter noise on reflections, but costs more performance and memory. </member> <member name="rendering/quality/reflections/texture_array_reflections.mobile" type="bool" setter="" getter=""> </member> @@ -704,7 +704,7 @@ <member name="rendering/quality/shading/force_lambert_over_burley.mobile" type="bool" setter="" getter=""> </member> <member name="rendering/quality/shading/force_vertex_shading" type="bool" setter="" getter=""> - Force vertex shading for all rendering. This can increase performance a lot, but also reduces quality inmensely. Can work to optimize on very low end mobile. + Force vertex shading for all rendering. This can increase performance a lot, but also reduces quality immensely. Can work to optimize on very low end mobile. </member> <member name="rendering/quality/shading/force_vertex_shading.mobile" type="bool" setter="" getter=""> </member> diff --git a/doc/classes/StreamPeerTCP.xml b/doc/classes/StreamPeerTCP.xml index 664ffc60c3..9a0fceddab 100644 --- a/doc/classes/StreamPeerTCP.xml +++ b/doc/classes/StreamPeerTCP.xml @@ -4,7 +4,7 @@ TCP Stream peer. </brief_description> <description> - TCP Stream peer. This object can be used to connect to TCP servers, or also is returned by a tcp server. + TCP Stream peer. This object can be used to connect to TCP servers, or also is returned by a TCP server. </description> <tutorials> </tutorials> @@ -54,6 +54,7 @@ <return type="bool"> </return> <description> + Returns [code]true[/code] if this peer is currently connected to a host, [code]false[code] otherwise. </description> </method> <method name="set_no_delay"> diff --git a/doc/classes/Vector2.xml b/doc/classes/Vector2.xml index c323cf6992..1f8eb47044 100644 --- a/doc/classes/Vector2.xml +++ b/doc/classes/Vector2.xml @@ -259,10 +259,10 @@ </methods> <members> <member name="x" type="float" setter="" getter=""> - The vector's x component. + The vector's x component. Also accessible by using the index position [code][0][/code]. </member> <member name="y" type="float" setter="" getter=""> - The vector's y component. + The vector's y component. Also accessible by using the index position [code][1][/code]. </member> </members> <constants> diff --git a/doc/classes/Vector3.xml b/doc/classes/Vector3.xml index 8c4e08778d..2499ba75ff 100644 --- a/doc/classes/Vector3.xml +++ b/doc/classes/Vector3.xml @@ -260,13 +260,13 @@ </methods> <members> <member name="x" type="float" setter="" getter=""> - The vector's x component. + The vector's x component. Also accessible by using the index position [code][0][/code]. </member> <member name="y" type="float" setter="" getter=""> - The vector's y component. + The vector's y component. Also accessible by using the index position [code][1][/code]. </member> <member name="z" type="float" setter="" getter=""> - The vector's z component. + The vector's z component. Also accessible by using the index position [code][2][/code]. </member> </members> <constants> diff --git a/doc/classes/YSort.xml b/doc/classes/YSort.xml index 12b9cb623f..45ae8645b1 100644 --- a/doc/classes/YSort.xml +++ b/doc/classes/YSort.xml @@ -14,6 +14,7 @@ </methods> <members> <member name="sort_enabled" type="bool" setter="set_sort_enabled" getter="is_sort_enabled"> + If [code]true[/code] child nodes are sorted, otherwise sorting is disabled. Default: [code]true[/code]. </member> </members> <constants> diff --git a/drivers/coreaudio/audio_driver_coreaudio.cpp b/drivers/coreaudio/audio_driver_coreaudio.cpp index aaec63d7ff..850b90d59b 100644 --- a/drivers/coreaudio/audio_driver_coreaudio.cpp +++ b/drivers/coreaudio/audio_driver_coreaudio.cpp @@ -145,9 +145,6 @@ Error AudioDriverCoreAudio::init() { unsigned int buffer_size = buffer_frames * channels; samples_in.resize(buffer_size); input_buf.resize(buffer_size); - input_buffer.resize(buffer_size * 8); - input_position = 0; - input_size = 0; print_verbose("CoreAudio: detected " + itos(channels) + " channels"); print_verbose("CoreAudio: audio buffer frames: " + itos(buffer_frames) + " calculated latency: " + itos(buffer_frames * 1000 / mix_rate) + "ms"); @@ -487,6 +484,8 @@ void AudioDriverCoreAudio::capture_finish() { Error AudioDriverCoreAudio::capture_start() { + input_buffer_init(buffer_frames); + OSStatus result = AudioOutputUnitStart(input_unit); if (result != noErr) { ERR_PRINTS("AudioOutputUnitStart failed, code: " + itos(result)); diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp index fbcbebc88c..7e6d969ccb 100644 --- a/drivers/gles2/rasterizer_scene_gles2.cpp +++ b/drivers/gles2/rasterizer_scene_gles2.cpp @@ -2455,13 +2455,20 @@ void RasterizerSceneGLES2::_draw_sky(RasterizerStorageGLES2::Sky *p_sky, const C glEnableVertexAttribArray(VS::ARRAY_VERTEX); glEnableVertexAttribArray(VS::ARRAY_TEX_UV); + storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_ASYM_PANO, asymmetrical); + storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_PANORAMA, !asymmetrical); storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_MULTIPLIER, true); storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_CUBEMAP, false); - storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_PANORAMA, true); storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_COPY_SECTION, false); storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_CUSTOM_ALPHA, false); storage->shaders.copy.bind(); storage->shaders.copy.set_uniform(CopyShaderGLES2::MULTIPLIER, p_energy); + if (asymmetrical) { + // pack the bits we need from our projection matrix + storage->shaders.copy.set_uniform(CopyShaderGLES2::ASYM_PROJ, camera.matrix[2][0], camera.matrix[0][0], camera.matrix[2][1], camera.matrix[1][1]); + ///@TODO I couldn't get mat3 + p_transform.basis to work, that would be better here. + storage->shaders.copy.set_uniform(CopyShaderGLES2::PANO_TRANSFORM, p_transform); + } glDrawArrays(GL_TRIANGLE_FAN, 0, 4); @@ -2469,6 +2476,8 @@ void RasterizerSceneGLES2::_draw_sky(RasterizerStorageGLES2::Sky *p_sky, const C glDisableVertexAttribArray(VS::ARRAY_TEX_UV); glBindBuffer(GL_ARRAY_BUFFER, 0); + storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_ASYM_PANO, false); + storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_PANORAMA, false); storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_MULTIPLIER, false); storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_CUBEMAP, false); } diff --git a/drivers/gles2/shaders/copy.glsl b/drivers/gles2/shaders/copy.glsl index 16bbde196d..0b8da4f875 100644 --- a/drivers/gles2/shaders/copy.glsl +++ b/drivers/gles2/shaders/copy.glsl @@ -35,6 +35,8 @@ void main() { #if defined(USE_CUBEMAP) || defined(USE_PANORAMA) cube_interp = cube_in; +#elif defined(USE_ASYM_PANO) + uv_interp = vertex_attrib.xy; #else uv_interp = uv_in; #endif @@ -68,6 +70,11 @@ varying vec2 uv_interp; #endif /* clang-format on */ +#ifdef USE_ASYM_PANO +uniform highp mat4 pano_transform; +uniform highp vec4 asym_proj; +#endif + #ifdef USE_CUBEMAP uniform samplerCube source_cube; // texunit:0 #else @@ -108,6 +115,21 @@ void main() { vec4 color = texturePanorama(source, normalize(cube_interp)); +#elif defined(USE_ASYM_PANO) + + // When an asymmetrical projection matrix is used (applicable for stereoscopic rendering i.e. VR) we need to do this calculation per fragment to get a perspective correct result. + // Note that we're ignoring the x-offset for IPD, with Z sufficiently in the distance it becomes neglectible, as a result we could probably just set cube_normal.z to -1. + // The Matrix[2][0] (= asym_proj.x) and Matrix[2][1] (= asym_proj.z) values are what provide the right shift in the image. + + vec3 cube_normal; + cube_normal.z = -1000000.0; + cube_normal.x = (cube_normal.z * (-uv_interp.x - asym_proj.x)) / asym_proj.y; + cube_normal.y = (cube_normal.z * (-uv_interp.y - asym_proj.z)) / asym_proj.a; + cube_normal = mat3(pano_transform) * cube_normal; + cube_normal.z = -cube_normal.z; + + vec4 color = texturePanorama(source, normalize(cube_normal.xyz)); + #elif defined(USE_CUBEMAP) vec4 color = textureCube(source_cube, normalize(cube_interp)); #else diff --git a/drivers/gles2/shaders/scene.glsl b/drivers/gles2/shaders/scene.glsl index 7b57f5d497..a1f0c2680c 100644 --- a/drivers/gles2/shaders/scene.glsl +++ b/drivers/gles2/shaders/scene.glsl @@ -359,7 +359,7 @@ void main() { normal = normalize((world_matrix * vec4(normal, 0.0)).xyz); #if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) - tangent = normalize((world_matrix * vec4(tangent, 0.0)), xyz); + tangent = normalize((world_matrix * vec4(tangent, 0.0)).xyz); binormal = normalize((world_matrix * vec4(binormal, 0.0)).xyz); #endif #endif diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index 8388b15edb..91ab34f775 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -2053,7 +2053,7 @@ FRAGMENT_SHADER_CODE emission = emission * rev_amount + fog_color * fog_amount; ambient_light *= rev_amount; - specular_light *rev_amount; + specular_light *= rev_amount; diffuse_light *= rev_amount; } diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.cpp b/drivers/pulseaudio/audio_driver_pulseaudio.cpp index 9c02549e39..d78316945f 100644 --- a/drivers/pulseaudio/audio_driver_pulseaudio.cpp +++ b/drivers/pulseaudio/audio_driver_pulseaudio.cpp @@ -613,20 +613,18 @@ Error AudioDriverPulseAudio::capture_init_device() { break; } - print_verbose("PulseAudio: detected " + itos(pa_rec_map.channels) + " input channels"); - pa_sample_spec spec; spec.format = PA_SAMPLE_S16LE; spec.channels = pa_rec_map.channels; spec.rate = mix_rate; - int latency = 30; - input_buffer_frames = closest_power_of_2(latency * mix_rate / 1000); - int buffer_size = input_buffer_frames * spec.channels; + int input_latency = 30; + int input_buffer_frames = closest_power_of_2(input_latency * mix_rate / 1000); + int input_buffer_size = input_buffer_frames * spec.channels; pa_buffer_attr attr; - attr.fragsize = buffer_size * sizeof(int16_t); + attr.fragsize = input_buffer_size * sizeof(int16_t); pa_rec_str = pa_stream_new(pa_ctx, "Record", &spec, &pa_rec_map); if (pa_rec_str == NULL) { @@ -642,9 +640,10 @@ Error AudioDriverPulseAudio::capture_init_device() { ERR_FAIL_V(ERR_CANT_OPEN); } - input_buffer.resize(input_buffer_frames * 8); - input_position = 0; - input_size = 0; + input_buffer_init(input_buffer_frames); + + print_verbose("PulseAudio: detected " + itos(pa_rec_map.channels) + " input channels"); + print_verbose("PulseAudio: input buffer frames: " + itos(input_buffer_frames) + " calculated latency: " + itos(input_buffer_frames * 1000 / mix_rate) + "ms"); return OK; } @@ -760,7 +759,6 @@ AudioDriverPulseAudio::AudioDriverPulseAudio() { mix_rate = 0; buffer_frames = 0; - input_buffer_frames = 0; pa_buffer_size = 0; channels = 0; pa_ready = 0; diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.h b/drivers/pulseaudio/audio_driver_pulseaudio.h index f8358a452b..d8bab841ff 100644 --- a/drivers/pulseaudio/audio_driver_pulseaudio.h +++ b/drivers/pulseaudio/audio_driver_pulseaudio.h @@ -64,7 +64,6 @@ class AudioDriverPulseAudio : public AudioDriver { unsigned int mix_rate; unsigned int buffer_frames; - unsigned int input_buffer_frames; unsigned int pa_buffer_size; int channels; int pa_ready; diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp index a91e41b008..8665f701b1 100644 --- a/drivers/wasapi/audio_driver_wasapi.cpp +++ b/drivers/wasapi/audio_driver_wasapi.cpp @@ -336,10 +336,7 @@ Error AudioDriverWASAPI::init_capture_device(bool reinit) { HRESULT hr = audio_input.audio_client->GetBufferSize(&max_frames); ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN); - // Set the buffer size - input_buffer.resize(max_frames * CAPTURE_BUFFER_CHANNELS); - input_position = 0; - input_size = 0; + input_buffer_init(max_frames); return OK; } diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp index f425d0a995..438d7ea306 100644 --- a/editor/editor_file_dialog.cpp +++ b/editor/editor_file_dialog.cpp @@ -1135,14 +1135,10 @@ void EditorFileDialog::_update_drives() { } void EditorFileDialog::_favorite_selected(int p_idx) { - - Vector<String> favorited = EditorSettings::get_singleton()->get_favorites(); - ERR_FAIL_INDEX(p_idx, favorited.size()); - - dir_access->change_dir(favorited[p_idx]); + dir_access->change_dir(favorites->get_item_metadata(p_idx)); file->set_text(""); - invalidate(); update_dir(); + invalidate(); _push_history(); } @@ -1192,7 +1188,7 @@ void EditorFileDialog::_update_favorites() { bool res = access == ACCESS_RESOURCES; String current = get_current_dir(); - Ref<Texture> star = get_icon("Favorites", "EditorIcons"); + Ref<Texture> folder_icon = get_icon("Folder", "EditorIcons"); favorites->clear(); favorite->set_pressed(false); @@ -1203,16 +1199,23 @@ void EditorFileDialog::_update_favorites() { if (cres != res) continue; String name = favorited[i]; - - bool setthis = name == current; + bool setthis = false; if (res && name == "res://") { + if (name == current) + setthis = true; name = "/"; + } else if (name.ends_with("/")) { + if (name == current) + setthis = true; + name = name.substr(0, name.length() - 1); + name = name.get_file(); + + favorites->add_item(name, folder_icon); } else { - name = name.get_file() + "/"; + continue; // We don't handle favorite files here } - favorites->add_item(name, star); favorites->set_item_metadata(favorites->get_item_count() - 1, favorited[i]); if (setthis) { diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index a90f15004a..3ecaa2b136 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -738,9 +738,9 @@ Control *EditorProperty::make_custom_tooltip(const String &p_text) const { tooltip_text = p_text; EditorHelpBit *help_bit = memnew(EditorHelpBit); help_bit->add_style_override("panel", get_stylebox("panel", "TooltipPanel")); - help_bit->get_rich_text()->set_fixed_size_to_width(300); + help_bit->get_rich_text()->set_fixed_size_to_width(360 * EDSCALE); - String text = TTR("Property: ") + "[u][b]" + p_text.get_slice("::", 0) + "[/b][/u]\n"; + String text = TTR("Property:") + " [u][b]" + p_text.get_slice("::", 0) + "[/b][/u]\n"; text += p_text.get_slice("::", 1).strip_edges(); help_bit->set_text(text); help_bit->call_deferred("set_text", text); //hack so it uses proper theme once inside scene @@ -960,7 +960,7 @@ Control *EditorInspectorCategory::make_custom_tooltip(const String &p_text) cons tooltip_text = p_text; EditorHelpBit *help_bit = memnew(EditorHelpBit); help_bit->add_style_override("panel", get_stylebox("panel", "TooltipPanel")); - help_bit->get_rich_text()->set_fixed_size_to_width(300); + help_bit->get_rich_text()->set_fixed_size_to_width(360 * EDSCALE); String text = "[u][b]" + p_text.get_slice("::", 0) + "[/b][/u]\n"; text += p_text.get_slice("::", 1).strip_edges(); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 18dd85617b..d01543198a 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -3892,7 +3892,9 @@ void EditorNode::_scene_tab_hover(int p_tab) { tab_preview_panel->hide(); } else { String path = editor_data.get_scene_path(p_tab); - EditorResourcePreview::get_singleton()->queue_resource_preview(path, this, "_thumbnail_done", p_tab); + if (path != String()) { + EditorResourcePreview::get_singleton()->queue_resource_preview(path, this, "_thumbnail_done", p_tab); + } } } diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 26bc43c540..701f10ca00 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -225,7 +225,7 @@ void FileSystemDock::_update_tree(const Vector<String> p_uncollapsed_paths, bool updating_tree = false; } -void FileSystemDock::_update_display_mode() { +void FileSystemDock::_update_display_mode(bool p_force) { // Compute the new display mode DisplayMode new_display_mode; if (display_mode_setting == DISPLAY_MODE_SETTING_TREE_ONLY) { @@ -234,7 +234,7 @@ void FileSystemDock::_update_display_mode() { new_display_mode = DISPLAY_MODE_SPLIT; } - if (new_display_mode != display_mode || old_display_mode_setting != display_mode_setting) { + if (p_force || new_display_mode != display_mode || old_display_mode_setting != display_mode_setting) { display_mode = new_display_mode; old_display_mode_setting = display_mode_setting; button_toggle_display_mode->set_pressed(display_mode_setting == DISPLAY_MODE_SETTING_SPLIT ? true : false); @@ -352,6 +352,9 @@ void FileSystemDock::_notification(int p_what) { tree->set_drop_mode_flags(0); } break; + case NOTIFICATION_THEME_CHANGED: { + _update_display_mode(true); + } break; case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { // Update icons String ei = "EditorIcons"; @@ -360,6 +363,11 @@ void FileSystemDock::_notification(int p_what) { button_tree->set_icon(get_icon("Filesystem", ei)); button_hist_next->set_icon(get_icon("Forward", ei)); button_hist_prev->set_icon(get_icon("Back", ei)); + if (button_file_list_display_mode->is_pressed()) { + button_file_list_display_mode->set_icon(get_icon("FileThumbnail", "EditorIcons")); + } else { + button_file_list_display_mode->set_icon(get_icon("FileList", "EditorIcons")); + } tree_search_box->set_right_icon(get_icon("Search", ei)); tree_search_box->set_clear_button_enabled(true); diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h index d964515572..2aa79b1ddd 100644 --- a/editor/filesystem_dock.h +++ b/editor/filesystem_dock.h @@ -268,7 +268,7 @@ private: void _file_list_thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Ref<Texture> &p_small_preview, const Variant &p_udata); void _tree_thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Ref<Texture> &p_small_preview, const Variant &p_udata); - void _update_display_mode(); + void _update_display_mode(bool p_force = false); Vector<String> _tree_get_selected(bool remove_self_inclusion = true); diff --git a/editor/plugin_config_dialog.cpp b/editor/plugin_config_dialog.cpp index a334f79f5a..8e626e7111 100644 --- a/editor/plugin_config_dialog.cpp +++ b/editor/plugin_config_dialog.cpp @@ -180,7 +180,7 @@ PluginConfigDialog::PluginConfigDialog() { grid->add_child(desc_lb); desc_edit = memnew(TextEdit); - desc_edit->set_custom_minimum_size(Size2(400.0f, 50.0f)); + desc_edit->set_custom_minimum_size(Size2(400, 80) * EDSCALE); grid->add_child(desc_edit); Label *author_lb = memnew(Label); diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 7e11c4a253..07a7e7952a 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -490,7 +490,7 @@ void ScriptEditor::_open_recent_script(int p_idx) { edit(text_file, true); return; } - // if it's a path then its most likely a deleted file not help + // if it's a path then it's most likely a deleted file not help } else if (path.find("::") != -1) { // built-in script Ref<Script> script = ResourceLoader::load(path); @@ -2912,7 +2912,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { script_list = memnew(ItemList); list_split->add_child(script_list); - script_list->set_custom_minimum_size(Size2(150 * EDSCALE, 90)); //need to give a bit of limit to avoid it from disappearing + script_list->set_custom_minimum_size(Size2(150, 90) * EDSCALE); //need to give a bit of limit to avoid it from disappearing script_list->set_v_size_flags(SIZE_EXPAND_FILL); script_split->set_split_offset(140); _sort_list_on_update = true; @@ -2951,7 +2951,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { overview_vbox->add_child(members_overview); members_overview->set_allow_reselect(true); - members_overview->set_custom_minimum_size(Size2(0, 90)); //need to give a bit of limit to avoid it from disappearing + members_overview->set_custom_minimum_size(Size2(0, 90) * EDSCALE); //need to give a bit of limit to avoid it from disappearing members_overview->set_v_size_flags(SIZE_EXPAND_FILL); members_overview->set_allow_rmb_select(true); members_overview->set_drag_forwarding(this); @@ -2959,12 +2959,12 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { help_overview = memnew(ItemList); overview_vbox->add_child(help_overview); help_overview->set_allow_reselect(true); - help_overview->set_custom_minimum_size(Size2(0, 90)); //need to give a bit of limit to avoid it from disappearing + help_overview->set_custom_minimum_size(Size2(0, 90) * EDSCALE); //need to give a bit of limit to avoid it from disappearing help_overview->set_v_size_flags(SIZE_EXPAND_FILL); tab_container = memnew(TabContainer); tab_container->set_tabs_visible(false); - tab_container->set_custom_minimum_size(Size2(200 * EDSCALE, 0)); + tab_container->set_custom_minimum_size(Size2(200, 0) * EDSCALE); script_split->add_child(tab_container); tab_container->set_h_size_flags(SIZE_EXPAND_FILL); diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp index 45c632af1f..ab89d170da 100644 --- a/editor/plugins/spatial_editor_plugin.cpp +++ b/editor/plugins/spatial_editor_plugin.cpp @@ -2259,6 +2259,11 @@ void SpatialEditorViewport::_notification(int p_what) { float cinema_half_width = cinema_label->get_size().width / 2.0f; cinema_label->set_anchor_and_margin(MARGIN_LEFT, 0.5f, -cinema_half_width); } + + if (lock_rotation) { + float locked_half_width = locked_label->get_size().width / 2.0f; + locked_label->set_anchor_and_margin(MARGIN_LEFT, 0.5f, -locked_half_width); + } } if (p_what == NOTIFICATION_ENTER_TREE) { @@ -2269,27 +2274,36 @@ void SpatialEditorViewport::_notification(int p_what) { surface->connect("mouse_exited", this, "_surface_mouse_exit"); surface->connect("focus_entered", this, "_surface_focus_enter"); surface->connect("focus_exited", this, "_surface_focus_exit"); - view_menu->set_flat(false); - view_menu->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles")); - view_menu->add_style_override("hover", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles")); - view_menu->add_style_override("pressed", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles")); - view_menu->add_style_override("focus", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles")); - view_menu->add_style_override("disabled", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles")); - info_label->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles")); - fps_label->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles")); - cinema_label->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles")); - preview_camera->set_icon(get_icon("Camera", "EditorIcons")); + _init_gizmo_instance(index); } + if (p_what == NOTIFICATION_EXIT_TREE) { _finish_gizmo_instances(); } - if (p_what == NOTIFICATION_MOUSE_ENTER) { - } + if (p_what == NOTIFICATION_THEME_CHANGED) { + + view_menu->set_icon(get_icon("GuiMiniTabMenu", "EditorIcons")); + preview_camera->set_icon(get_icon("Camera", "EditorIcons")); + + view_menu->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles")); + view_menu->add_style_override("hover", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles")); + view_menu->add_style_override("pressed", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles")); + view_menu->add_style_override("focus", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles")); + view_menu->add_style_override("disabled", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles")); - if (p_what == NOTIFICATION_DRAW) { + preview_camera->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles")); + preview_camera->add_style_override("hover", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles")); + preview_camera->add_style_override("pressed", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles")); + preview_camera->add_style_override("focus", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles")); + preview_camera->add_style_override("disabled", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles")); + + info_label->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles")); + fps_label->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles")); + cinema_label->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles")); + locked_label->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles")); } } @@ -2530,8 +2544,14 @@ void SpatialEditorViewport::_menu_option(int p_option) { if (!se) continue; - Transform xform = camera_transform; - xform.scale_basis(sp->get_scale()); + Transform xform; + if (orthogonal) { + xform = sp->get_global_transform(); + xform.basis.set_euler(camera_transform.basis.get_euler()); + } else { + xform = camera_transform; + xform.scale_basis(sp->get_scale()); + } undo_redo->add_do_method(sp, "set_global_transform", xform); undo_redo->add_undo_method(sp, "set_global_transform", sp->get_global_gizmo_transform()); @@ -2579,9 +2599,9 @@ void SpatialEditorViewport::_menu_option(int p_option) { lock_rotation = !current; view_menu->get_popup()->set_item_checked(idx, !current); if (lock_rotation) { - view_menu->set_icon(get_icon("Lock", "EditorIcons")); + locked_label->show(); } else { - view_menu->set_icon(Ref<Texture>()); + locked_label->hide(); } } break; @@ -2651,11 +2671,6 @@ void SpatialEditorViewport::_menu_option(int p_option) { bool current = view_menu->get_popup()->is_item_checked(idx); view_menu->get_popup()->set_item_checked(idx, !current); - if (current) - preview_camera->set_anchor_and_margin(MARGIN_TOP, ANCHOR_BEGIN, 10 * EDSCALE); - else - preview_camera->set_anchor_and_margin(MARGIN_TOP, ANCHOR_BEGIN, 15 * EDSCALE + fps_label->get_size().height); - } break; case VIEW_DISPLAY_NORMAL: { @@ -2769,7 +2784,7 @@ void SpatialEditorViewport::_toggle_camera_preview(bool p_activate) { VS::get_singleton()->viewport_attach_camera(viewport->get_viewport_rid(), camera->get_camera()); //restore if (!preview) preview_camera->hide(); - view_menu->show(); + view_menu->set_disabled(false); surface->update(); } else { @@ -2777,7 +2792,7 @@ void SpatialEditorViewport::_toggle_camera_preview(bool p_activate) { previewing = preview; previewing->connect("tree_exiting", this, "_preview_exited_scene"); VS::get_singleton()->viewport_attach_camera(viewport->get_viewport_rid(), preview->get_camera()); //replace - view_menu->hide(); + view_menu->set_disabled(true); surface->update(); } } @@ -3434,8 +3449,10 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed surface->set_focus_mode(FOCUS_ALL); view_menu = memnew(MenuButton); + view_menu->set_flat(false); surface->add_child(view_menu); - view_menu->set_position(Point2(4, 4) * EDSCALE); + view_menu->set_position(Point2(10, 10) * EDSCALE); + view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/top_view"), VIEW_TOP); view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/bottom_view"), VIEW_BOTTOM); view_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("spatial_editor/left_view"), VIEW_LEFT); @@ -3486,12 +3503,8 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed ED_SHORTCUT("spatial_editor/freelook_down", TTR("Freelook Down"), KEY_Q); ED_SHORTCUT("spatial_editor/freelook_speed_modifier", TTR("Freelook Speed Modifier"), KEY_SHIFT); - preview_camera = memnew(Button); - preview_camera->set_toggle_mode(true); - preview_camera->set_anchor_and_margin(MARGIN_LEFT, ANCHOR_END, -90 * EDSCALE); - preview_camera->set_anchor_and_margin(MARGIN_TOP, ANCHOR_BEGIN, 10 * EDSCALE); - preview_camera->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, -10 * EDSCALE); - preview_camera->set_h_grow_direction(GROW_DIRECTION_BEGIN); + preview_camera = memnew(CheckBox); + preview_camera->set_position(Point2(10, 38) * EDSCALE); // Below the 'view_menu' MenuButton. preview_camera->set_text(TTR("Preview")); surface->add_child(preview_camera); preview_camera->hide(); @@ -3511,7 +3524,6 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed surface->add_child(info_label); info_label->hide(); - // FPS Counter. fps_label = memnew(Label); fps_label->set_anchor_and_margin(MARGIN_LEFT, ANCHOR_END, -90 * EDSCALE); fps_label->set_anchor_and_margin(MARGIN_TOP, ANCHOR_BEGIN, 10 * EDSCALE); @@ -3529,6 +3541,16 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed cinema_label->hide(); previewing_cinema = false; + locked_label = memnew(Label); + locked_label->set_anchor_and_margin(MARGIN_TOP, ANCHOR_END, -20 * EDSCALE); + locked_label->set_anchor_and_margin(MARGIN_BOTTOM, ANCHOR_END, -10 * EDSCALE); + locked_label->set_h_grow_direction(GROW_DIRECTION_END); + locked_label->set_v_grow_direction(GROW_DIRECTION_BEGIN); + locked_label->set_align(Label::ALIGN_CENTER); + surface->add_child(locked_label); + locked_label->set_text(TTR("View Rotation Locked")); + locked_label->hide(); + accept = NULL; freelook_active = false; @@ -5452,7 +5474,6 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { view_menu = memnew(MenuButton); view_menu->set_text(TTR("View")); - view_menu->set_position(Point2(212, 0)); hbc_menu->add_child(view_menu); p = view_menu->get_popup(); diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h index c552f21e39..3cce76cc17 100644 --- a/editor/plugins/spatial_editor_plugin.h +++ b/editor/plugins/spatial_editor_plugin.h @@ -192,7 +192,7 @@ private: EditorSelection *editor_selection; UndoRedo *undo_redo; - Button *preview_camera; + CheckBox *preview_camera; ViewportContainer *viewport_container; MenuButton *view_menu; @@ -211,6 +211,7 @@ private: Label *info_label; Label *fps_label; Label *cinema_label; + Label *locked_label; struct _RayResult { diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 45c20121da..a8f4c38695 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -1307,6 +1307,13 @@ bool SceneTreeDock::_validate_no_foreign() { return false; } + // When edited_scene inherits from another one the root Node will be the parent Scene, + // we don't want to consider that Node a foreign one otherwise we would not be able to + // delete it + if (edited_scene->get_scene_inherited_state().is_valid() && edited_scene == E->get()) { + continue; + } + if (edited_scene->get_scene_inherited_state().is_valid() && edited_scene->get_scene_inherited_state()->find_node_by_path(edited_scene->get_path_to(E->get())) >= 0) { accept->set_text(TTR("Can't operate on nodes the current scene inherits from!")); diff --git a/editor/script_editor_debugger.cpp b/editor/script_editor_debugger.cpp index 6fbac0d4b5..a36a844710 100644 --- a/editor/script_editor_debugger.cpp +++ b/editor/script_editor_debugger.cpp @@ -355,7 +355,7 @@ void ScriptEditorDebugger::_video_mem_request() { Size2 ScriptEditorDebugger::get_minimum_size() const { Size2 ms = Control::get_minimum_size(); - ms.y = MAX(ms.y, 250); + ms.y = MAX(ms.y, 250 * EDSCALE); return ms; } void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_data) { diff --git a/main/input_default.cpp b/main/input_default.cpp index 913c143025..33c422190d 100644 --- a/main/input_default.cpp +++ b/main/input_default.cpp @@ -261,6 +261,13 @@ void InputDefault::parse_input_event(const Ref<InputEvent> &p_event) { void InputDefault::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_emulated) { + // Notes on mouse-touch emulation: + // - Emulated mouse events are parsed, that is, re-routed to this method, so they make the same effects + // as true mouse events. The only difference is the situation is flagged as emulated so they are not + // emulated back to touch events in an endless loop. + // - Emulated touch events are handed right to the main loop (i.e., the SceneTree) because they don't + // require additional handling by this class. + _THREAD_SAFE_METHOD_ Ref<InputEventKey> k = p_event; @@ -316,11 +323,21 @@ void InputDefault::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool } } - if (emulate_mouse_from_touch) { + Ref<InputEventScreenTouch> st = p_event; + + if (st.is_valid()) { + + if (st->is_pressed()) { + SpeedTrack &track = touch_speed_track[st->get_index()]; + track.reset(); + } else { + // Since a pointer index may not occur again (OSs may or may not reuse them), + // imperatively remove it from the map to keep no fossil entries in it + touch_speed_track.erase(st->get_index()); + } - Ref<InputEventScreenTouch> st = p_event; + if (emulate_mouse_from_touch) { - if (st.is_valid()) { bool translate = false; if (st->is_pressed()) { if (mouse_from_touch_index == -1) { @@ -351,10 +368,18 @@ void InputDefault::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool _parse_input_event_impl(button_event, true); } } + } + + Ref<InputEventScreenDrag> sd = p_event; + + if (sd.is_valid()) { + + SpeedTrack &track = touch_speed_track[sd->get_index()]; + track.update(sd->get_relative()); + sd->set_speed(track.speed); - Ref<InputEventScreenDrag> sd = p_event; + if (emulate_mouse_from_touch && sd->get_index() == mouse_from_touch_index) { - if (sd.is_valid() && sd->get_index() == mouse_from_touch_index) { Ref<InputEventMouseMotion> motion_event; motion_event.instance(); diff --git a/main/input_default.h b/main/input_default.h index b420ec124b..4964b9a83c 100644 --- a/main/input_default.h +++ b/main/input_default.h @@ -117,6 +117,7 @@ class InputDefault : public Input { }; SpeedTrack mouse_speed_track; + Map<int, SpeedTrack> touch_speed_track; Map<int, Joypad> joy_names; int fallback_mapping; diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp index d1ef08dc83..44044d2750 100644 --- a/modules/csg/csg_shape.cpp +++ b/modules/csg/csg_shape.cpp @@ -521,6 +521,11 @@ CSGBrush *CSGMesh::_build_brush() { Array arrays = mesh->surface_get_arrays(i); + if (arrays.size() == 0) { + _make_dirty(); + ERR_FAIL_COND_V(arrays.size() == 0, NULL); + } + PoolVector<Vector3> avertices = arrays[Mesh::ARRAY_VERTEX]; if (avertices.size() == 0) continue; diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp index 37e72bf9f8..3e56275396 100644 --- a/modules/gdnative/nativescript/nativescript.cpp +++ b/modules/gdnative/nativescript/nativescript.cpp @@ -1711,8 +1711,7 @@ void NativeReloadNode::_notification(int p_what) { } RES ResourceFormatLoaderNativeScript::load(const String &p_path, const String &p_original_path, Error *r_error) { - ResourceFormatLoaderText rsflt; - return rsflt.load(p_path, p_original_path, r_error); + return ResourceFormatLoaderText::singleton->load(p_path, p_original_path, r_error); } void ResourceFormatLoaderNativeScript::get_recognized_extensions(List<String> *p_extensions) const { diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 48c1760662..4909ac8d92 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -2081,6 +2081,7 @@ GDScriptLanguage::GDScriptLanguage() { #ifdef DEBUG_ENABLED GLOBAL_DEF("debug/gdscript/warnings/enable", true); GLOBAL_DEF("debug/gdscript/warnings/treat_warnings_as_errors", false); + GLOBAL_DEF("debug/gdscript/completion/autocomplete_setters_and_getters", false); for (int i = 0; i < (int)GDScriptWarning::WARNING_MAX; i++) { String warning = GDScriptWarning::get_name_from_code((GDScriptWarning::Code)i).to_lower(); GLOBAL_DEF("debug/gdscript/warnings/" + warning, !warning.begins_with("unsafe_")); diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index 310c4e21f2..45319c59e7 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -1603,13 +1603,13 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo return OK; } -Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser::ClassNode *p_class, const GDScriptParser::FunctionNode *p_func, bool p_for_ready) { +Error GDScriptCompiler::_parse_function(Ref<GDScript> p_script, const GDScriptParser::ClassNode *p_class, const GDScriptParser::FunctionNode *p_func, bool p_for_ready) { Vector<int> bytecode; CodeGen codegen; codegen.class_node = p_class; - codegen.script = p_script; + codegen.script = p_script.ptr(); codegen.function_node = p_func; codegen.stack_max = 0; codegen.current_line = 0; @@ -1853,7 +1853,7 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser return OK; } -Error GDScriptCompiler::_parse_class_level(GDScript *p_script, GDScript *p_owner, const GDScriptParser::ClassNode *p_class, bool p_keep_state) { +Error GDScriptCompiler::_parse_class_level(Ref<GDScript> p_script, Ref<GDScript> p_owner, const GDScriptParser::ClassNode *p_class, bool p_keep_state) { if (p_class->owner && p_class->owner->owner) { // Owner is not root @@ -1887,7 +1887,7 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, GDScript *p_owner p_script->initializer = NULL; p_script->subclasses.clear(); - p_script->_owner = p_owner; + p_script->_owner = p_owner.ptr(); p_script->tool = p_class->tool; p_script->name = p_class->name; @@ -1994,7 +1994,7 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, GDScript *p_owner StringName name = p_class->_signals[i].name; - GDScript *c = p_script; + GDScript *c = p_script.ptr(); while (c) { @@ -2054,7 +2054,7 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, GDScript *p_owner return OK; } -Error GDScriptCompiler::_parse_class_blocks(GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state) { +Error GDScriptCompiler::_parse_class_blocks(Ref<GDScript> p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state) { //parse methods bool has_initializer = false; @@ -2159,7 +2159,7 @@ Error GDScriptCompiler::_parse_class_blocks(GDScript *p_script, const GDScriptPa return OK; } -void GDScriptCompiler::_make_scripts(const GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state) { +void GDScriptCompiler::_make_scripts(const Ref<GDScript> p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state) { Map<StringName, Ref<GDScript> > old_subclasses; @@ -2178,20 +2178,20 @@ void GDScriptCompiler::_make_scripts(const GDScript *p_script, const GDScriptPar subclass.instance(); } - subclass->_owner = const_cast<GDScript *>(p_script); + subclass->_owner = const_cast<GDScript *>(p_script.ptr()); class_map.insert(name, subclass); _make_scripts(subclass.ptr(), p_class->subclasses[i], p_keep_state); } } -Error GDScriptCompiler::compile(const GDScriptParser *p_parser, GDScript *p_script, bool p_keep_state) { +Error GDScriptCompiler::compile(const GDScriptParser *p_parser, Ref<GDScript> p_script, bool p_keep_state) { err_line = -1; err_column = -1; error = ""; parser = p_parser; - main_script = p_script; + main_script = p_script.ptr(); const GDScriptParser::Node *root = parser->get_parse_tree(); ERR_FAIL_COND_V(root->type != GDScriptParser::Node::TYPE_CLASS, ERR_INVALID_DATA); diff --git a/modules/gdscript/gdscript_compiler.h b/modules/gdscript/gdscript_compiler.h index 55f5e2b48e..23c6450aa7 100644 --- a/modules/gdscript/gdscript_compiler.h +++ b/modules/gdscript/gdscript_compiler.h @@ -148,17 +148,17 @@ class GDScriptCompiler { int _parse_assign_right_expression(CodeGen &codegen, const GDScriptParser::OperatorNode *p_expression, int p_stack_level); int _parse_expression(CodeGen &codegen, const GDScriptParser::Node *p_expression, int p_stack_level, bool p_root = false, bool p_initializer = false); Error _parse_block(CodeGen &codegen, const GDScriptParser::BlockNode *p_block, int p_stack_level = 0, int p_break_addr = -1, int p_continue_addr = -1); - Error _parse_function(GDScript *p_script, const GDScriptParser::ClassNode *p_class, const GDScriptParser::FunctionNode *p_func, bool p_for_ready = false); - Error _parse_class_level(GDScript *p_script, GDScript *p_owner, const GDScriptParser::ClassNode *p_class, bool p_keep_state); - Error _parse_class_blocks(GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state); - void _make_scripts(const GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state); + Error _parse_function(Ref<GDScript> p_script, const GDScriptParser::ClassNode *p_class, const GDScriptParser::FunctionNode *p_func, bool p_for_ready = false); + Error _parse_class_level(Ref<GDScript> p_script, Ref<GDScript> p_owner, const GDScriptParser::ClassNode *p_class, bool p_keep_state); + Error _parse_class_blocks(Ref<GDScript> p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state); + void _make_scripts(const Ref<GDScript> p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state); int err_line; int err_column; StringName source; String error; public: - Error compile(const GDScriptParser *p_parser, GDScript *p_script, bool p_keep_state = false); + Error compile(const GDScriptParser *p_parser, Ref<GDScript> p_script, bool p_keep_state = false); String get_error() const; int get_error_line() const; diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index ddd9e6b01c..2ce92f340d 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -1999,7 +1999,8 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context if (!_static) { List<MethodInfo> methods; - ClassDB::get_method_list(type, &methods, false, true); + bool is_autocompleting_getters = GLOBAL_GET("debug/gdscript/completion/autocomplete_setters_and_getters").booleanize(); + ClassDB::get_method_list(type, &methods, false, !is_autocompleting_getters); for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) { if (E->get().name.begins_with("_")) { continue; diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp index f09ff224e8..31115a4bd9 100644 --- a/modules/gdscript/gdscript_function.cpp +++ b/modules/gdscript/gdscript_function.cpp @@ -275,7 +275,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a #endif uint32_t alloca_size = 0; - GDScript *_class; + GDScript *script; int ip = 0; int line = _initial_line; @@ -286,7 +286,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a line = p_state->line; ip = p_state->ip; alloca_size = p_state->stack.size(); - _class = p_state->_class; + script = p_state->script.ptr(); p_instance = p_state->instance; defarg = p_state->defarg; self = p_state->self; @@ -368,9 +368,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a } else { self = p_instance->owner; } - _class = p_instance->script.ptr(); + script = p_instance->script.ptr(); } else { - _class = _script; + script = this->_script.ptr(); } } @@ -395,7 +395,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a #define GET_VARIANT_PTR(m_v, m_code_ofs) \ Variant *m_v; \ - m_v = _get_variant(_code_ptr[ip + m_code_ofs], p_instance, _class, self, stack, err_text); \ + m_v = _get_variant(_code_ptr[ip + m_code_ofs], p_instance, script, self, stack, err_text); \ if (unlikely(!m_v)) \ OPCODE_BREAK; @@ -404,7 +404,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a #define CHECK_SPACE(m_space) #define GET_VARIANT_PTR(m_v, m_code_ofs) \ Variant *m_v; \ - m_v = _get_variant(_code_ptr[ip + m_code_ofs], p_instance, _class, self, stack, err_text); + m_v = _get_variant(_code_ptr[ip + m_code_ofs], p_instance, script, self, stack, err_text); #endif @@ -1185,7 +1185,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a GET_VARIANT_PTR(dst, argc + 3); - const GDScript *gds = _script; + const GDScript *gds = _script.ptr(); const Map<StringName, GDScriptFunction *>::Element *E = NULL; while (gds->base.ptr()) { @@ -1256,11 +1256,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a gdfs->state.stack_size = _stack_size; gdfs->state.self = self; gdfs->state.alloca_size = alloca_size; - gdfs->state._class = _class; + gdfs->state.script = _script; gdfs->state.ip = ip + ipofs; gdfs->state.line = line; gdfs->state.instance_id = (p_instance && p_instance->get_owner()) ? p_instance->get_owner()->get_instance_id() : 0; - gdfs->state.script_id = _class->get_instance_id(); //gdfs->state.result_pos=ip+ipofs-1; gdfs->state.defarg = defarg; gdfs->state.instance = p_instance; @@ -1549,8 +1548,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a String err_file; if (p_instance) err_file = p_instance->script->path; - else if (_class) - err_file = _class->path; + else if (script) + err_file = script->path; if (err_file == "") err_file = "<built-in>"; String err_func = name; @@ -1765,15 +1764,20 @@ GDScriptFunction::~GDScriptFunction() { Variant GDScriptFunctionState::_signal_callback(const Variant **p_args, int p_argcount, Variant::CallError &r_error) { #ifdef DEBUG_ENABLED - if (state.instance_id && !ObjectDB::get_instance(state.instance_id)) { - ERR_EXPLAIN("Resumed after yield, but class instance is gone"); + // Checking this first since it's faster + if (!state.script.is_valid()) { + ERR_EXPLAIN("Resumed after yield, but script is gone"); ERR_FAIL_V(Variant()); } - if (state.script_id && !ObjectDB::get_instance(state.script_id)) { - ERR_EXPLAIN("Resumed after yield, but script is gone"); + if (state.instance_id && !ObjectDB::get_instance(state.instance_id)) { + ERR_EXPLAIN("Resumed after yield, but class instance is gone"); ERR_FAIL_V(Variant()); } +#else + if (!is_valid()) { + return Variant(); + } #endif Variant arg; @@ -1841,12 +1845,12 @@ bool GDScriptFunctionState::is_valid(bool p_extended_check) const { return false; if (p_extended_check) { + //script gone? (checking this first since it's faster) + if (!state.script.is_valid()) + return false; //class instance gone? if (state.instance_id && !ObjectDB::get_instance(state.instance_id)) return false; - //script gone? - if (state.script_id && !ObjectDB::get_instance(state.script_id)) - return false; } return true; @@ -1856,13 +1860,14 @@ Variant GDScriptFunctionState::resume(const Variant &p_arg) { ERR_FAIL_COND_V(!function, Variant()); #ifdef DEBUG_ENABLED - if (state.instance_id && !ObjectDB::get_instance(state.instance_id)) { - ERR_EXPLAIN("Resumed after yield, but class instance is gone"); + // Checking this first since it's faster + if (!state.script.is_valid()) { + ERR_EXPLAIN("Resumed after yield, but script is gone"); ERR_FAIL_V(Variant()); } - if (state.script_id && !ObjectDB::get_instance(state.script_id)) { - ERR_EXPLAIN("Resumed after yield, but script is gone"); + if (state.instance_id && !ObjectDB::get_instance(state.instance_id)) { + ERR_EXPLAIN("Resumed after yield, but class instance is gone"); ERR_FAIL_V(Variant()); } #endif diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h index bfb6d673f1..a47070de4f 100644 --- a/modules/gdscript/gdscript_function.h +++ b/modules/gdscript/gdscript_function.h @@ -225,7 +225,7 @@ private: bool _static; MultiplayerAPI::RPCMode rpc_mode; - GDScript *_script; + Ref<GDScript> _script; StringName name; Vector<Variant> constants; @@ -272,15 +272,13 @@ private: public: struct CallState { - ObjectID instance_id; //by debug only - ObjectID script_id; - + ObjectID instance_id; GDScriptInstance *instance; Vector<uint8_t> stack; int stack_size; Variant self; uint32_t alloca_size; - GDScript *_class; + Ref<GDScript> script; int ip; int line; int defarg; @@ -299,7 +297,7 @@ public: int get_default_argument_addr(int p_idx) const; GDScriptDataType get_return_type() const; GDScriptDataType get_argument_type(int p_idx) const; - GDScript *get_script() const { return _script; } + GDScript *get_script() const { return const_cast<GDScript *>(_script.ptr()); } StringName get_source() const { return source; } void debug_get_stack_member_state(int p_line, List<Pair<StringName, int> > *r_stackvars) const; diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 5f2655eb92..97ac6f7de6 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -6709,9 +6709,15 @@ GDScriptParser::DataType GDScriptParser::_reduce_function_call_type(const Operat } } + bool rets = false; return_type.has_type = true; return_type.kind = DataType::BUILTIN; - return_type.builtin_type = Variant::get_method_return_type(base_type.builtin_type, callee_name); + return_type.builtin_type = Variant::get_method_return_type(base_type.builtin_type, callee_name, &rets); + // If the method returns, but it might return any type, (Variant::NIL), pretend we don't know the type. + // At least make sure we know that it returns + if (rets && return_type.builtin_type == Variant::NIL) { + return_type.has_type = false; + } break; } diff --git a/modules/jpg/image_loader_jpegd.cpp b/modules/jpg/image_loader_jpegd.cpp index a49137ae73..24d40111cf 100644 --- a/modules/jpg/image_loader_jpegd.cpp +++ b/modules/jpg/image_loader_jpegd.cpp @@ -48,9 +48,9 @@ Error jpeg_load_image_from_buffer(Image *p_image, const uint8_t *p_buffer, int p const int image_width = decoder.get_width(); const int image_height = decoder.get_height(); - int comps = decoder.get_num_components(); - if (comps == 3) - comps = 4; //weird + const int comps = decoder.get_num_components(); + if (comps != 1 && comps != 3) + return ERR_FILE_CORRUPT; if (decoder.begin_decoding() != jpgd::JPGD_SUCCESS) return ERR_FILE_CORRUPT; @@ -73,7 +73,19 @@ Error jpeg_load_image_from_buffer(Image *p_image, const uint8_t *p_buffer, int p } jpgd::uint8 *pDst = pImage_data + y * dst_bpl; - memcpy(pDst, pScan_line, dst_bpl); + + if (comps == 1) { + memcpy(pDst, pScan_line, dst_bpl); + } else { + // For images with more than 1 channel pScan_line will always point to a buffer + // containing 32-bit RGBA pixels. Alpha is always 255 and we ignore it. + for (int x = 0; x < image_width; x++) { + pDst[0] = pScan_line[x * 4 + 0]; + pDst[1] = pScan_line[x * 4 + 1]; + pDst[2] = pScan_line[x * 4 + 2]; + pDst += 3; + } + } } //all good @@ -82,7 +94,7 @@ Error jpeg_load_image_from_buffer(Image *p_image, const uint8_t *p_buffer, int p if (comps == 1) fmt = Image::FORMAT_L8; else - fmt = Image::FORMAT_RGBA8; + fmt = Image::FORMAT_RGB8; dw = PoolVector<uint8_t>::Write(); p_image->create(image_width, image_height, 0, fmt, data); diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index 0c4433112d..4d88cca6f1 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -191,7 +191,6 @@ void GDMono::initialize() { String hint_config_dir = path_join(locations[i], "etc"); if (FileAccess::exists(hint_mscorlib_path) && DirAccess::exists(hint_config_dir)) { - need_set_mono_dirs = false; assembly_rootdir = hint_assembly_rootdir; config_dir = hint_config_dir; break; diff --git a/modules/websocket/emws_server.cpp b/modules/websocket/emws_server.cpp index ad4a758c0f..db02162699 100644 --- a/modules/websocket/emws_server.cpp +++ b/modules/websocket/emws_server.cpp @@ -71,6 +71,9 @@ int EMWSServer::get_peer_port(int p_peer_id) const { void EMWSServer::disconnect_peer(int p_peer_id, int p_code, String p_reason) { } +void EMWSServer::poll() { +} + EMWSServer::EMWSServer() { } diff --git a/modules/websocket/lws_client.cpp b/modules/websocket/lws_client.cpp index add3931b50..d71d091720 100644 --- a/modules/websocket/lws_client.cpp +++ b/modules/websocket/lws_client.cpp @@ -34,10 +34,6 @@ #include "core/io/stream_peer_ssl.h" #include "tls/mbedtls/wrapper/include/openssl/ssl.h" -#if defined(MINGW_ENABLED) || defined(_MSC_VER) -#define strncpy strncpy_s -#endif - Error LWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, PoolVector<String> p_protocols) { ERR_FAIL_COND_V(context != NULL, FAILED); @@ -80,26 +76,11 @@ Error LWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port, ERR_FAIL_V(FAILED); } - char abuf[1024]; - char hbuf[1024]; - char pbuf[2048]; - String addr_str = (String)addr; - strncpy(abuf, addr_str.ascii().get_data(), 1023); - abuf[1023] = '\0'; - strncpy(hbuf, p_host.utf8().get_data(), 1023); - hbuf[1023] = '\0'; - strncpy(pbuf, p_path.utf8().get_data(), 2047); - pbuf[2047] = '\0'; - i.context = context; if (p_protocols.size() > 0) i.protocol = _lws_ref->lws_names; else i.protocol = NULL; - i.address = abuf; - i.host = hbuf; - i.path = pbuf; - i.port = p_port; if (p_ssl) { i.ssl_connection = LCCSCF_USE_SSL; @@ -109,7 +90,16 @@ Error LWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port, i.ssl_connection = 0; } + // This String needs to survive till we call lws_client_connect_via_info + String addr_str = (String)addr; + + i.address = addr_str.ascii().get_data(); + i.host = p_host.utf8().get_data(); + i.path = p_path.utf8().get_data(); + i.port = p_port; + lws_client_connect_via_info(&i); + return OK; }; diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index 30bc413459..8e050c1d27 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -586,7 +586,7 @@ Error OS_Android::shell_open(String p_uri) { String OS_Android::get_resource_dir() const { - return "/"; //android has it's own filesystem for resources inside the APK + return "/"; //android has its own filesystem for resources inside the APK } String OS_Android::get_locale() const { diff --git a/platform/javascript/engine.js b/platform/javascript/engine.js index c3ef5bbbb5..91458eb4c3 100644 --- a/platform/javascript/engine.js +++ b/platform/javascript/engine.js @@ -1,3 +1,6 @@ + // The following is concatenated with generated code, and acts as the end + // of a wrapper for said code. See pre.js for the other part of the + // wrapper. exposedLibs['PATH'] = PATH; exposedLibs['FS'] = FS; return Module; diff --git a/platform/javascript/pre.js b/platform/javascript/pre.js index 02194bc75e..a870e676ea 100644 --- a/platform/javascript/pre.js +++ b/platform/javascript/pre.js @@ -1,2 +1,5 @@ var Engine = { RuntimeEnvironment: function(Module, exposedLibs) { + // The above is concatenated with generated code, and acts as the start of + // a wrapper for said code. See engine.js for the other part of the + // wrapper. diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index 6ab433203f..70b49805d2 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -100,12 +100,13 @@ static int prev_mouse_y = 0; static int button_mask = 0; static bool mouse_down_control = false; -static Vector2 get_mouse_pos(NSEvent *event) { +static Vector2 get_mouse_pos(NSPoint locationInWindow, CGFloat backingScaleFactor) { const NSRect contentRect = [OS_OSX::singleton->window_view frame]; - const NSPoint p = [event locationInWindow]; - mouse_x = p.x * OS_OSX::singleton->_mouse_scale([[event window] backingScaleFactor]); - mouse_y = (contentRect.size.height - p.y) * OS_OSX::singleton->_mouse_scale([[event window] backingScaleFactor]); + const NSPoint p = locationInWindow; + const float s = OS_OSX::singleton->_mouse_scale(backingScaleFactor); + mouse_x = p.x * s; + mouse_y = (contentRect.size.height - p.y) * s; return Vector2(mouse_x, mouse_y); } @@ -325,6 +326,13 @@ static Vector2 get_mouse_pos(NSEvent *event) { - (void)windowDidBecomeKey:(NSNotification *)notification { //_GodotInputWindowFocus(window, GL_TRUE); //_GodotPlatformSetCursorMode(window, window->cursorMode); + [OS_OSX::singleton->context update]; + + get_mouse_pos( + [OS_OSX::singleton->window_object mouseLocationOutsideOfEventStream], + [OS_OSX::singleton->window_view backingScaleFactor]); + OS_OSX::singleton->input->set_mouse_position(Point2(mouse_x, mouse_y)); + if (OS_OSX::singleton->get_main_loop()) OS_OSX::singleton->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN); } @@ -593,12 +601,13 @@ static void _mouseDownEvent(NSEvent *event, int index, int mask, bool pressed) { mm->set_button_mask(button_mask); prev_mouse_x = mouse_x; prev_mouse_y = mouse_y; - const Vector2 pos = get_mouse_pos(event); + const CGFloat backingScaleFactor = [[event window] backingScaleFactor]; + const Vector2 pos = get_mouse_pos([event locationInWindow], backingScaleFactor); mm->set_position(pos); mm->set_global_position(pos); Vector2 relativeMotion = Vector2(); - relativeMotion.x = [event deltaX] * OS_OSX::singleton -> _mouse_scale([[event window] backingScaleFactor]); - relativeMotion.y = [event deltaY] * OS_OSX::singleton -> _mouse_scale([[event window] backingScaleFactor]); + relativeMotion.x = [event deltaX] * OS_OSX::singleton -> _mouse_scale(backingScaleFactor); + relativeMotion.y = [event deltaY] * OS_OSX::singleton -> _mouse_scale(backingScaleFactor); mm->set_relative(relativeMotion); get_key_modifier_state([event modifierFlags], mm); @@ -681,7 +690,7 @@ static void _mouseDownEvent(NSEvent *event, int index, int mask, bool pressed) { Ref<InputEventMagnifyGesture> ev; ev.instance(); get_key_modifier_state([event modifierFlags], ev); - ev->set_position(get_mouse_pos(event)); + ev->set_position(get_mouse_pos([event locationInWindow], [[event window] backingScaleFactor])); ev->set_factor([event magnification] + 1.0); OS_OSX::singleton->push_input(ev); } @@ -1073,6 +1082,8 @@ inline void sendPanEvent(double dx, double dy, int modifierFlags) { - (void)scrollWheel:(NSEvent *)event { double deltaX, deltaY; + get_mouse_pos([event locationInWindow], [[event window] backingScaleFactor]); + deltaX = [event scrollingDeltaX]; deltaY = [event scrollingDeltaY]; diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 7c4c8f0eff..88c2c8aec6 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -2095,7 +2095,7 @@ void OS_X11::process_xevents() { last_timestamp = event.xkey.time; // key event is a little complex, so - // it will be handled in it's own function. + // it will be handled in its own function. handle_key_event((XKeyEvent *)&event); } break; case SelectionRequest: { diff --git a/scene/3d/arvr_nodes.cpp b/scene/3d/arvr_nodes.cpp index 4bff26a200..2dc500f7ab 100644 --- a/scene/3d/arvr_nodes.cpp +++ b/scene/3d/arvr_nodes.cpp @@ -38,14 +38,14 @@ void ARVRCamera::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { - // need to find our ARVROrigin parent and let it know we're it's camera! + // need to find our ARVROrigin parent and let it know we're its camera! ARVROrigin *origin = Object::cast_to<ARVROrigin>(get_parent()); if (origin != NULL) { origin->set_tracked_camera(this); } }; break; case NOTIFICATION_EXIT_TREE: { - // need to find our ARVROrigin parent and let it know we're no longer it's camera! + // need to find our ARVROrigin parent and let it know we're no longer its camera! ARVROrigin *origin = Object::cast_to<ARVROrigin>(get_parent()); if (origin != NULL) { origin->clear_tracked_camera_if(this); diff --git a/scene/3d/arvr_nodes.h b/scene/3d/arvr_nodes.h index 67fb658562..d6690676cc 100644 --- a/scene/3d/arvr_nodes.h +++ b/scene/3d/arvr_nodes.h @@ -62,7 +62,7 @@ public: }; /* - ARVRController is a helper node that automatically updates it's position based on tracker data. + ARVRController is a helper node that automatically updates its position based on tracker data. It must be a child node of our ARVROrigin node */ @@ -102,7 +102,7 @@ public: }; /* - ARVRAnchor is a helper node that automatically updates it's position based on anchor data, it represents a real world location. + ARVRAnchor is a helper node that automatically updates its position based on anchor data, it represents a real world location. It must be a child node of our ARVROrigin node */ diff --git a/scene/3d/light.cpp b/scene/3d/light.cpp index 7e1d60ab8e..11d61315ba 100644 --- a/scene/3d/light.cpp +++ b/scene/3d/light.cpp @@ -163,11 +163,6 @@ void Light::_update_visibility() { if (!is_inside_tree()) return; - // FIXME: Since the call to VS::instance_light_set_enabled was disabled below, - // the whole logic became pointless so editor_ok triggers unused variable warnings. - // Commenting out for now but this should be fixed/reimplemented so that editor_only - // works as expected (GH-17989). - /* bool editor_ok = true; #ifdef TOOLS_ENABLED @@ -184,8 +179,8 @@ void Light::_update_visibility() { } #endif - //VS::get_singleton()->instance_light_set_enabled(get_instance(),is_visible_in_tree() && editor_ok); - */ + VS::get_singleton()->instance_set_visible(get_instance(), is_visible_in_tree() && editor_ok); + _change_notify("geometry/visible"); } diff --git a/scene/3d/mesh_instance.cpp b/scene/3d/mesh_instance.cpp index 4cbf6f2de3..cf0317cd58 100644 --- a/scene/3d/mesh_instance.cpp +++ b/scene/3d/mesh_instance.cpp @@ -253,6 +253,11 @@ void MeshInstance::_notification(int p_what) { } } +int MeshInstance::get_surface_material_count() const { + + return materials.size(); +} + void MeshInstance::set_surface_material(int p_surface, const Ref<Material> &p_material) { ERR_FAIL_INDEX(p_surface, materials.size()); @@ -359,6 +364,7 @@ void MeshInstance::_bind_methods() { ClassDB::bind_method(D_METHOD("set_skeleton_path", "skeleton_path"), &MeshInstance::set_skeleton_path); ClassDB::bind_method(D_METHOD("get_skeleton_path"), &MeshInstance::get_skeleton_path); + ClassDB::bind_method(D_METHOD("get_surface_material_count"), &MeshInstance::get_surface_material_count); ClassDB::bind_method(D_METHOD("set_surface_material", "surface", "material"), &MeshInstance::set_surface_material); ClassDB::bind_method(D_METHOD("get_surface_material", "surface"), &MeshInstance::get_surface_material); diff --git a/scene/3d/mesh_instance.h b/scene/3d/mesh_instance.h index 0dfec538f9..0b5b4b9e7b 100644 --- a/scene/3d/mesh_instance.h +++ b/scene/3d/mesh_instance.h @@ -76,6 +76,7 @@ public: void set_skeleton_path(const NodePath &p_skeleton); NodePath get_skeleton_path(); + int get_surface_material_count() const; void set_surface_material(int p_surface, const Ref<Material> &p_material); Ref<Material> get_surface_material(int p_surface) const; diff --git a/scene/3d/path.cpp b/scene/3d/path.cpp index e37efa0e8a..339a434a6e 100644 --- a/scene/3d/path.cpp +++ b/scene/3d/path.cpp @@ -43,6 +43,16 @@ void Path::_curve_changed() { if (is_inside_tree()) { emit_signal("curve_changed"); } + + // update the configuration warnings of all children of type OrientedPathFollows + if (is_inside_tree()) { + for (int i = 0; i < get_child_count(); i++) { + OrientedPathFollow *child = Object::cast_to<OrientedPathFollow>(get_child(i)); + if (child) { + child->update_configuration_warning(); + } + } + } } void Path::set_curve(const Ref<Curve3D> &p_curve) { @@ -207,6 +217,18 @@ void PathFollow::_validate_property(PropertyInfo &property) const { } } +String PathFollow::get_configuration_warning() const { + + if (!is_visible_in_tree() || !is_inside_tree()) + return String(); + + if (!Object::cast_to<Path>(get_parent())) { + return TTR("PathFollow only works when set as a child of a Path node."); + } + + return String(); +} + void PathFollow::_bind_methods() { ClassDB::bind_method(D_METHOD("set_offset", "offset"), &PathFollow::set_offset); @@ -444,6 +466,23 @@ void OrientedPathFollow::_validate_property(PropertyInfo &property) const { } } +String OrientedPathFollow::get_configuration_warning() const { + + if (!is_visible_in_tree() || !is_inside_tree()) + return String(); + + if (!Object::cast_to<Path>(get_parent())) { + return TTR("OrientedPathFollow only works when set as a child of a Path node."); + } else { + Path *path = Object::cast_to<Path>(get_parent()); + if (path->get_curve().is_valid() && !path->get_curve()->is_up_vector_enabled()) { + return TTR("OrientedPathFollow requires up vectors enabled in its parent Path."); + } + } + + return String(); +} + void OrientedPathFollow::_bind_methods() { ClassDB::bind_method(D_METHOD("set_offset", "offset"), &OrientedPathFollow::set_offset); diff --git a/scene/3d/path.h b/scene/3d/path.h index f73bf17dfe..beb37d9714 100644 --- a/scene/3d/path.h +++ b/scene/3d/path.h @@ -106,6 +106,8 @@ public: void set_cubic_interpolation(bool p_enable); bool get_cubic_interpolation() const; + String get_configuration_warning() const; + PathFollow(); }; @@ -151,6 +153,8 @@ public: void set_cubic_interpolation(bool p_enable); bool get_cubic_interpolation() const; + String get_configuration_warning() const; + OrientedPathFollow(); }; diff --git a/scene/3d/voxel_light_baker.cpp b/scene/3d/voxel_light_baker.cpp index 541f6047d9..0eccbbc8f9 100644 --- a/scene/3d/voxel_light_baker.cpp +++ b/scene/3d/voxel_light_baker.cpp @@ -261,7 +261,7 @@ static _FORCE_INLINE_ void get_uv_and_normal(const Vector3 &p_pos, const Vector3 void VoxelLightBaker::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, const Vector3 *p_vtx, const Vector3 *p_normal, const Vector2 *p_uv, const MaterialCache &p_material, const AABB &p_aabb) { if (p_level == cell_subdiv - 1) { - //plot the face by guessing it's albedo and emission value + //plot the face by guessing its albedo and emission value //find best axis to map to, for scanning values int closest_axis = 0; diff --git a/scene/gui/gradient_edit.cpp b/scene/gui/gradient_edit.cpp index 934b84ec0c..c13964d196 100644 --- a/scene/gui/gradient_edit.cpp +++ b/scene/gui/gradient_edit.cpp @@ -236,8 +236,8 @@ void GradientEdit::_gui_input(const Ref<InputEvent> &p_event) { //Snap to nearest point if holding shift if (mm->get_shift()) { - float snap_treshhold = 0.03; - float smallest_ofs = snap_treshhold; + float snap_threshold = 0.03; + float smallest_ofs = snap_threshold; bool found = false; int nearest_point = 0; for (int i = 0; i < points.size(); ++i) { diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 6f344f1028..c4373876b1 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -1608,6 +1608,8 @@ LineEdit::LineEdit() { text_changed_dirty = false; placeholder_alpha = 0.6; clear_button_enabled = false; + clear_button_status.press_attempt = false; + clear_button_status.pressing_inside = false; deselect(); set_focus_mode(FOCUS_ALL); diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp index c56b7d0f26..b7f8c74046 100644 --- a/scene/gui/tabs.cpp +++ b/scene/gui/tabs.cpp @@ -106,41 +106,8 @@ void Tabs::_gui_input(const Ref<InputEvent> &p_event) { } } - // test hovering to display right or close button - int hover_now = -1; - int hover_buttons = -1; - for (int i = 0; i < tabs.size(); i++) { - - if (i < offset) - continue; - - Rect2 rect = get_tab_rect(i); - if (rect.has_point(pos)) { - hover_now = i; - } - if (tabs[i].rb_rect.has_point(pos)) { - rb_hover = i; - cb_hover = -1; - hover_buttons = i; - break; - } else if (!tabs[i].disabled && tabs[i].cb_rect.has_point(pos)) { - cb_hover = i; - rb_hover = -1; - hover_buttons = i; - break; - } - } - if (hover != hover_now) { - hover = hover_now; - emit_signal("tab_hover", hover); - } - - if (hover_buttons == -1) { // no hover - rb_hover = hover_buttons; - cb_hover = hover_buttons; - } + _update_hover(); update(); - return; } @@ -522,6 +489,48 @@ Ref<Texture> Tabs::get_tab_right_button(int p_tab) const { return tabs[p_tab].right_button; } +void Tabs::_update_hover() { + + if (!is_inside_tree()) { + return; + } + + const Point2 &pos = get_local_mouse_position(); + // test hovering to display right or close button + int hover_now = -1; + int hover_buttons = -1; + for (int i = 0; i < tabs.size(); i++) { + + if (i < offset) + continue; + + Rect2 rect = get_tab_rect(i); + if (rect.has_point(pos)) { + hover_now = i; + } + if (tabs[i].rb_rect.has_point(pos)) { + rb_hover = i; + cb_hover = -1; + hover_buttons = i; + break; + } else if (!tabs[i].disabled && tabs[i].cb_rect.has_point(pos)) { + cb_hover = i; + rb_hover = -1; + hover_buttons = i; + break; + } + } + if (hover != hover_now) { + hover = hover_now; + emit_signal("tab_hover", hover); + } + + if (hover_buttons == -1) { // no hover + rb_hover = hover_buttons; + cb_hover = hover_buttons; + } +} + void Tabs::_update_cache() { Ref<StyleBox> tab_disabled = get_stylebox("tab_disabled"); Ref<StyleBox> tab_bg = get_stylebox("tab_bg"); @@ -597,6 +606,7 @@ void Tabs::add_tab(const String &p_str, const Ref<Texture> &p_icon) { tabs.push_back(t); _update_cache(); + call_deferred("_update_hover"); update(); minimum_size_changed(); } @@ -604,6 +614,7 @@ void Tabs::add_tab(const String &p_str, const Ref<Texture> &p_icon) { void Tabs::clear_tabs() { tabs.clear(); current = 0; + call_deferred("_update_hover"); update(); } @@ -614,6 +625,7 @@ void Tabs::remove_tab(int p_idx) { if (current >= p_idx) current--; _update_cache(); + call_deferred("_update_hover"); update(); minimum_size_changed(); @@ -931,6 +943,7 @@ bool Tabs::get_select_with_rmb() const { void Tabs::_bind_methods() { ClassDB::bind_method(D_METHOD("_gui_input"), &Tabs::_gui_input); + ClassDB::bind_method(D_METHOD("_update_hover"), &Tabs::_update_hover); ClassDB::bind_method(D_METHOD("get_tab_count"), &Tabs::get_tab_count); ClassDB::bind_method(D_METHOD("set_current_tab", "tab_idx"), &Tabs::set_current_tab); ClassDB::bind_method(D_METHOD("get_current_tab"), &Tabs::get_current_tab); diff --git a/scene/gui/tabs.h b/scene/gui/tabs.h index e204f4364b..a98744b804 100644 --- a/scene/gui/tabs.h +++ b/scene/gui/tabs.h @@ -97,6 +97,8 @@ private: int get_tab_width(int p_idx) const; void _ensure_no_over_offset(); + + void _update_hover(); void _update_cache(); protected: diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 8fd7dc1d7b..50e94e6db5 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -2192,7 +2192,7 @@ void Node::_duplicate_signals(const Node *p_original, Node *p_copy) const { if (p_copy->has_node(ptarget)) copytarget = p_copy->get_node(ptarget); - if (copy && copytarget) { + if (copy && copytarget && !copy->is_connected(E->get().signal, copytarget, E->get().method)) { copy->connect(E->get().signal, copytarget, E->get().method, E->get().binds, E->get().flags); } } diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index 086fb83af9..42ce9d10cd 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -264,7 +264,7 @@ Node *SceneState::instance(GenEditState p_edit_state) const { } if (n.instance >= 0 || n.type != TYPE_INSTANCED || i == 0) { - //if node was not part of instance, must set it's name, parenthood and ownership + //if node was not part of instance, must set its name, parenthood and ownership if (i > 0) { if (parent) { parent->_add_child_nocheck(node, snames[n.name]); diff --git a/servers/audio/audio_stream.cpp b/servers/audio/audio_stream.cpp index 7de0695e8c..02a0bed964 100644 --- a/servers/audio/audio_stream.cpp +++ b/servers/audio/audio_stream.cpp @@ -136,16 +136,20 @@ void AudioStreamPlaybackMicrophone::_mix_internal(AudioFrame *p_buffer, int p_fr Vector<int32_t> buf = AudioDriver::get_singleton()->get_input_buffer(); unsigned int input_size = AudioDriver::get_singleton()->get_input_size(); + int mix_rate = AudioDriver::get_singleton()->get_mix_rate(); + int playback_delay = MIN(((50 * mix_rate) / 1000) * 2, buf.size() >> 1); +#ifdef DEBUG_ENABLED + unsigned int input_position = AudioDriver::get_singleton()->get_input_position(); +#endif - // p_frames is multiplied by two since an AudioFrame is stereo - if ((p_frames + MICROPHONE_PLAYBACK_DELAY * 2) > input_size) { + if (playback_delay > input_size) { for (int i = 0; i < p_frames; i++) { p_buffer[i] = AudioFrame(0.0f, 0.0f); } input_ofs = 0; } else { for (int i = 0; i < p_frames; i++) { - if (input_size >= input_ofs) { + if (input_size > input_ofs) { float l = (buf[input_ofs++] >> 16) / 32768.f; if (input_ofs >= buf.size()) { input_ofs = 0; @@ -162,6 +166,12 @@ void AudioStreamPlaybackMicrophone::_mix_internal(AudioFrame *p_buffer, int p_fr } } +#ifdef DEBUG_ENABLED + if (input_ofs > input_position && (input_ofs - input_position) < (p_frames * 2)) { + print_verbose(String(get_class_name()) + " buffer underrun: input_position=" + itos(input_position) + " input_ofs=" + itos(input_ofs) + " input_size=" + itos(input_size)); + } +#endif + AudioDriver::get_singleton()->unlock(); } diff --git a/servers/audio/audio_stream.h b/servers/audio/audio_stream.h index 2740f86d55..f6ed45cc9c 100644 --- a/servers/audio/audio_stream.h +++ b/servers/audio/audio_stream.h @@ -122,8 +122,6 @@ class AudioStreamPlaybackMicrophone : public AudioStreamPlaybackResampled { GDCLASS(AudioStreamPlaybackMicrophone, AudioStreamPlayback) friend class AudioStreamMicrophone; - static const int MICROPHONE_PLAYBACK_DELAY = 256; - bool active; unsigned int input_ofs; diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp index d36057b465..37454d9253 100644 --- a/servers/audio_server.cpp +++ b/servers/audio_server.cpp @@ -80,6 +80,14 @@ double AudioDriver::get_mix_time() const { return total; } +void AudioDriver::input_buffer_init(int driver_buffer_frames) { + + const int input_buffer_channels = 2; + input_buffer.resize(driver_buffer_frames * input_buffer_channels * 4); + input_position = 0; + input_size = 0; +} + void AudioDriver::input_buffer_write(int32_t sample) { input_buffer.write[input_position++] = sample; diff --git a/servers/audio_server.h b/servers/audio_server.h index ba6569eb38..b12ca6e589 100644 --- a/servers/audio_server.h +++ b/servers/audio_server.h @@ -59,6 +59,7 @@ protected: void audio_server_process(int p_frames, int32_t *p_buffer, bool p_update_mix_time = true); void update_mix_time(int p_frames); + void input_buffer_init(int driver_buffer_frames); void input_buffer_write(int32_t sample); #ifdef DEBUG_ENABLED diff --git a/servers/physics/collision_solver_sat.cpp b/servers/physics/collision_solver_sat.cpp index 087ae570fb..f17f6f7014 100644 --- a/servers/physics/collision_solver_sat.cpp +++ b/servers/physics/collision_solver_sat.cpp @@ -98,7 +98,6 @@ static void _generate_contacts_edge_edge(const Vector3 *p_points_A, int p_point_ Vector3 c = rel_A.cross(rel_B).cross(rel_B); - //if ( Math::abs(rel_A.dot(c) )<_EDGE_IS_VALID_SUPPORT_TRESHOLD ) { if (Math::abs(rel_A.dot(c)) < CMP_EPSILON) { // should handle somehow.. |