diff options
22 files changed, 1445 insertions, 786 deletions
diff --git a/core/templates/bin_sorted_array.h b/core/templates/bin_sorted_array.h new file mode 100644 index 0000000000..be9d0b5475 --- /dev/null +++ b/core/templates/bin_sorted_array.h @@ -0,0 +1,181 @@ +/*************************************************************************/ +/*  bin_sorted_array.h                                                   */ +/*************************************************************************/ +/*                       This file is part of:                           */ +/*                           GODOT ENGINE                                */ +/*                      https://godotengine.org                          */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.                 */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).   */ +/*                                                                       */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the       */ +/* "Software"), to deal in the Software without restriction, including   */ +/* without limitation the rights to use, copy, modify, merge, publish,   */ +/* distribute, sublicense, and/or sell copies of the Software, and to    */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions:                                             */ +/*                                                                       */ +/* The above copyright notice and this permission notice shall be        */ +/* included in all copies or substantial portions of the Software.       */ +/*                                                                       */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */ +/*************************************************************************/ + +#ifndef BIN_SORTED_ARRAY_H +#define BIN_SORTED_ARRAY_H + +#include "core/templates/local_vector.h" +#include "core/templates/paged_array.h" + +template <class T> +class BinSortedArray { +	PagedArray<T> array; +	LocalVector<uint64_t> bin_limits; + +	// Implement if elements need to keep track of their own index in the array. +	_FORCE_INLINE_ virtual void _update_idx(T &r_element, uint64_t p_idx) {} + +	_FORCE_INLINE_ void _swap(uint64_t p_a, uint64_t p_b) { +		SWAP(array[p_a], array[p_b]); +		_update_idx(array[p_a], p_a); +		_update_idx(array[p_b], p_b); +	} + +public: +	uint64_t insert(T &p_element, uint64_t p_bin) { +		array.push_back(p_element); +		uint64_t new_idx = array.size() - 1; +		_update_idx(p_element, new_idx); +		bin_limits[0] = new_idx; +		if (p_bin != 0) { +			new_idx = move(new_idx, p_bin); +		} +		return new_idx; +	} + +	uint64_t move(uint64_t p_idx, uint64_t p_bin) { +		ERR_FAIL_COND_V(p_idx >= array.size(), -1); + +		uint64_t current_bin = bin_limits.size() - 1; +		while (p_idx > bin_limits[current_bin]) { +			current_bin--; +		} + +		if (p_bin == current_bin) { +			return p_idx; +		} + +		uint64_t current_idx = p_idx; +		if (p_bin > current_bin) { +			while (p_bin > current_bin) { +				uint64_t swap_idx = 0; + +				if (current_bin == bin_limits.size() - 1) { +					bin_limits.push_back(0); +				} else { +					bin_limits[current_bin + 1]++; +					swap_idx = bin_limits[current_bin + 1]; +				} + +				if (current_idx != swap_idx) { +					_swap(current_idx, swap_idx); +					current_idx = swap_idx; +				} + +				current_bin++; +			} +		} else { +			while (p_bin < current_bin) { +				uint64_t swap_idx = bin_limits[current_bin]; + +				if (current_idx != swap_idx) { +					_swap(current_idx, swap_idx); +				} + +				if (current_bin == bin_limits.size() - 1 && bin_limits[current_bin] == 0) { +					bin_limits.resize(bin_limits.size() - 1); +				} else { +					bin_limits[current_bin]--; +				} +				current_idx = swap_idx; +				current_bin--; +			} +		} + +		return current_idx; +	} + +	void remove(uint64_t p_idx) { +		ERR_FAIL_COND(p_idx >= array.size()); +		uint64_t new_idx = move(p_idx, 0); +		uint64_t swap_idx = array.size() - 1; + +		if (new_idx != swap_idx) { +			_swap(new_idx, swap_idx); +		} + +		if (bin_limits[0] > 0) { +			bin_limits[0]--; +		} + +		array.pop_back(); +	} + +	void set_page_pool(PagedArrayPool<T> *p_page_pool) { +		array.set_page_pool(p_page_pool); +	} + +	_FORCE_INLINE_ const T &operator[](uint64_t p_index) const { +		return array[p_index]; +	} + +	_FORCE_INLINE_ T &operator[](uint64_t p_index) { +		return array[p_index]; +	} + +	int get_bin_count() { +		if (array.size() == 0) { +			return 0; +		} +		return bin_limits.size(); +	} + +	int get_bin_start(int p_bin) { +		ERR_FAIL_COND_V(p_bin >= get_bin_count(), ~0U); +		if ((unsigned int)p_bin == bin_limits.size() - 1) { +			return 0; +		} +		return bin_limits[p_bin + 1] + 1; +	} + +	int get_bin_size(int p_bin) { +		ERR_FAIL_COND_V(p_bin >= get_bin_count(), 0); +		if ((unsigned int)p_bin == bin_limits.size() - 1) { +			return bin_limits[p_bin] + 1; +		} +		return bin_limits[p_bin] - bin_limits[p_bin + 1]; +	} + +	void reset() { +		array.reset(); +		bin_limits.clear(); +		bin_limits.push_back(0); +	} + +	BinSortedArray() { +		bin_limits.push_back(0); +	} + +	virtual ~BinSortedArray() { +		reset(); +	} +}; + +#endif //BIN_SORTED_ARRAY_H diff --git a/doc/classes/GeometryInstance3D.xml b/doc/classes/GeometryInstance3D.xml index b2c3bfc3ed..667ca2dacf 100644 --- a/doc/classes/GeometryInstance3D.xml +++ b/doc/classes/GeometryInstance3D.xml @@ -52,25 +52,21 @@  		</member>  		<member name="lod_bias" type="float" setter="set_lod_bias" getter="get_lod_bias" default="1.0">  		</member> -		<member name="lod_max_distance" type="float" setter="set_lod_max_distance" getter="get_lod_max_distance" default="0.0"> -			The GeometryInstance3D's max LOD distance. -			[b]Note:[/b] This property currently has no effect. +		<member name="material_override" type="Material" setter="set_material_override" getter="get_material_override"> +			The material override for the whole geometry. +			If a material is assigned to this property, it will be used instead of any material set in any material slot of the mesh.  		</member> -		<member name="lod_max_hysteresis" type="float" setter="set_lod_max_hysteresis" getter="get_lod_max_hysteresis" default="0.0"> -			The GeometryInstance3D's max LOD margin. -			[b]Note:[/b] This property currently has no effect. +		<member name="visibility_range_begin" type="float" setter="set_visibility_range_begin" getter="get_visibility_range_begin" default="0.0"> +			Starting distance from which the GeometryInstance3D will be visible, taking [member visibility_range_begin_margin] into account as well. The default value of 0 is used to disable the range check.  		</member> -		<member name="lod_min_distance" type="float" setter="set_lod_min_distance" getter="get_lod_min_distance" default="0.0"> -			The GeometryInstance3D's min LOD distance. -			[b]Note:[/b] This property currently has no effect. +		<member name="visibility_range_begin_margin" type="float" setter="set_visibility_range_begin_margin" getter="get_visibility_range_begin_margin" default="0.0"> +			Margin for the [member visibility_range_begin] threshold. The GeometryInstance3D will only change its visibility state when it goes over or under the [member visibility_range_begin] threshold by this amount.  		</member> -		<member name="lod_min_hysteresis" type="float" setter="set_lod_min_hysteresis" getter="get_lod_min_hysteresis" default="0.0"> -			The GeometryInstance3D's min LOD margin. -			[b]Note:[/b] This property currently has no effect. +		<member name="visibility_range_end" type="float" setter="set_visibility_range_end" getter="get_visibility_range_end" default="0.0"> +			Distance from which the GeometryInstance3D will be hidden, taking [member visibility_range_end_margin] into account as well. The default value of 0 is used to disable the range check..  		</member> -		<member name="material_override" type="Material" setter="set_material_override" getter="get_material_override"> -			The material override for the whole geometry. -			If a material is assigned to this property, it will be used instead of any material set in any material slot of the mesh. +		<member name="visibility_range_end_margin" type="float" setter="set_visibility_range_end_margin" getter="get_visibility_range_end_margin" default="0.0"> +			Margin for the [member visibility_range_end] threshold. The GeometryInstance3D will only change its visibility state when it goes over or under the [member visibility_range_end] threshold by this amount.  		</member>  	</members>  	<constants> diff --git a/doc/classes/Node3D.xml b/doc/classes/Node3D.xml index a6237708c6..1c161803db 100644 --- a/doc/classes/Node3D.xml +++ b/doc/classes/Node3D.xml @@ -20,7 +20,7 @@  				Forces the transform to update. Transform changes in physics are not instant for performance reasons. Transforms are accumulated and then set. Use this if you need an up-to-date transform when doing physics operations.  			</description>  		</method> -		<method name="get_parent_spatial" qualifiers="const"> +		<method name="get_parent_node_3d" qualifiers="const">  			<return type="Node3D">  			</return>  			<description> @@ -310,6 +310,9 @@  		<member name="transform" type="Transform3D" setter="set_transform" getter="get_transform" default="Transform3D( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )">  			Local space [Transform3D] of this node, with respect to the parent node.  		</member> +		<member name="visibility_parent" type="NodePath" setter="set_visibility_parent" getter="get_visibility_parent" default="NodePath("")"> +			Defines the visibility range parent for this node and its subtree. The visibility parent must be a GeometryInstance3D. Any visual instance will only be visible if the visibility parent (and all of its visibility ancestors) is hidden by being closer to the camera than its own [member GeometryInstance3D.visibility_range_begin]. Nodes hidden via the [member Node3D.visible] property are essentially removed from the visibility dependency tree, so dependant instances will not take the hidden node or its ancestors into account. +		</member>  		<member name="visible" type="bool" setter="set_visible" getter="is_visible" default="true">  			If [code]true[/code], this node is drawn. The node is only visible if all of its antecedents are visible as well (in other words, [method is_visible_in_tree] must return [code]true[/code]).  		</member> diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index ba19176788..9b9644093f 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -1175,17 +1175,6 @@  				Once finished with your RID, you will want to free the RID using the RenderingServer's [method free_rid] static method.  			</description>  		</method> -		<method name="instance_geometry_set_as_instance_lod"> -			<return type="void"> -			</return> -			<argument index="0" name="instance" type="RID"> -			</argument> -			<argument index="1" name="as_lod_of_instance" type="RID"> -			</argument> -			<description> -				Not implemented in Godot 3.x. -			</description> -		</method>  		<method name="instance_geometry_set_cast_shadows_setting">  			<return type="void">  			</return> @@ -1197,45 +1186,45 @@  				Sets the shadow casting setting to one of [enum ShadowCastingSetting]. Equivalent to [member GeometryInstance3D.cast_shadow].  			</description>  		</method> -		<method name="instance_geometry_set_draw_range"> +		<method name="instance_geometry_set_flag">  			<return type="void">  			</return>  			<argument index="0" name="instance" type="RID">  			</argument> -			<argument index="1" name="min" type="float"> -			</argument> -			<argument index="2" name="max" type="float"> -			</argument> -			<argument index="3" name="min_margin" type="float"> +			<argument index="1" name="flag" type="int" enum="RenderingServer.InstanceFlags">  			</argument> -			<argument index="4" name="max_margin" type="float"> +			<argument index="2" name="enabled" type="bool">  			</argument>  			<description> -				Not implemented in Godot 3.x. +				Sets the flag for a given [enum InstanceFlags]. See [enum InstanceFlags] for more details.  			</description>  		</method> -		<method name="instance_geometry_set_flag"> +		<method name="instance_geometry_set_material_override">  			<return type="void">  			</return>  			<argument index="0" name="instance" type="RID">  			</argument> -			<argument index="1" name="flag" type="int" enum="RenderingServer.InstanceFlags"> -			</argument> -			<argument index="2" name="enabled" type="bool"> +			<argument index="1" name="material" type="RID">  			</argument>  			<description> -				Sets the flag for a given [enum InstanceFlags]. See [enum InstanceFlags] for more details. +				Sets a material that will override the material for all surfaces on the mesh associated with this instance. Equivalent to [member GeometryInstance3D.material_override].  			</description>  		</method> -		<method name="instance_geometry_set_material_override"> +		<method name="instance_geometry_set_visibility_range">  			<return type="void">  			</return>  			<argument index="0" name="instance" type="RID">  			</argument> -			<argument index="1" name="material" type="RID"> +			<argument index="1" name="min" type="float"> +			</argument> +			<argument index="2" name="max" type="float"> +			</argument> +			<argument index="3" name="min_margin" type="float"> +			</argument> +			<argument index="4" name="max_margin" type="float">  			</argument>  			<description> -				Sets a material that will override the material for all surfaces on the mesh associated with this instance. Equivalent to [member GeometryInstance3D.material_override]. +				Sets the visibility range values for the given geometry instance. Equivalent to [member GeometryInstance3D.visibility_range_begin] and related properties.  			</description>  		</method>  		<method name="instance_set_base"> @@ -1341,6 +1330,17 @@  				Sets the world space transform of the instance. Equivalent to [member Node3D.transform].  			</description>  		</method> +		<method name="instance_set_visibility_parent"> +			<return type="void"> +			</return> +			<argument index="0" name="instance" type="RID"> +			</argument> +			<argument index="1" name="parent" type="RID"> +			</argument> +			<description> +				Sets the visibility parent for the given instance. Equivalent to [member Node3D.visibility_parent]. +			</description> +		</method>  		<method name="instance_set_visible">  			<return type="void">  			</return> diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index e4d88850ea..08aa2fecbb 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -1213,7 +1213,7 @@ void ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_m  					Node3D *n = src_mesh_node;  					while (n) {  						xf = n->get_transform() * xf; -						n = n->get_parent_spatial(); +						n = n->get_parent_node_3d();  					}  					Vector<uint8_t> lightmap_cache; diff --git a/modules/gdscript/gdscript_vm.cpp b/modules/gdscript/gdscript_vm.cpp index 318ec966ae..8a261a88e3 100644 --- a/modules/gdscript/gdscript_vm.cpp +++ b/modules/gdscript/gdscript_vm.cpp @@ -1989,7 +1989,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a  				ip += instr_arg_count; -				int self_fun = _code_ptr[ip + 1]; +				int argc = _code_ptr[ip + 1]; +				GD_ERR_BREAK(argc < 0); + +				int self_fun = _code_ptr[ip + 2];  #ifdef DEBUG_ENABLED  				if (self_fun < 0 || self_fun >= _global_names_count) {  					err_text = "compiler bug, function name not found"; @@ -1998,9 +2001,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a  #endif  				const StringName *methodname = &_global_names_ptr[self_fun]; -				int argc = _code_ptr[ip + 2]; -				GD_ERR_BREAK(argc < 0); -  				Variant **argptrs = instruction_args;  				GET_INSTRUCTION_ARG(dst, argc); diff --git a/platform/javascript/package-lock.json b/platform/javascript/package-lock.json index 8bf5c52ff6..8003619576 100644 --- a/platform/javascript/package-lock.json +++ b/platform/javascript/package-lock.json @@ -5,27 +5,27 @@    "requires": true,    "dependencies": {      "@babel/code-frame": { -      "version": "7.10.4", -      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", -      "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", +      "version": "7.12.11", +      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", +      "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==",        "dev": true,        "requires": {          "@babel/highlight": "^7.10.4"        }      },      "@babel/helper-validator-identifier": { -      "version": "7.10.4", -      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", -      "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", +      "version": "7.14.5", +      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", +      "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==",        "dev": true      },      "@babel/highlight": { -      "version": "7.10.4", -      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", -      "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", +      "version": "7.14.5", +      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", +      "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==",        "dev": true,        "requires": { -        "@babel/helper-validator-identifier": "^7.10.4", +        "@babel/helper-validator-identifier": "^7.14.5",          "chalk": "^2.0.0",          "js-tokens": "^4.0.0"        }, @@ -40,39 +40,38 @@              "escape-string-regexp": "^1.0.5",              "supports-color": "^5.3.0"            } +        }, +        "escape-string-regexp": { +          "version": "1.0.5", +          "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", +          "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", +          "dev": true          }        }      },      "@babel/parser": { -      "version": "7.14.1", -      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.1.tgz", -      "integrity": "sha512-muUGEKu8E/ftMTPlNp+mc6zL3E9zKWmF5sDHZ5MSsoTP9Wyz64AhEf9kD08xYJ7w6Hdcu8H550ircnPyWSIF0Q==", +      "version": "7.14.5", +      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.5.tgz", +      "integrity": "sha512-TM8C+xtH/9n1qzX+JNHi7AN2zHMTiPUtspO0ZdHflW8KaskkALhMmuMHb4bCmNdv9VAPzJX3/bXqkVLnAvsPfg==",        "dev": true      },      "@eslint/eslintrc": { -      "version": "0.1.3", -      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.1.3.tgz", -      "integrity": "sha512-4YVwPkANLeNtRjMekzux1ci8hIaH5eGKktGqR0d3LWsKNn5B2X/1Z6Trxy7jQXl9EBGE6Yj02O+t09FMeRllaA==", +      "version": "0.4.2", +      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz", +      "integrity": "sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg==",        "dev": true,        "requires": {          "ajv": "^6.12.4",          "debug": "^4.1.1",          "espree": "^7.3.0", -        "globals": "^12.1.0", +        "globals": "^13.9.0",          "ignore": "^4.0.6",          "import-fresh": "^3.2.1",          "js-yaml": "^3.13.1", -        "lodash": "^4.17.19",          "minimatch": "^3.0.4",          "strip-json-comments": "^3.1.1"        }      }, -    "@types/color-name": { -      "version": "1.1.1", -      "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", -      "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", -      "dev": true -    },      "@types/json5": {        "version": "0.0.29",        "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -80,9 +79,9 @@        "dev": true      },      "acorn": { -      "version": "7.4.0", -      "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz", -      "integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==", +      "version": "7.4.1", +      "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", +      "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",        "dev": true      },      "acorn-jsx": { @@ -92,9 +91,9 @@        "dev": true      },      "ajv": { -      "version": "6.12.5", -      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.5.tgz", -      "integrity": "sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag==", +      "version": "6.12.6", +      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", +      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",        "dev": true,        "requires": {          "fast-deep-equal": "^3.1.1", @@ -134,78 +133,39 @@        }      },      "array-includes": { -      "version": "3.1.1", -      "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", -      "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", +      "version": "3.1.3", +      "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", +      "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==",        "dev": true,        "requires": { +        "call-bind": "^1.0.2",          "define-properties": "^1.1.3", -        "es-abstract": "^1.17.0", +        "es-abstract": "^1.18.0-next.2", +        "get-intrinsic": "^1.1.1",          "is-string": "^1.0.5" -      }, -      "dependencies": { -        "es-abstract": { -          "version": "1.17.6", -          "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", -          "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", -          "dev": true, -          "requires": { -            "es-to-primitive": "^1.2.1", -            "function-bind": "^1.1.1", -            "has": "^1.0.3", -            "has-symbols": "^1.0.1", -            "is-callable": "^1.2.0", -            "is-regex": "^1.1.0", -            "object-inspect": "^1.7.0", -            "object-keys": "^1.1.1", -            "object.assign": "^4.1.0", -            "string.prototype.trimend": "^1.0.1", -            "string.prototype.trimstart": "^1.0.1" -          } -        }        }      },      "array.prototype.flat": { -      "version": "1.2.3", -      "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz", -      "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==", +      "version": "1.2.4", +      "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", +      "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==",        "dev": true,        "requires": { +        "call-bind": "^1.0.0",          "define-properties": "^1.1.3", -        "es-abstract": "^1.17.0-next.1" -      }, -      "dependencies": { -        "es-abstract": { -          "version": "1.17.6", -          "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", -          "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", -          "dev": true, -          "requires": { -            "es-to-primitive": "^1.2.1", -            "function-bind": "^1.1.1", -            "has": "^1.0.3", -            "has-symbols": "^1.0.1", -            "is-callable": "^1.2.0", -            "is-regex": "^1.1.0", -            "object-inspect": "^1.7.0", -            "object-keys": "^1.1.1", -            "object.assign": "^4.1.0", -            "string.prototype.trimend": "^1.0.1", -            "string.prototype.trimstart": "^1.0.1" -          } -        } +        "es-abstract": "^1.18.0-next.1"        }      },      "astral-regex": { -      "version": "1.0.0", -      "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", -      "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", +      "version": "2.0.0", +      "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", +      "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",        "dev": true      },      "balanced-match": { -      "version": "1.0.0", -      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", -      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", +      "version": "1.0.2", +      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", +      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",        "dev": true      },      "bluebird": { @@ -224,6 +184,16 @@          "concat-map": "0.0.1"        }      }, +    "call-bind": { +      "version": "1.0.2", +      "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", +      "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", +      "dev": true, +      "requires": { +        "function-bind": "^1.1.1", +        "get-intrinsic": "^1.0.2" +      } +    },      "callsites": {        "version": "3.1.0",        "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -231,18 +201,18 @@        "dev": true      },      "catharsis": { -      "version": "0.8.11", -      "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.8.11.tgz", -      "integrity": "sha512-a+xUyMV7hD1BrDQA/3iPV7oc+6W26BgVJO05PGEoatMyIuPScQKsde6i3YorWX1qs+AZjnJ18NqdKoCtKiNh1g==", +      "version": "0.9.0", +      "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", +      "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==",        "dev": true,        "requires": { -        "lodash": "^4.17.14" +        "lodash": "^4.17.15"        }      },      "chalk": { -      "version": "4.1.0", -      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", -      "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", +      "version": "4.1.1", +      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", +      "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",        "dev": true,        "requires": {          "ansi-styles": "^4.1.0", @@ -250,12 +220,11 @@        },        "dependencies": {          "ansi-styles": { -          "version": "4.2.1", -          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", -          "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", +          "version": "4.3.0", +          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", +          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",            "dev": true,            "requires": { -            "@types/color-name": "^1.1.1",              "color-convert": "^2.0.1"            }          }, @@ -313,15 +282,9 @@        "dev": true      },      "confusing-browser-globals": { -      "version": "1.0.9", -      "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.9.tgz", -      "integrity": "sha512-KbS1Y0jMtyPgIxjO7ZzMAuUpAKMt1SzCL9fsrKsX6b0zJPTaT0SiSPmewwVZg9UAO83HVIlEhZF84LIjZ0lmAw==", -      "dev": true -    }, -    "contains-path": { -      "version": "0.1.0", -      "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", -      "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", +      "version": "1.0.10", +      "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.10.tgz", +      "integrity": "sha512-gNld/3lySHwuhaVluJUKLePYirM3QNCKzVxqAdhJII9/WXKVX5PURzMVJspS1jTslSqjeuG4KMVTSouit5YPHA==",        "dev": true      },      "cross-spawn": { @@ -336,12 +299,12 @@        }      },      "debug": { -      "version": "4.1.1", -      "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", -      "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", +      "version": "4.3.1", +      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", +      "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",        "dev": true,        "requires": { -        "ms": "^2.1.1" +        "ms": "2.1.2"        }      },      "deep-is": { @@ -369,9 +332,9 @@        }      },      "emoji-regex": { -      "version": "7.0.3", -      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", -      "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", +      "version": "8.0.0", +      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", +      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",        "dev": true      },      "enquirer": { @@ -399,23 +362,27 @@        }      },      "es-abstract": { -      "version": "1.18.0-next.0", -      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.0.tgz", -      "integrity": "sha512-elZXTZXKn51hUBdJjSZGYRujuzilgXo8vSPQzjGYXLvSlGiCo8VO8ZGV3kjo9a0WNJJ57hENagwbtlRuHuzkcQ==", +      "version": "1.18.3", +      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz", +      "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==",        "dev": true,        "requires": { +        "call-bind": "^1.0.2",          "es-to-primitive": "^1.2.1",          "function-bind": "^1.1.1", +        "get-intrinsic": "^1.1.1",          "has": "^1.0.3", -        "has-symbols": "^1.0.1", -        "is-callable": "^1.2.0", -        "is-negative-zero": "^2.0.0", -        "is-regex": "^1.1.1", -        "object-inspect": "^1.8.0", +        "has-symbols": "^1.0.2", +        "is-callable": "^1.2.3", +        "is-negative-zero": "^2.0.1", +        "is-regex": "^1.1.3", +        "is-string": "^1.0.6", +        "object-inspect": "^1.10.3",          "object-keys": "^1.1.1", -        "object.assign": "^4.1.0", -        "string.prototype.trimend": "^1.0.1", -        "string.prototype.trimstart": "^1.0.1" +        "object.assign": "^4.1.2", +        "string.prototype.trimend": "^1.0.4", +        "string.prototype.trimstart": "^1.0.4", +        "unbox-primitive": "^1.0.1"        }      },      "es-to-primitive": { @@ -430,35 +397,37 @@        }      },      "escape-string-regexp": { -      "version": "1.0.5", -      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", -      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", +      "version": "4.0.0", +      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", +      "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",        "dev": true      },      "eslint": { -      "version": "7.9.0", -      "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.9.0.tgz", -      "integrity": "sha512-V6QyhX21+uXp4T+3nrNfI3hQNBDa/P8ga7LoQOenwrlEFXrEnUEE+ok1dMtaS3b6rmLXhT1TkTIsG75HMLbknA==", +      "version": "7.28.0", +      "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.28.0.tgz", +      "integrity": "sha512-UMfH0VSjP0G4p3EWirscJEQ/cHqnT/iuH6oNZOB94nBjWbMnhGEPxsZm1eyIW0C/9jLI0Fow4W5DXLjEI7mn1g==",        "dev": true,        "requires": { -        "@babel/code-frame": "^7.0.0", -        "@eslint/eslintrc": "^0.1.3", +        "@babel/code-frame": "7.12.11", +        "@eslint/eslintrc": "^0.4.2",          "ajv": "^6.10.0",          "chalk": "^4.0.0",          "cross-spawn": "^7.0.2",          "debug": "^4.0.1",          "doctrine": "^3.0.0",          "enquirer": "^2.3.5", -        "eslint-scope": "^5.1.0", +        "escape-string-regexp": "^4.0.0", +        "eslint-scope": "^5.1.1",          "eslint-utils": "^2.1.0", -        "eslint-visitor-keys": "^1.3.0", -        "espree": "^7.3.0", -        "esquery": "^1.2.0", +        "eslint-visitor-keys": "^2.0.0", +        "espree": "^7.3.1", +        "esquery": "^1.4.0",          "esutils": "^2.0.2", -        "file-entry-cache": "^5.0.1", +        "fast-deep-equal": "^3.1.3", +        "file-entry-cache": "^6.0.1",          "functional-red-black-tree": "^1.0.1", -        "glob-parent": "^5.0.0", -        "globals": "^12.1.0", +        "glob-parent": "^5.1.2", +        "globals": "^13.6.0",          "ignore": "^4.0.6",          "import-fresh": "^3.0.0",          "imurmurhash": "^0.1.4", @@ -466,7 +435,7 @@          "js-yaml": "^3.13.1",          "json-stable-stringify-without-jsonify": "^1.0.1",          "levn": "^0.4.1", -        "lodash": "^4.17.19", +        "lodash.merge": "^4.6.2",          "minimatch": "^3.0.4",          "natural-compare": "^1.4.0",          "optionator": "^0.9.1", @@ -475,19 +444,19 @@          "semver": "^7.2.1",          "strip-ansi": "^6.0.0",          "strip-json-comments": "^3.1.0", -        "table": "^5.2.3", +        "table": "^6.0.9",          "text-table": "^0.2.0",          "v8-compile-cache": "^2.0.3"        }      },      "eslint-config-airbnb-base": { -      "version": "14.2.0", -      "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.0.tgz", -      "integrity": "sha512-Snswd5oC6nJaevs3nZoLSTvGJBvzTfnBqOIArkf3cbyTyq9UD79wOk8s+RiL6bhca0p/eRO6veczhf6A/7Jy8Q==", +      "version": "14.2.1", +      "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz", +      "integrity": "sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA==",        "dev": true,        "requires": { -        "confusing-browser-globals": "^1.0.9", -        "object.assign": "^4.1.0", +        "confusing-browser-globals": "^1.0.10", +        "object.assign": "^4.1.2",          "object.entries": "^1.1.2"        }      }, @@ -519,50 +488,46 @@        }      },      "eslint-module-utils": { -      "version": "2.6.0", -      "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz", -      "integrity": "sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA==", +      "version": "2.6.1", +      "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.1.tgz", +      "integrity": "sha512-ZXI9B8cxAJIH4nfkhTwcRTEAnrVfobYqwjWy/QMCZ8rHkZHFjf9yO4BzpiF9kCSfNlMG54eKigISHpX0+AaT4A==",        "dev": true,        "requires": { -        "debug": "^2.6.9", +        "debug": "^3.2.7",          "pkg-dir": "^2.0.0"        },        "dependencies": {          "debug": { -          "version": "2.6.9", -          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", -          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", +          "version": "3.2.7", +          "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", +          "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",            "dev": true,            "requires": { -            "ms": "2.0.0" +            "ms": "^2.1.1"            } -        }, -        "ms": { -          "version": "2.0.0", -          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", -          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", -          "dev": true          }        }      },      "eslint-plugin-import": { -      "version": "2.22.0", -      "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.0.tgz", -      "integrity": "sha512-66Fpf1Ln6aIS5Gr/55ts19eUuoDhAbZgnr6UxK5hbDx6l/QgQgx61AePq+BV4PP2uXQFClgMVzep5zZ94qqsxg==", +      "version": "2.23.4", +      "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.23.4.tgz", +      "integrity": "sha512-6/wP8zZRsnQFiR3iaPFgh5ImVRM1WN5NUWfTIRqwOdeiGJlBcSk82o1FEVq8yXmy4lkIzTo7YhHCIxlU/2HyEQ==",        "dev": true,        "requires": { -        "array-includes": "^3.1.1", -        "array.prototype.flat": "^1.2.3", -        "contains-path": "^0.1.0", +        "array-includes": "^3.1.3", +        "array.prototype.flat": "^1.2.4",          "debug": "^2.6.9", -        "doctrine": "1.5.0", -        "eslint-import-resolver-node": "^0.3.3", -        "eslint-module-utils": "^2.6.0", +        "doctrine": "^2.1.0", +        "eslint-import-resolver-node": "^0.3.4", +        "eslint-module-utils": "^2.6.1", +        "find-up": "^2.0.0",          "has": "^1.0.3", +        "is-core-module": "^2.4.0",          "minimatch": "^3.0.4", -        "object.values": "^1.1.1", -        "read-pkg-up": "^2.0.0", -        "resolve": "^1.17.0", +        "object.values": "^1.1.3", +        "pkg-up": "^2.0.0", +        "read-pkg-up": "^3.0.0", +        "resolve": "^1.20.0",          "tsconfig-paths": "^3.9.0"        },        "dependencies": { @@ -576,13 +541,12 @@            }          },          "doctrine": { -          "version": "1.5.0", -          "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", -          "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", +          "version": "2.1.0", +          "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", +          "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",            "dev": true,            "requires": { -            "esutils": "^2.0.2", -            "isarray": "^1.0.0" +            "esutils": "^2.0.2"            }          },          "ms": { @@ -610,23 +574,39 @@        "dev": true,        "requires": {          "eslint-visitor-keys": "^1.1.0" +      }, +      "dependencies": { +        "eslint-visitor-keys": { +          "version": "1.3.0", +          "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", +          "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", +          "dev": true +        }        }      },      "eslint-visitor-keys": { -      "version": "1.3.0", -      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", -      "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", +      "version": "2.1.0", +      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", +      "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",        "dev": true      },      "espree": { -      "version": "7.3.0", -      "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.0.tgz", -      "integrity": "sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw==", +      "version": "7.3.1", +      "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", +      "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==",        "dev": true,        "requires": {          "acorn": "^7.4.0", -        "acorn-jsx": "^5.2.0", +        "acorn-jsx": "^5.3.1",          "eslint-visitor-keys": "^1.3.0" +      }, +      "dependencies": { +        "eslint-visitor-keys": { +          "version": "1.3.0", +          "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", +          "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", +          "dev": true +        }        }      },      "esprima": { @@ -636,9 +616,9 @@        "dev": true      },      "esquery": { -      "version": "1.3.1", -      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", -      "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", +      "version": "1.4.0", +      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", +      "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",        "dev": true,        "requires": {          "estraverse": "^5.1.0" @@ -700,12 +680,12 @@        "dev": true      },      "file-entry-cache": { -      "version": "5.0.1", -      "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", -      "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", +      "version": "6.0.1", +      "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", +      "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",        "dev": true,        "requires": { -        "flat-cache": "^2.0.1" +        "flat-cache": "^3.0.4"        }      },      "find-up": { @@ -718,20 +698,19 @@        }      },      "flat-cache": { -      "version": "2.0.1", -      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", -      "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", +      "version": "3.0.4", +      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", +      "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==",        "dev": true,        "requires": { -        "flatted": "^2.0.0", -        "rimraf": "2.6.3", -        "write": "1.0.3" +        "flatted": "^3.1.0", +        "rimraf": "^3.0.2"        }      },      "flatted": { -      "version": "2.0.2", -      "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", -      "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", +      "version": "3.1.1", +      "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", +      "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==",        "dev": true      },      "fs.realpath": { @@ -752,10 +731,21 @@        "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",        "dev": true      }, +    "get-intrinsic": { +      "version": "1.1.1", +      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", +      "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", +      "dev": true, +      "requires": { +        "function-bind": "^1.1.1", +        "has": "^1.0.3", +        "has-symbols": "^1.0.1" +      } +    },      "glob": { -      "version": "7.1.6", -      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", -      "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", +      "version": "7.1.7", +      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", +      "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",        "dev": true,        "requires": {          "fs.realpath": "^1.0.0", @@ -767,27 +757,27 @@        }      },      "glob-parent": { -      "version": "5.1.1", -      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", -      "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", +      "version": "5.1.2", +      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", +      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",        "dev": true,        "requires": {          "is-glob": "^4.0.1"        }      },      "globals": { -      "version": "12.4.0", -      "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", -      "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", +      "version": "13.9.0", +      "resolved": "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz", +      "integrity": "sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA==",        "dev": true,        "requires": { -        "type-fest": "^0.8.1" +        "type-fest": "^0.20.2"        }      },      "graceful-fs": { -      "version": "4.2.4", -      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", -      "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", +      "version": "4.2.6", +      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", +      "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==",        "dev": true      },      "has": { @@ -799,6 +789,12 @@          "function-bind": "^1.1.1"        }      }, +    "has-bigints": { +      "version": "1.0.1", +      "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", +      "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", +      "dev": true +    },      "has-flag": {        "version": "3.0.0",        "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -806,9 +802,9 @@        "dev": true      },      "has-symbols": { -      "version": "1.0.1", -      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", -      "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", +      "version": "1.0.2", +      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", +      "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==",        "dev": true      },      "hosted-git-info": { @@ -824,9 +820,9 @@        "dev": true      },      "import-fresh": { -      "version": "3.2.1", -      "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", -      "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", +      "version": "3.3.0", +      "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", +      "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",        "dev": true,        "requires": {          "parent-module": "^1.0.0", @@ -861,16 +857,40 @@        "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",        "dev": true      }, +    "is-bigint": { +      "version": "1.0.2", +      "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz", +      "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==", +      "dev": true +    }, +    "is-boolean-object": { +      "version": "1.1.1", +      "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz", +      "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==", +      "dev": true, +      "requires": { +        "call-bind": "^1.0.2" +      } +    },      "is-callable": { -      "version": "1.2.1", -      "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.1.tgz", -      "integrity": "sha512-wliAfSzx6V+6WfMOmus1xy0XvSgf/dlStkvTfq7F0g4bOIW0PSUbnyse3NhDwdyYS1ozfUtAAySqTws3z9Eqgg==", +      "version": "1.2.3", +      "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", +      "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==",        "dev": true      }, +    "is-core-module": { +      "version": "2.4.0", +      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", +      "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", +      "dev": true, +      "requires": { +        "has": "^1.0.3" +      } +    },      "is-date-object": { -      "version": "1.0.2", -      "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", -      "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", +      "version": "1.0.4", +      "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", +      "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==",        "dev": true      },      "is-extglob": { @@ -880,9 +900,9 @@        "dev": true      },      "is-fullwidth-code-point": { -      "version": "2.0.0", -      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", -      "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", +      "version": "3.0.0", +      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", +      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",        "dev": true      },      "is-glob": { @@ -895,41 +915,42 @@        }      },      "is-negative-zero": { -      "version": "2.0.0", -      "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.0.tgz", -      "integrity": "sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE=", +      "version": "2.0.1", +      "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", +      "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", +      "dev": true +    }, +    "is-number-object": { +      "version": "1.0.5", +      "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz", +      "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==",        "dev": true      },      "is-regex": { -      "version": "1.1.1", -      "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", -      "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", +      "version": "1.1.3", +      "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", +      "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==",        "dev": true,        "requires": { -        "has-symbols": "^1.0.1" +        "call-bind": "^1.0.2", +        "has-symbols": "^1.0.2"        }      },      "is-string": { -      "version": "1.0.5", -      "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", -      "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", +      "version": "1.0.6", +      "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", +      "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==",        "dev": true      },      "is-symbol": { -      "version": "1.0.3", -      "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", -      "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", +      "version": "1.0.4", +      "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", +      "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",        "dev": true,        "requires": { -        "has-symbols": "^1.0.1" +        "has-symbols": "^1.0.2"        }      }, -    "isarray": { -      "version": "1.0.0", -      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", -      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", -      "dev": true -    },      "isexe": {        "version": "2.0.0",        "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -943,9 +964,9 @@        "dev": true      },      "js-yaml": { -      "version": "3.14.0", -      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", -      "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", +      "version": "3.14.1", +      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", +      "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",        "dev": true,        "requires": {          "argparse": "^1.0.7", @@ -962,13 +983,14 @@        }      },      "jsdoc": { -      "version": "github:jsdoc/jsdoc#544a992824631fc652183d8b0b4b1281dc961560", -      "from": "github:jsdoc/jsdoc#544a992824631fc652183d8b0b4b1281dc961560", +      "version": "3.6.7", +      "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.7.tgz", +      "integrity": "sha512-sxKt7h0vzCd+3Y81Ey2qinupL6DpRSZJclS04ugHDNmRUXGzqicMJ6iwayhSA0S0DwwX30c5ozyUthr1QKF6uw==",        "dev": true,        "requires": {          "@babel/parser": "^7.9.4",          "bluebird": "^3.7.2", -        "catharsis": "^0.8.11", +        "catharsis": "^0.9.0",          "escape-string-regexp": "^2.0.0",          "js2xmlparser": "^4.0.1",          "klaw": "^3.0.0", @@ -979,7 +1001,7 @@          "requizzle": "^0.2.3",          "strip-json-comments": "^3.1.0",          "taffydb": "2.6.2", -        "underscore": "~1.12.1" +        "underscore": "~1.13.1"        },        "dependencies": {          "escape-string-regexp": { @@ -987,15 +1009,15 @@            "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",            "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",            "dev": true -        }, -        "mkdirp": { -          "version": "1.0.4", -          "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", -          "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", -          "dev": true          }        }      }, +    "json-parse-better-errors": { +      "version": "1.0.2", +      "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", +      "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", +      "dev": true +    },      "json-schema-traverse": {        "version": "0.4.1",        "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -1046,14 +1068,14 @@        }      },      "load-json-file": { -      "version": "2.0.0", -      "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", -      "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", +      "version": "4.0.0", +      "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", +      "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=",        "dev": true,        "requires": {          "graceful-fs": "^4.1.2", -        "parse-json": "^2.2.0", -        "pify": "^2.0.0", +        "parse-json": "^4.0.0", +        "pify": "^3.0.0",          "strip-bom": "^3.0.0"        }      }, @@ -1073,6 +1095,33 @@        "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",        "dev": true      }, +    "lodash.clonedeep": { +      "version": "4.5.0", +      "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", +      "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", +      "dev": true +    }, +    "lodash.merge": { +      "version": "4.6.2", +      "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", +      "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", +      "dev": true +    }, +    "lodash.truncate": { +      "version": "4.4.2", +      "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", +      "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", +      "dev": true +    }, +    "lru-cache": { +      "version": "6.0.0", +      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", +      "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", +      "dev": true, +      "requires": { +        "yallist": "^4.0.0" +      } +    },      "markdown-it": {        "version": "10.0.0",        "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz", @@ -1093,9 +1142,9 @@        "dev": true      },      "marked": { -      "version": "2.0.3", -      "resolved": "https://registry.npmjs.org/marked/-/marked-2.0.3.tgz", -      "integrity": "sha512-5otztIIcJfPc2qGTN8cVtOJEjNJZ0jwa46INMagrYfk0EvqtRuEHLsEe0LrFS0/q+ZRKT0+kXK7P2T1AN5lWRA==", +      "version": "2.0.7", +      "resolved": "https://registry.npmjs.org/marked/-/marked-2.0.7.tgz", +      "integrity": "sha512-BJXxkuIfJchcXOJWTT2DOL+yFWifFv2yGYOUzvXg8Qz610QKw+sHCvTMYwA+qWGhlA2uivBezChZ/pBy1tWdkQ==",        "dev": true      },      "mdurl": { @@ -1120,13 +1169,10 @@        "dev": true      },      "mkdirp": { -      "version": "0.5.5", -      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", -      "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", -      "dev": true, -      "requires": { -        "minimist": "^1.2.5" -      } +      "version": "1.0.4", +      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", +      "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", +      "dev": true      },      "ms": {        "version": "2.1.2", @@ -1161,9 +1207,9 @@        }      },      "object-inspect": { -      "version": "1.8.0", -      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", -      "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", +      "version": "1.10.3", +      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", +      "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==",        "dev": true      },      "object-keys": { @@ -1173,80 +1219,37 @@        "dev": true      },      "object.assign": { -      "version": "4.1.1", -      "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.1.tgz", -      "integrity": "sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA==", +      "version": "4.1.2", +      "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", +      "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",        "dev": true,        "requires": { +        "call-bind": "^1.0.0",          "define-properties": "^1.1.3", -        "es-abstract": "^1.18.0-next.0",          "has-symbols": "^1.0.1",          "object-keys": "^1.1.1"        }      },      "object.entries": { -      "version": "1.1.2", -      "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.2.tgz", -      "integrity": "sha512-BQdB9qKmb/HyNdMNWVr7O3+z5MUIx3aiegEIJqjMBbBf0YT9RRxTJSim4mzFqtyr7PDAHigq0N9dO0m0tRakQA==", +      "version": "1.1.4", +      "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.4.tgz", +      "integrity": "sha512-h4LWKWE+wKQGhtMjZEBud7uLGhqyLwj8fpHOarZhD2uY3C9cRtk57VQ89ke3moByLXMedqs3XCHzyb4AmA2DjA==",        "dev": true,        "requires": { +        "call-bind": "^1.0.2",          "define-properties": "^1.1.3", -        "es-abstract": "^1.17.5", -        "has": "^1.0.3" -      }, -      "dependencies": { -        "es-abstract": { -          "version": "1.17.6", -          "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", -          "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", -          "dev": true, -          "requires": { -            "es-to-primitive": "^1.2.1", -            "function-bind": "^1.1.1", -            "has": "^1.0.3", -            "has-symbols": "^1.0.1", -            "is-callable": "^1.2.0", -            "is-regex": "^1.1.0", -            "object-inspect": "^1.7.0", -            "object-keys": "^1.1.1", -            "object.assign": "^4.1.0", -            "string.prototype.trimend": "^1.0.1", -            "string.prototype.trimstart": "^1.0.1" -          } -        } +        "es-abstract": "^1.18.2"        }      },      "object.values": { -      "version": "1.1.1", -      "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", -      "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", +      "version": "1.1.4", +      "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz", +      "integrity": "sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==",        "dev": true,        "requires": { +        "call-bind": "^1.0.2",          "define-properties": "^1.1.3", -        "es-abstract": "^1.17.0-next.1", -        "function-bind": "^1.1.1", -        "has": "^1.0.3" -      }, -      "dependencies": { -        "es-abstract": { -          "version": "1.17.6", -          "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", -          "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", -          "dev": true, -          "requires": { -            "es-to-primitive": "^1.2.1", -            "function-bind": "^1.1.1", -            "has": "^1.0.3", -            "has-symbols": "^1.0.1", -            "is-callable": "^1.2.0", -            "is-regex": "^1.1.0", -            "object-inspect": "^1.7.0", -            "object-keys": "^1.1.1", -            "object.assign": "^4.1.0", -            "string.prototype.trimend": "^1.0.1", -            "string.prototype.trimstart": "^1.0.1" -          } -        } +        "es-abstract": "^1.18.2"        }      },      "once": { @@ -1306,12 +1309,13 @@        }      },      "parse-json": { -      "version": "2.2.0", -      "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", -      "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", +      "version": "4.0.0", +      "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", +      "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",        "dev": true,        "requires": { -        "error-ex": "^1.2.0" +        "error-ex": "^1.3.1", +        "json-parse-better-errors": "^1.0.1"        }      },      "path-exists": { @@ -1333,24 +1337,24 @@        "dev": true      },      "path-parse": { -      "version": "1.0.6", -      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", -      "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", +      "version": "1.0.7", +      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", +      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",        "dev": true      },      "path-type": { -      "version": "2.0.0", -      "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", -      "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", +      "version": "3.0.0", +      "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", +      "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",        "dev": true,        "requires": { -        "pify": "^2.0.0" +        "pify": "^3.0.0"        }      },      "pify": { -      "version": "2.3.0", -      "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", -      "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", +      "version": "3.0.0", +      "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", +      "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",        "dev": true      },      "pkg-dir": { @@ -1362,6 +1366,15 @@          "find-up": "^2.1.0"        }      }, +    "pkg-up": { +      "version": "2.0.0", +      "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", +      "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", +      "dev": true, +      "requires": { +        "find-up": "^2.1.0" +      } +    },      "prelude-ls": {        "version": "1.2.1",        "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -1381,30 +1394,36 @@        "dev": true      },      "read-pkg": { -      "version": "2.0.0", -      "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", -      "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", +      "version": "3.0.0", +      "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", +      "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=",        "dev": true,        "requires": { -        "load-json-file": "^2.0.0", +        "load-json-file": "^4.0.0",          "normalize-package-data": "^2.3.2", -        "path-type": "^2.0.0" +        "path-type": "^3.0.0"        }      },      "read-pkg-up": { -      "version": "2.0.0", -      "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", -      "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", +      "version": "3.0.0", +      "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", +      "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=",        "dev": true,        "requires": {          "find-up": "^2.0.0", -        "read-pkg": "^2.0.0" +        "read-pkg": "^3.0.0"        }      },      "regexpp": { -      "version": "3.1.0", -      "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", -      "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", +      "version": "3.2.0", +      "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", +      "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", +      "dev": true +    }, +    "require-from-string": { +      "version": "2.0.2", +      "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", +      "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",        "dev": true      },      "requizzle": { @@ -1417,11 +1436,12 @@        }      },      "resolve": { -      "version": "1.17.0", -      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", -      "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", +      "version": "1.20.0", +      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", +      "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",        "dev": true,        "requires": { +        "is-core-module": "^2.2.0",          "path-parse": "^1.0.6"        }      }, @@ -1432,19 +1452,22 @@        "dev": true      },      "rimraf": { -      "version": "2.6.3", -      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", -      "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", +      "version": "3.0.2", +      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", +      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",        "dev": true,        "requires": {          "glob": "^7.1.3"        }      },      "semver": { -      "version": "7.3.2", -      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", -      "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", -      "dev": true +      "version": "7.3.5", +      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", +      "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", +      "dev": true, +      "requires": { +        "lru-cache": "^6.0.0" +      }      },      "shebang-command": {        "version": "2.0.0", @@ -1462,14 +1485,40 @@        "dev": true      },      "slice-ansi": { -      "version": "2.1.0", -      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", -      "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", +      "version": "4.0.0", +      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", +      "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",        "dev": true,        "requires": { -        "ansi-styles": "^3.2.0", -        "astral-regex": "^1.0.0", -        "is-fullwidth-code-point": "^2.0.0" +        "ansi-styles": "^4.0.0", +        "astral-regex": "^2.0.0", +        "is-fullwidth-code-point": "^3.0.0" +      }, +      "dependencies": { +        "ansi-styles": { +          "version": "4.3.0", +          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", +          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", +          "dev": true, +          "requires": { +            "color-convert": "^2.0.1" +          } +        }, +        "color-convert": { +          "version": "2.0.1", +          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", +          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", +          "dev": true, +          "requires": { +            "color-name": "~1.1.4" +          } +        }, +        "color-name": { +          "version": "1.1.4", +          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", +          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", +          "dev": true +        }        }      },      "spdx-correct": { @@ -1499,9 +1548,9 @@        }      },      "spdx-license-ids": { -      "version": "3.0.6", -      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.6.tgz", -      "integrity": "sha512-+orQK83kyMva3WyPf59k1+Y525csj5JejicWut55zeTWANuN17qSiSLUXWtzHeNWORSvT7GLDJ/E/XiIWoXBTw==", +      "version": "3.0.9", +      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz", +      "integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==",        "dev": true      },      "sprintf-js": { @@ -1511,93 +1560,34 @@        "dev": true      },      "string-width": { -      "version": "3.1.0", -      "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", -      "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", +      "version": "4.2.2", +      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", +      "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==",        "dev": true,        "requires": { -        "emoji-regex": "^7.0.1", -        "is-fullwidth-code-point": "^2.0.0", -        "strip-ansi": "^5.1.0" -      }, -      "dependencies": { -        "ansi-regex": { -          "version": "4.1.0", -          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", -          "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", -          "dev": true -        }, -        "strip-ansi": { -          "version": "5.2.0", -          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", -          "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", -          "dev": true, -          "requires": { -            "ansi-regex": "^4.1.0" -          } -        } +        "emoji-regex": "^8.0.0", +        "is-fullwidth-code-point": "^3.0.0", +        "strip-ansi": "^6.0.0"        }      },      "string.prototype.trimend": { -      "version": "1.0.1", -      "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", -      "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", +      "version": "1.0.4", +      "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", +      "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==",        "dev": true,        "requires": { -        "define-properties": "^1.1.3", -        "es-abstract": "^1.17.5" -      }, -      "dependencies": { -        "es-abstract": { -          "version": "1.17.6", -          "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", -          "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", -          "dev": true, -          "requires": { -            "es-to-primitive": "^1.2.1", -            "function-bind": "^1.1.1", -            "has": "^1.0.3", -            "has-symbols": "^1.0.1", -            "is-callable": "^1.2.0", -            "is-regex": "^1.1.0", -            "object-inspect": "^1.7.0", -            "object-keys": "^1.1.1", -            "object.assign": "^4.1.0", -            "string.prototype.trimend": "^1.0.1", -            "string.prototype.trimstart": "^1.0.1" -          } -        } +        "call-bind": "^1.0.2", +        "define-properties": "^1.1.3"        }      },      "string.prototype.trimstart": { -      "version": "1.0.1", -      "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", -      "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", +      "version": "1.0.4", +      "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", +      "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==",        "dev": true,        "requires": { -        "define-properties": "^1.1.3", -        "es-abstract": "^1.17.5" -      }, -      "dependencies": { -        "es-abstract": { -          "version": "1.17.6", -          "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", -          "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", -          "dev": true, -          "requires": { -            "es-to-primitive": "^1.2.1", -            "function-bind": "^1.1.1", -            "has": "^1.0.3", -            "has-symbols": "^1.0.1", -            "is-callable": "^1.2.0", -            "is-regex": "^1.1.0", -            "object-inspect": "^1.7.0", -            "object-keys": "^1.1.1", -            "object.assign": "^4.1.0", -            "string.prototype.trimend": "^1.0.1", -            "string.prototype.trimstart": "^1.0.1" -          } -        } +        "call-bind": "^1.0.2", +        "define-properties": "^1.1.3"        }      },      "strip-ansi": { @@ -1631,15 +1621,37 @@        }      },      "table": { -      "version": "5.4.6", -      "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", -      "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", +      "version": "6.7.1", +      "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", +      "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==",        "dev": true,        "requires": { -        "ajv": "^6.10.2", -        "lodash": "^4.17.14", -        "slice-ansi": "^2.1.0", -        "string-width": "^3.0.0" +        "ajv": "^8.0.1", +        "lodash.clonedeep": "^4.5.0", +        "lodash.truncate": "^4.4.2", +        "slice-ansi": "^4.0.0", +        "string-width": "^4.2.0", +        "strip-ansi": "^6.0.0" +      }, +      "dependencies": { +        "ajv": { +          "version": "8.6.0", +          "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.0.tgz", +          "integrity": "sha512-cnUG4NSBiM4YFBxgZIj/In3/6KX+rQ2l2YPRVcvAMQGWEPKuXoPIhxzwqh31jA3IPbI4qEOp/5ILI4ynioXsGQ==", +          "dev": true, +          "requires": { +            "fast-deep-equal": "^3.1.1", +            "json-schema-traverse": "^1.0.0", +            "require-from-string": "^2.0.2", +            "uri-js": "^4.2.2" +          } +        }, +        "json-schema-traverse": { +          "version": "1.0.0", +          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", +          "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", +          "dev": true +        }        }      },      "taffydb": { @@ -1676,9 +1688,9 @@        }      },      "type-fest": { -      "version": "0.8.1", -      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", -      "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", +      "version": "0.20.2", +      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", +      "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",        "dev": true      },      "uc.micro": { @@ -1687,25 +1699,37 @@        "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==",        "dev": true      }, +    "unbox-primitive": { +      "version": "1.0.1", +      "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", +      "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", +      "dev": true, +      "requires": { +        "function-bind": "^1.1.1", +        "has-bigints": "^1.0.1", +        "has-symbols": "^1.0.2", +        "which-boxed-primitive": "^1.0.2" +      } +    },      "underscore": { -      "version": "1.12.1", -      "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", -      "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==", +      "version": "1.13.1", +      "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz", +      "integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g==",        "dev": true      },      "uri-js": { -      "version": "4.4.0", -      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", -      "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", +      "version": "4.4.1", +      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", +      "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",        "dev": true,        "requires": {          "punycode": "^2.1.0"        }      },      "v8-compile-cache": { -      "version": "2.1.1", -      "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz", -      "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==", +      "version": "2.3.0", +      "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", +      "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",        "dev": true      },      "validate-npm-package-license": { @@ -1727,6 +1751,19 @@          "isexe": "^2.0.0"        }      }, +    "which-boxed-primitive": { +      "version": "1.0.2", +      "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", +      "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", +      "dev": true, +      "requires": { +        "is-bigint": "^1.0.1", +        "is-boolean-object": "^1.1.0", +        "is-number-object": "^1.0.4", +        "is-string": "^1.0.5", +        "is-symbol": "^1.0.3" +      } +    },      "word-wrap": {        "version": "1.2.3",        "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -1739,20 +1776,17 @@        "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",        "dev": true      }, -    "write": { -      "version": "1.0.3", -      "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", -      "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", -      "dev": true, -      "requires": { -        "mkdirp": "^0.5.1" -      } -    },      "xmlcreate": {        "version": "2.0.3",        "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.3.tgz",        "integrity": "sha512-HgS+X6zAztGa9zIK3Y3LXuJes33Lz9x+YyTxgrkIdabu2vqcGOWwdfCpf1hWLRrd553wd4QCDf6BBO6FfdsRiQ==",        "dev": true +    }, +    "yallist": { +      "version": "4.0.0", +      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", +      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", +      "dev": true      }    }  } diff --git a/platform/javascript/package.json b/platform/javascript/package.json index 53748503f9..9dafae30c5 100644 --- a/platform/javascript/package.json +++ b/platform/javascript/package.json @@ -20,9 +20,9 @@    "author": "Godot Engine contributors",    "license": "MIT",    "devDependencies": { -    "eslint": "^7.9.0", -    "eslint-config-airbnb-base": "^14.2.0", -    "eslint-plugin-import": "^2.22.0", -    "jsdoc": "github:jsdoc/jsdoc#544a992824631fc652183d8b0b4b1281dc961560" +    "eslint": "^7.28.0", +    "eslint-config-airbnb-base": "^14.2.1", +    "eslint-plugin-import": "^2.23.4", +    "jsdoc": "^3.6.7"    }  } diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp index e96e4df55c..e96b8ee1f9 100644 --- a/scene/3d/node_3d.cpp +++ b/scene/3d/node_3d.cpp @@ -32,6 +32,7 @@  #include "core/config/engine.h"  #include "core/object/message_queue.h" +#include "scene/3d/visual_instance_3d.h"  #include "scene/main/scene_tree.h"  #include "scene/main/window.h"  #include "scene/scene_string_names.h" @@ -148,6 +149,7 @@ void Node3D::_notification(int p_what) {  			_notify_dirty();  			notification(NOTIFICATION_ENTER_WORLD); +			_update_visibility_parent(true);  		} break;  		case NOTIFICATION_EXIT_TREE: { @@ -161,6 +163,7 @@ void Node3D::_notification(int p_what) {  			data.parent = nullptr;  			data.C = nullptr;  			data.top_level_active = false; +			_update_visibility_parent(true);  		} break;  		case NOTIFICATION_ENTER_WORLD: {  			data.inside_world = true; @@ -282,8 +285,12 @@ Transform3D Node3D::get_local_gizmo_transform() const {  }  #endif -Node3D *Node3D::get_parent_spatial() const { -	return data.parent; +Node3D *Node3D::get_parent_node_3d() const { +	if (data.top_level) { +		return nullptr; +	} + +	return Object::cast_to<Node3D>(get_parent());  }  Transform3D Node3D::get_relative_transform(const Node *p_parent) const { @@ -690,6 +697,51 @@ void Node3D::force_update_transform() {  	notification(NOTIFICATION_TRANSFORM_CHANGED);  } +void Node3D::_update_visibility_parent(bool p_update_root) { +	RID new_parent; + +	if (!visibility_parent_path.is_empty()) { +		if (!p_update_root) { +			return; +		} +		Node *parent = get_node_or_null(visibility_parent_path); +		ERR_FAIL_COND_MSG(!parent, "Can't find visibility parent node at path: " + visibility_parent_path); +		ERR_FAIL_COND_MSG(parent == this, "The visibility parent can't be the same node."); +		GeometryInstance3D *gi = Object::cast_to<GeometryInstance3D>(parent); +		ERR_FAIL_COND_MSG(!gi, "The visibility parent node must be a GeometryInstance3D, at path: " + visibility_parent_path); +		new_parent = gi ? gi->get_instance() : RID(); +	} else if (data.parent) { +		new_parent = data.parent->data.visibility_parent; +	} + +	if (new_parent == data.visibility_parent) { +		return; +	} + +	data.visibility_parent = new_parent; + +	VisualInstance3D *vi = Object::cast_to<VisualInstance3D>(this); +	if (vi) { +		RS::get_singleton()->instance_set_visibility_parent(vi->get_instance(), data.visibility_parent); +	} + +	for (List<Node3D *>::Element *E = data.children.front(); E; E = E->next()) { +		Node3D *c = E->get(); +		c->_update_visibility_parent(false); +	} +} + +void Node3D::set_visibility_parent(const NodePath &p_path) { +	visibility_parent_path = p_path; +	if (is_inside_tree()) { +		_update_visibility_parent(true); +	} +} + +NodePath Node3D::get_visibility_parent() const { +	return visibility_parent_path; +} +  void Node3D::_bind_methods() {  	ClassDB::bind_method(D_METHOD("set_transform", "local"), &Node3D::set_transform);  	ClassDB::bind_method(D_METHOD("get_transform"), &Node3D::get_transform); @@ -703,7 +755,7 @@ void Node3D::_bind_methods() {  	ClassDB::bind_method(D_METHOD("get_scale"), &Node3D::get_scale);  	ClassDB::bind_method(D_METHOD("set_global_transform", "global"), &Node3D::set_global_transform);  	ClassDB::bind_method(D_METHOD("get_global_transform"), &Node3D::get_global_transform); -	ClassDB::bind_method(D_METHOD("get_parent_spatial"), &Node3D::get_parent_spatial); +	ClassDB::bind_method(D_METHOD("get_parent_node_3d"), &Node3D::get_parent_node_3d);  	ClassDB::bind_method(D_METHOD("set_ignore_transform_notification", "enabled"), &Node3D::set_ignore_transform_notification);  	ClassDB::bind_method(D_METHOD("set_as_top_level", "enable"), &Node3D::set_as_top_level);  	ClassDB::bind_method(D_METHOD("is_set_as_top_level"), &Node3D::is_set_as_top_level); @@ -713,6 +765,9 @@ void Node3D::_bind_methods() {  	ClassDB::bind_method(D_METHOD("force_update_transform"), &Node3D::force_update_transform); +	ClassDB::bind_method(D_METHOD("set_visibility_parent", "path"), &Node3D::set_visibility_parent); +	ClassDB::bind_method(D_METHOD("get_visibility_parent"), &Node3D::get_visibility_parent); +  	ClassDB::bind_method(D_METHOD("_update_gizmo"), &Node3D::_update_gizmo);  	ClassDB::bind_method(D_METHOD("update_gizmo"), &Node3D::update_gizmo); @@ -768,6 +823,7 @@ void Node3D::_bind_methods() {  	ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "transform", PROPERTY_HINT_NONE, ""), "set_transform", "get_transform");  	ADD_GROUP("Visibility", "");  	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "visible"), "set_visible", "is_visible"); +	ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "visibility_parent", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "GeometryInstance3D"), "set_visibility_parent", "get_visibility_parent");  	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "gizmo", PROPERTY_HINT_RESOURCE_TYPE, "Node3DGizmo", 0), "set_gizmo", "get_gizmo");  	ADD_SIGNAL(MethodInfo("visibility_changed")); diff --git a/scene/3d/node_3d.h b/scene/3d/node_3d.h index 5f076ceb12..c7e36cf2ec 100644 --- a/scene/3d/node_3d.h +++ b/scene/3d/node_3d.h @@ -75,6 +75,8 @@ class Node3D : public Node {  		bool top_level = false;  		bool inside_world = false; +		RID visibility_parent; +  		int children_lock = 0;  		Node3D *parent = nullptr;  		List<Node3D *> children; @@ -95,12 +97,17 @@ class Node3D : public Node {  	} data; +	NodePath visibility_parent_path; +  	void _update_gizmo();  	void _notify_dirty();  	void _propagate_transform_changed(Node3D *p_origin);  	void _propagate_visibility_changed(); +	void _propagate_visibility_parent(); +	void _update_visibility_parent(bool p_update_root); +  protected:  	_FORCE_INLINE_ void set_ignore_transform_notification(bool p_ignore) { data.ignore_notification = p_ignore; } @@ -118,7 +125,7 @@ public:  		NOTIFICATION_LOCAL_TRANSFORM_CHANGED = 44,  	}; -	Node3D *get_parent_spatial() const; +	Node3D *get_parent_node_3d() const;  	Ref<World3D> get_world_3d() const; @@ -196,6 +203,9 @@ public:  	void force_update_transform(); +	void set_visibility_parent(const NodePath &p_path); +	NodePath get_visibility_parent() const; +  	Node3D();  }; diff --git a/scene/3d/visual_instance_3d.cpp b/scene/3d/visual_instance_3d.cpp index 6971c1ce2a..c16e3c2d78 100644 --- a/scene/3d/visual_instance_3d.cpp +++ b/scene/3d/visual_instance_3d.cpp @@ -150,40 +150,40 @@ Ref<Material> GeometryInstance3D::get_material_override() const {  	return material_override;  } -void GeometryInstance3D::set_lod_min_distance(float p_dist) { -	lod_min_distance = p_dist; -	RS::get_singleton()->instance_geometry_set_draw_range(get_instance(), lod_min_distance, lod_max_distance, lod_min_hysteresis, lod_max_hysteresis); +void GeometryInstance3D::set_visibility_range_begin(float p_dist) { +	visibility_range_begin = p_dist; +	RS::get_singleton()->instance_geometry_set_visibility_range(get_instance(), visibility_range_begin, visibility_range_end, visibility_range_begin_margin, visibility_range_end_margin);  } -float GeometryInstance3D::get_lod_min_distance() const { -	return lod_min_distance; +float GeometryInstance3D::get_visibility_range_begin() const { +	return visibility_range_begin;  } -void GeometryInstance3D::set_lod_max_distance(float p_dist) { -	lod_max_distance = p_dist; -	RS::get_singleton()->instance_geometry_set_draw_range(get_instance(), lod_min_distance, lod_max_distance, lod_min_hysteresis, lod_max_hysteresis); +void GeometryInstance3D::set_visibility_range_end(float p_dist) { +	visibility_range_end = p_dist; +	RS::get_singleton()->instance_geometry_set_visibility_range(get_instance(), visibility_range_begin, visibility_range_end, visibility_range_begin_margin, visibility_range_end_margin);  } -float GeometryInstance3D::get_lod_max_distance() const { -	return lod_max_distance; +float GeometryInstance3D::get_visibility_range_end() const { +	return visibility_range_end;  } -void GeometryInstance3D::set_lod_min_hysteresis(float p_dist) { -	lod_min_hysteresis = p_dist; -	RS::get_singleton()->instance_geometry_set_draw_range(get_instance(), lod_min_distance, lod_max_distance, lod_min_hysteresis, lod_max_hysteresis); +void GeometryInstance3D::set_visibility_range_begin_margin(float p_dist) { +	visibility_range_begin_margin = p_dist; +	RS::get_singleton()->instance_geometry_set_visibility_range(get_instance(), visibility_range_begin, visibility_range_end, visibility_range_begin_margin, visibility_range_end_margin);  } -float GeometryInstance3D::get_lod_min_hysteresis() const { -	return lod_min_hysteresis; +float GeometryInstance3D::get_visibility_range_begin_margin() const { +	return visibility_range_begin_margin;  } -void GeometryInstance3D::set_lod_max_hysteresis(float p_dist) { -	lod_max_hysteresis = p_dist; -	RS::get_singleton()->instance_geometry_set_draw_range(get_instance(), lod_min_distance, lod_max_distance, lod_min_hysteresis, lod_max_hysteresis); +void GeometryInstance3D::set_visibility_range_end_margin(float p_dist) { +	visibility_range_end_margin = p_dist; +	RS::get_singleton()->instance_geometry_set_visibility_range(get_instance(), visibility_range_begin, visibility_range_end, visibility_range_begin_margin, visibility_range_end_margin);  } -float GeometryInstance3D::get_lod_max_hysteresis() const { -	return lod_max_hysteresis; +float GeometryInstance3D::get_visibility_range_end_margin() const { +	return visibility_range_end_margin;  }  void GeometryInstance3D::_notification(int p_what) { @@ -357,17 +357,17 @@ void GeometryInstance3D::_bind_methods() {  	ClassDB::bind_method(D_METHOD("set_lod_bias", "bias"), &GeometryInstance3D::set_lod_bias);  	ClassDB::bind_method(D_METHOD("get_lod_bias"), &GeometryInstance3D::get_lod_bias); -	ClassDB::bind_method(D_METHOD("set_lod_max_hysteresis", "mode"), &GeometryInstance3D::set_lod_max_hysteresis); -	ClassDB::bind_method(D_METHOD("get_lod_max_hysteresis"), &GeometryInstance3D::get_lod_max_hysteresis); +	ClassDB::bind_method(D_METHOD("set_visibility_range_end_margin", "distance"), &GeometryInstance3D::set_visibility_range_end_margin); +	ClassDB::bind_method(D_METHOD("get_visibility_range_end_margin"), &GeometryInstance3D::get_visibility_range_end_margin); -	ClassDB::bind_method(D_METHOD("set_lod_max_distance", "mode"), &GeometryInstance3D::set_lod_max_distance); -	ClassDB::bind_method(D_METHOD("get_lod_max_distance"), &GeometryInstance3D::get_lod_max_distance); +	ClassDB::bind_method(D_METHOD("set_visibility_range_end", "distance"), &GeometryInstance3D::set_visibility_range_end); +	ClassDB::bind_method(D_METHOD("get_visibility_range_end"), &GeometryInstance3D::get_visibility_range_end); -	ClassDB::bind_method(D_METHOD("set_lod_min_hysteresis", "mode"), &GeometryInstance3D::set_lod_min_hysteresis); -	ClassDB::bind_method(D_METHOD("get_lod_min_hysteresis"), &GeometryInstance3D::get_lod_min_hysteresis); +	ClassDB::bind_method(D_METHOD("set_visibility_range_begin_margin", "distance"), &GeometryInstance3D::set_visibility_range_begin_margin); +	ClassDB::bind_method(D_METHOD("get_visibility_range_begin_margin"), &GeometryInstance3D::get_visibility_range_begin_margin); -	ClassDB::bind_method(D_METHOD("set_lod_min_distance", "mode"), &GeometryInstance3D::set_lod_min_distance); -	ClassDB::bind_method(D_METHOD("get_lod_min_distance"), &GeometryInstance3D::get_lod_min_distance); +	ClassDB::bind_method(D_METHOD("set_visibility_range_begin", "distance"), &GeometryInstance3D::set_visibility_range_begin); +	ClassDB::bind_method(D_METHOD("get_visibility_range_begin"), &GeometryInstance3D::get_visibility_range_begin);  	ClassDB::bind_method(D_METHOD("set_shader_instance_uniform", "uniform", "value"), &GeometryInstance3D::set_shader_instance_uniform);  	ClassDB::bind_method(D_METHOD("get_shader_instance_uniform", "uniform"), &GeometryInstance3D::get_shader_instance_uniform); @@ -398,11 +398,11 @@ void GeometryInstance3D::_bind_methods() {  	ADD_PROPERTY(PropertyInfo(Variant::INT, "gi_mode", PROPERTY_HINT_ENUM, "Disabled,Baked,Dynamic"), "set_gi_mode", "get_gi_mode");  	ADD_PROPERTY(PropertyInfo(Variant::INT, "gi_lightmap_scale", PROPERTY_HINT_ENUM, "1x,2x,4x,8x"), "set_lightmap_scale", "get_lightmap_scale"); -	ADD_GROUP("LOD", "lod_"); -	ADD_PROPERTY(PropertyInfo(Variant::INT, "lod_min_distance", PROPERTY_HINT_RANGE, "0,32768,0.01"), "set_lod_min_distance", "get_lod_min_distance"); -	ADD_PROPERTY(PropertyInfo(Variant::INT, "lod_min_hysteresis", PROPERTY_HINT_RANGE, "0,32768,0.01"), "set_lod_min_hysteresis", "get_lod_min_hysteresis"); -	ADD_PROPERTY(PropertyInfo(Variant::INT, "lod_max_distance", PROPERTY_HINT_RANGE, "0,32768,0.01"), "set_lod_max_distance", "get_lod_max_distance"); -	ADD_PROPERTY(PropertyInfo(Variant::INT, "lod_max_hysteresis", PROPERTY_HINT_RANGE, "0,32768,0.01"), "set_lod_max_hysteresis", "get_lod_max_hysteresis"); +	ADD_GROUP("Visibility Range", "visibility_range_"); +	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "visibility_range_begin", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01"), "set_visibility_range_begin", "get_visibility_range_begin"); +	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "visibility_range_begin_margin", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01"), "set_visibility_range_begin_margin", "get_visibility_range_begin_margin"); +	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "visibility_range_end", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01"), "set_visibility_range_end", "get_visibility_range_end"); +	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "visibility_range_end_margin", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01"), "set_visibility_range_end_margin", "get_visibility_range_end_margin");  	//ADD_SIGNAL( MethodInfo("visibility_changed")); diff --git a/scene/3d/visual_instance_3d.h b/scene/3d/visual_instance_3d.h index 68d29ef81e..2d5699859b 100644 --- a/scene/3d/visual_instance_3d.h +++ b/scene/3d/visual_instance_3d.h @@ -107,10 +107,13 @@ public:  private:  	ShadowCastingSetting shadow_casting_setting = SHADOW_CASTING_SETTING_ON;  	Ref<Material> material_override; -	float lod_min_distance = 0.0; -	float lod_max_distance = 0.0; -	float lod_min_hysteresis = 0.0; -	float lod_max_hysteresis = 0.0; + +	float visibility_range_begin = 0.0; +	float visibility_range_end = 0.0; +	float visibility_range_begin_margin = 0.0; +	float visibility_range_end_margin = 0.0; + +	Vector<NodePath> visibility_range_children;  	float lod_bias = 1.0; @@ -136,17 +139,20 @@ public:  	void set_cast_shadows_setting(ShadowCastingSetting p_shadow_casting_setting);  	ShadowCastingSetting get_cast_shadows_setting() const; -	void set_lod_min_distance(float p_dist); -	float get_lod_min_distance() const; +	void set_visibility_range_begin(float p_dist); +	float get_visibility_range_begin() const; + +	void set_visibility_range_end(float p_dist); +	float get_visibility_range_end() const; -	void set_lod_max_distance(float p_dist); -	float get_lod_max_distance() const; +	void set_visibility_range_begin_margin(float p_dist); +	float get_visibility_range_begin_margin() const; -	void set_lod_min_hysteresis(float p_dist); -	float get_lod_min_hysteresis() const; +	void set_visibility_range_end_margin(float p_dist); +	float get_visibility_range_end_margin() const; -	void set_lod_max_hysteresis(float p_dist); -	float get_lod_max_hysteresis() const; +	void set_visibility_range_parent(const Node *p_parent); +	void clear_visibility_range_parent();  	void set_material_override(const Ref<Material> &p_material);  	Ref<Material> get_material_override() const; diff --git a/scene/3d/xr_nodes.cpp b/scene/3d/xr_nodes.cpp index 5a4d9b5d7e..4f2c816934 100644 --- a/scene/3d/xr_nodes.cpp +++ b/scene/3d/xr_nodes.cpp @@ -520,9 +520,9 @@ TypedArray<String> XROrigin3D::get_configuration_warnings() const {  		}  	} -	bool vr_enabled = GLOBAL_GET("rendering/vr/enabled"); -	if (!vr_enabled) { -		warnings.push_back(TTR("VR is not enabled in rendering project settings. Stereoscopic output is not supported unless this is enabled.")); +	bool xr_enabled = GLOBAL_GET("rendering/xr/enabled"); +	if (!xr_enabled) { +		warnings.push_back(TTR("XR is not enabled in rendering project settings. Stereoscopic output is not supported unless this is enabled."));  	}  	return warnings; diff --git a/servers/rendering/renderer_rd/effects_rd.cpp b/servers/rendering/renderer_rd/effects_rd.cpp index 8c6f76b2ab..111c75debd 100644 --- a/servers/rendering/renderer_rd/effects_rd.cpp +++ b/servers/rendering/renderer_rd/effects_rd.cpp @@ -1580,7 +1580,11 @@ EffectsRD::EffectsRD() {  		tonemap.shader_version = tonemap.shader.version_create();  		for (int i = 0; i < TONEMAP_MODE_MAX; i++) { -			tonemap.pipelines[i].setup(tonemap.shader.version_get_shader(tonemap.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0); +			if (tonemap.shader.is_variant_enabled(i)) { +				tonemap.pipelines[i].setup(tonemap.shader.version_get_shader(tonemap.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0); +			} else { +				tonemap.pipelines[i].clear(); +			}  		}  	} diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp index 0a8f174ec6..1aa01dd16e 100644 --- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp @@ -127,8 +127,12 @@ void RendererSceneSkyRD::SkyShaderData::set_code(const String &p_code) {  		depth_stencil_state.enable_depth_test = true;  		depth_stencil_state.depth_compare_operator = RD::COMPARE_OP_LESS_OR_EQUAL; -		RID shader_variant = scene_singleton->sky.sky_shader.shader.version_get_shader(version, i); -		pipelines[i].setup(shader_variant, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), depth_stencil_state, RD::PipelineColorBlendState::create_disabled(), 0); +		if (scene_singleton->sky.sky_shader.shader.is_variant_enabled(i)) { +			RID shader_variant = scene_singleton->sky.sky_shader.shader.version_get_shader(version, i); +			pipelines[i].setup(shader_variant, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), depth_stencil_state, RD::PipelineColorBlendState::create_disabled(), 0); +		} else { +			pipelines[i].clear(); +		}  	}  	valid = true; diff --git a/servers/rendering/renderer_scene.h b/servers/rendering/renderer_scene.h index 4d1ea2e382..3b25498ed8 100644 --- a/servers/rendering/renderer_scene.h +++ b/servers/rendering/renderer_scene.h @@ -63,6 +63,8 @@ public:  	virtual void scenario_set_reflection_atlas_size(RID p_scenario, int p_reflection_size, int p_reflection_count) = 0;  	virtual bool is_scenario(RID p_scenario) const = 0;  	virtual RID scenario_get_environment(RID p_scenario) = 0; +	virtual void scenario_add_viewport_visibility_mask(RID p_scenario, RID p_viewport) = 0; +	virtual void scenario_remove_viewport_visibility_mask(RID p_scenario, RID p_viewport) = 0;  	virtual RID instance_allocate() = 0;  	virtual void instance_initialize(RID p_rid) = 0; @@ -82,6 +84,7 @@ public:  	virtual void instance_set_exterior(RID p_instance, bool p_enabled) = 0;  	virtual void instance_set_extra_visibility_margin(RID p_instance, real_t p_margin) = 0; +	virtual void instance_set_visibility_parent(RID p_instance, RID p_parent_instance) = 0;  	// don't use these in a game!  	virtual Vector<ObjectID> instances_cull_aabb(const AABB &p_aabb, RID p_scenario = RID()) const = 0; @@ -92,8 +95,7 @@ public:  	virtual void instance_geometry_set_cast_shadows_setting(RID p_instance, RS::ShadowCastingSetting p_shadow_casting_setting) = 0;  	virtual void instance_geometry_set_material_override(RID p_instance, RID p_material) = 0; -	virtual void instance_geometry_set_draw_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin) = 0; -	virtual void instance_geometry_set_as_instance_lod(RID p_instance, RID p_as_lod_of_instance) = 0; +	virtual void instance_geometry_set_visibility_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin) = 0;  	virtual void instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_slice_index) = 0;  	virtual void instance_geometry_set_lod_bias(RID p_instance, float p_lod_bias) = 0; diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp index 290f058fc7..2c66b22089 100644 --- a/servers/rendering/renderer_scene_cull.cpp +++ b/servers/rendering/renderer_scene_cull.cpp @@ -323,6 +323,7 @@ void RendererSceneCull::scenario_initialize(RID p_rid) {  	scenario->instance_aabbs.set_page_pool(&instance_aabb_page_pool);  	scenario->instance_data.set_page_pool(&instance_data_page_pool); +	scenario->instance_visibility.set_page_pool(&instance_visibility_data_page_pool);  	RendererSceneOcclusionCull::get_singleton()->add_scenario(p_rid); @@ -369,6 +370,37 @@ RID RendererSceneCull::scenario_get_environment(RID p_scenario) {  	return scenario->environment;  } +void RendererSceneCull::scenario_remove_viewport_visibility_mask(RID p_scenario, RID p_viewport) { +	Scenario *scenario = scenario_owner.getornull(p_scenario); +	ERR_FAIL_COND(!scenario); +	if (!scenario->viewport_visibility_masks.has(p_viewport)) { +		return; +	} + +	uint64_t mask = scenario->viewport_visibility_masks[p_viewport]; +	scenario->used_viewport_visibility_bits &= ~mask; +	scenario->viewport_visibility_masks.erase(p_viewport); +} + +void RendererSceneCull::scenario_add_viewport_visibility_mask(RID p_scenario, RID p_viewport) { +	Scenario *scenario = scenario_owner.getornull(p_scenario); +	ERR_FAIL_COND(!scenario); +	ERR_FAIL_COND(scenario->viewport_visibility_masks.has(p_viewport)); + +	uint64_t new_mask = 1; +	while (new_mask & scenario->used_viewport_visibility_bits) { +		new_mask <<= 1; +	} + +	if (new_mask == 0) { +		ERR_PRINT("Only 64 viewports per scenario allowed when using visibility ranges."); +		new_mask = ((uint64_t)1) << 63; +	} + +	scenario->viewport_visibility_masks[p_viewport] = new_mask; +	scenario->used_viewport_visibility_bits |= new_mask; +} +  /* INSTANCING API */  void RendererSceneCull::_instance_queue_update(Instance *p_instance, bool p_update_aabb, bool p_update_dependencies) { @@ -1103,10 +1135,142 @@ void RendererSceneCull::instance_geometry_set_material_override(RID p_instance,  	}  } -void RendererSceneCull::instance_geometry_set_draw_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin) { +void RendererSceneCull::instance_geometry_set_visibility_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin) { +	Instance *instance = instance_owner.getornull(p_instance); +	ERR_FAIL_COND(!instance); + +	instance->visibility_range_begin = p_min; +	instance->visibility_range_end = p_max; +	instance->visibility_range_begin_margin = p_min_margin; +	instance->visibility_range_end_margin = p_max_margin; + +	_update_instance_visibility_dependencies(instance); + +	if (instance->scenario && instance->visibility_index != -1) { +		InstanceVisibilityData &vd = instance->scenario->instance_visibility[instance->visibility_index]; +		vd.range_begin = instance->visibility_range_begin; +		vd.range_end = instance->visibility_range_end; +		vd.range_begin_margin = instance->visibility_range_begin_margin; +		vd.range_end_margin = instance->visibility_range_end_margin; +	} +} + +void RendererSceneCull::instance_set_visibility_parent(RID p_instance, RID p_parent_instance) { +	Instance *instance = instance_owner.getornull(p_instance); +	ERR_FAIL_COND(!instance); + +	Instance *old_parent = instance->visibility_parent; +	if (old_parent) { +		if ((1 << old_parent->base_type) & RS::INSTANCE_GEOMETRY_MASK && old_parent->base_data) { +			InstanceGeometryData *old_parent_geom = static_cast<InstanceGeometryData *>(old_parent->base_data); +			old_parent_geom->visibility_dependencies.erase(instance); +			_update_instance_visibility_depth(old_parent); +		} +		instance->visibility_parent = nullptr; +	} + +	Instance *parent = instance_owner.getornull(p_parent_instance); +	ERR_FAIL_COND(p_parent_instance.is_valid() && !parent); + +	if (parent) { +		if ((1 << parent->base_type) & RS::INSTANCE_GEOMETRY_MASK && parent->base_data) { +			InstanceGeometryData *parent_geom = static_cast<InstanceGeometryData *>(parent->base_data); +			parent_geom->visibility_dependencies.insert(instance); +			_update_instance_visibility_depth(parent); +		} +		instance->visibility_parent = parent; +	} + +	_update_instance_visibility_dependencies(instance); +} + +void RendererSceneCull::_update_instance_visibility_depth(Instance *p_instance) { +	bool cycle_detected = false; +	Set<Instance *> traversed_nodes; + +	{ +		Instance *instance = p_instance; +		while (instance && ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) && instance->base_data) { +			InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); +			if (!geom->visibility_dependencies.is_empty()) { +				uint32_t depth = 0; +				for (Set<Instance *>::Element *E = geom->visibility_dependencies.front(); E; E = E->next()) { +					if (((1 << E->get()->base_type) & RS::INSTANCE_GEOMETRY_MASK) == 0 || !E->get()->base_data) { +						continue; +					} +					InstanceGeometryData *child_geom = static_cast<InstanceGeometryData *>(E->get()->base_data); +					depth = MAX(depth, child_geom->visibility_dependencies_depth); +				} +				geom->visibility_dependencies_depth = depth + 1; +			} else { +				geom->visibility_dependencies_depth = 0; +			} + +			if (instance->scenario && instance->visibility_index != -1) { +				instance->scenario->instance_visibility.move(instance->visibility_index, geom->visibility_dependencies_depth); +			} + +			traversed_nodes.insert(instance); + +			instance = instance->visibility_parent; +			if (traversed_nodes.has(instance)) { +				cycle_detected = true; +				break; +			} +		} +	} + +	if (cycle_detected) { +		ERR_PRINT("Cycle detected in the visibility dependecies tree."); +		for (Set<Instance *>::Element *E = traversed_nodes.front(); E; E = E->next()) { +			Instance *instance = E->get(); +			InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); +			geom->visibility_dependencies_depth = 0; +			if (instance->scenario && instance->visibility_index != -1) { +				instance->scenario->instance_visibility.move(instance->visibility_index, geom->visibility_dependencies_depth); +			} +		} +	}  } -void RendererSceneCull::instance_geometry_set_as_instance_lod(RID p_instance, RID p_as_lod_of_instance) { +void RendererSceneCull::_update_instance_visibility_dependencies(Instance *p_instance) { +	bool is_geometry_instance = ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) && p_instance->base_data; +	bool has_visibility_range = p_instance->visibility_range_begin > 0.0 || p_instance->visibility_range_end > 0.0; +	bool needs_visibility_cull = has_visibility_range && is_geometry_instance && p_instance->array_index != -1; + +	if (!needs_visibility_cull && p_instance->visibility_index != -1) { +		p_instance->scenario->instance_visibility.remove(p_instance->visibility_index); +		p_instance->visibility_index = -1; +	} else if (needs_visibility_cull && p_instance->visibility_index == -1) { +		InstanceVisibilityData vd; +		vd.instance = p_instance; +		vd.range_begin = p_instance->visibility_range_begin; +		vd.range_end = p_instance->visibility_range_end; +		vd.range_begin_margin = p_instance->visibility_range_begin_margin; +		vd.range_end_margin = p_instance->visibility_range_end_margin; +		vd.position = p_instance->transformed_aabb.get_position() + p_instance->transformed_aabb.get_size() / 2.0f; +		vd.array_index = p_instance->array_index; + +		InstanceGeometryData *geom_data = static_cast<InstanceGeometryData *>(p_instance->base_data); +		p_instance->scenario->instance_visibility.insert(vd, geom_data->visibility_dependencies_depth); +	} + +	if (p_instance->scenario && p_instance->array_index != -1) { +		p_instance->scenario->instance_data[p_instance->array_index].visibility_index = p_instance->visibility_index; + +		InstanceGeometryData *geom_data = static_cast<InstanceGeometryData *>(p_instance->base_data); +		if ((has_visibility_range || p_instance->visibility_parent) && (p_instance->visibility_index == -1 || (geom_data && geom_data->visibility_dependencies_depth == 0))) { +			p_instance->scenario->instance_data[p_instance->array_index].flags |= InstanceData::FLAG_VISIBILITY_DEPENDENCY_NEEDS_CHECK; +		} else { +			p_instance->scenario->instance_data[p_instance->array_index].flags &= ~InstanceData::FLAG_VISIBILITY_DEPENDENCY_NEEDS_CHECK; +		} + +		if (p_instance->visibility_parent) { +			p_instance->scenario->instance_data[p_instance->array_index].parent_array_index = p_instance->visibility_parent->array_index; +		} else { +			p_instance->scenario->instance_data[p_instance->array_index].parent_array_index = -1; +		} +	}  }  void RendererSceneCull::instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_slice_index) { @@ -1352,12 +1516,23 @@ void RendererSceneCull::_update_instance(Instance *p_instance) {  		idata.layer_mask = p_instance->layer_mask;  		idata.flags = p_instance->base_type; //changing it means de-indexing, so this never needs to be changed later  		idata.base_rid = p_instance->base; +		idata.parent_array_index = p_instance->visibility_parent ? p_instance->visibility_parent->array_index : -1; +		idata.visibility_index = p_instance->visibility_index; +  		switch (p_instance->base_type) {  			case RS::INSTANCE_MESH:  			case RS::INSTANCE_MULTIMESH:  			case RS::INSTANCE_IMMEDIATE:  			case RS::INSTANCE_PARTICLES: { -				idata.instance_geometry = static_cast<InstanceGeometryData *>(p_instance->base_data)->geometry_instance; +				InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data); +				idata.instance_geometry = geom->geometry_instance; + +				for (Set<Instance *>::Element *E = geom->visibility_dependencies.front(); E; E = E->next()) { +					Instance *dep_instance = E->get(); +					if (dep_instance->array_index != -1) { +						dep_instance->scenario->instance_data[dep_instance->array_index].parent_array_index = p_instance->array_index; +					} +				}  			} break;  			case RS::INSTANCE_LIGHT: {  				idata.instance_data_rid = static_cast<InstanceLightData *>(p_instance->base_data)->instance.get_id(); @@ -1404,6 +1579,7 @@ void RendererSceneCull::_update_instance(Instance *p_instance) {  		p_instance->scenario->instance_data.push_back(idata);  		p_instance->scenario->instance_aabbs.push_back(InstanceBounds(p_instance->transformed_aabb)); +		_update_instance_visibility_dependencies(p_instance);  	} else {  		if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {  			p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY].update(p_instance->indexer_id, bvh_aabb); @@ -1413,6 +1589,10 @@ void RendererSceneCull::_update_instance(Instance *p_instance) {  		p_instance->scenario->instance_aabbs[p_instance->array_index] = InstanceBounds(p_instance->transformed_aabb);  	} +	if (p_instance->visibility_index != -1) { +		p_instance->scenario->instance_visibility[p_instance->visibility_index].position = p_instance->transformed_aabb.get_position() + p_instance->transformed_aabb.get_size() / 2.0f; +	} +  	//move instance and repair  	pair_pass++; @@ -1486,9 +1666,24 @@ void RendererSceneCull::_unpair_instance(Instance *p_instance) {  	//replace this by last  	int32_t swap_with_index = p_instance->scenario->instance_data.size() - 1;  	if (swap_with_index != p_instance->array_index) { -		p_instance->scenario->instance_data[swap_with_index].instance->array_index = p_instance->array_index; //swap +		Instance *swapped_instance = p_instance->scenario->instance_data[swap_with_index].instance; +		swapped_instance->array_index = p_instance->array_index; //swap  		p_instance->scenario->instance_data[p_instance->array_index] = p_instance->scenario->instance_data[swap_with_index];  		p_instance->scenario->instance_aabbs[p_instance->array_index] = p_instance->scenario->instance_aabbs[swap_with_index]; + +		if (swapped_instance->visibility_index != -1) { +			swapped_instance->scenario->instance_visibility[swapped_instance->visibility_index].array_index = swapped_instance->array_index; +		} + +		if ((1 << swapped_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) { +			InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(swapped_instance->base_data); +			for (Set<Instance *>::Element *E = geom->visibility_dependencies.front(); E; E = E->next()) { +				Instance *dep_instance = E->get(); +				if (dep_instance != p_instance && dep_instance->array_index != -1) { +					dep_instance->scenario->instance_data[dep_instance->array_index].parent_array_index = swapped_instance->array_index; +				} +			} +		}  	}  	// pop last @@ -1505,7 +1700,16 @@ void RendererSceneCull::_unpair_instance(Instance *p_instance) {  		scene_render->geometry_instance_pair_reflection_probe_instances(geom->geometry_instance, nullptr, 0);  		scene_render->geometry_instance_pair_decal_instances(geom->geometry_instance, nullptr, 0);  		scene_render->geometry_instance_pair_voxel_gi_instances(geom->geometry_instance, nullptr, 0); + +		for (Set<Instance *>::Element *E = geom->visibility_dependencies.front(); E; E = E->next()) { +			Instance *dep_instance = E->get(); +			if (dep_instance->array_index != -1) { +				dep_instance->scenario->instance_data[dep_instance->array_index].parent_array_index = -1; +			} +		}  	} + +	_update_instance_visibility_dependencies(p_instance);  }  void RendererSceneCull::_update_instance_aabb(Instance *p_instance) { @@ -2272,16 +2476,73 @@ void RendererSceneCull::render_camera(RID p_render_buffers, RID p_camera, RID p_  #endif  } -void RendererSceneCull::_frustum_cull_threaded(uint32_t p_thread, CullData *cull_data) { +void RendererSceneCull::_visibility_cull_threaded(uint32_t p_thread, VisibilityCullData *cull_data) { +	uint32_t total_threads = RendererThreadPool::singleton->thread_work_pool.get_thread_count(); +	uint32_t bin_from = p_thread * cull_data->cull_count / total_threads; +	uint32_t bin_to = (p_thread + 1 == total_threads) ? cull_data->cull_count : ((p_thread + 1) * cull_data->cull_count / total_threads); + +	_visibility_cull(*cull_data, cull_data->cull_offset + bin_from, cull_data->cull_offset + bin_to); +} + +void RendererSceneCull::_visibility_cull(const VisibilityCullData &cull_data, uint64_t p_from, uint64_t p_to) { +	Scenario *scenario = cull_data.scenario; +	for (unsigned int i = p_from; i < p_to; i++) { +		InstanceVisibilityData &vd = scenario->instance_visibility[i]; +		InstanceData &idata = scenario->instance_data[vd.array_index]; + +		if (idata.parent_array_index >= 0) { +			uint32_t parent_flags = scenario->instance_data[idata.parent_array_index].flags; +			if ((parent_flags & InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN) || (parent_flags & InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN_CLOSE_RANGE) == 0) { +				idata.flags |= InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN; +				idata.flags &= ~InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN_CLOSE_RANGE; +				continue; +			} +		} + +		int range_check = _visibility_range_check(vd, cull_data.camera_position, cull_data.viewport_mask); + +		if (range_check == -1) { +			idata.flags |= InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN; +			idata.flags &= ~InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN_CLOSE_RANGE; +		} else if (range_check == 1) { +			idata.flags &= ~InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN; +			idata.flags |= InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN_CLOSE_RANGE; +		} else { +			idata.flags &= ~InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN; +			idata.flags &= ~InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN_CLOSE_RANGE; +		} +	} +} + +int RendererSceneCull::_visibility_range_check(InstanceVisibilityData &r_vis_data, const Vector3 &p_camera_pos, uint64_t p_viewport_mask) { +	float dist = p_camera_pos.distance_to(r_vis_data.position); + +	bool in_range_last_frame = p_viewport_mask & r_vis_data.viewport_state; +	float begin_offset = in_range_last_frame ? -r_vis_data.range_begin_margin : r_vis_data.range_begin_margin; +	float end_offset = in_range_last_frame ? r_vis_data.range_end_margin : -r_vis_data.range_end_margin; + +	if (r_vis_data.range_end > 0.0f && dist > r_vis_data.range_end + end_offset) { +		r_vis_data.viewport_state &= ~p_viewport_mask; +		return -1; +	} else if (r_vis_data.range_begin > 0.0f && dist < r_vis_data.range_begin + begin_offset) { +		r_vis_data.viewport_state &= ~p_viewport_mask; +		return 1; +	} else { +		r_vis_data.viewport_state |= p_viewport_mask; +		return 0; +	} +} + +void RendererSceneCull::_scene_cull_threaded(uint32_t p_thread, CullData *cull_data) {  	uint32_t cull_total = cull_data->scenario->instance_data.size();  	uint32_t total_threads = RendererThreadPool::singleton->thread_work_pool.get_thread_count();  	uint32_t cull_from = p_thread * cull_total / total_threads;  	uint32_t cull_to = (p_thread + 1 == total_threads) ? cull_total : ((p_thread + 1) * cull_total / total_threads); -	_frustum_cull(*cull_data, frustum_cull_result_threads[p_thread], cull_from, cull_to); +	_scene_cull(*cull_data, scene_cull_result_threads[p_thread], cull_from, cull_to);  } -void RendererSceneCull::_frustum_cull(CullData &cull_data, FrustumCullResult &cull_result, uint64_t p_from, uint64_t p_to) { +void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cull_result, uint64_t p_from, uint64_t p_to) {  	uint64_t frame_number = RSG::rasterizer->get_frame_number();  	float lightmap_probe_update_speed = RSG::storage->lightmap_get_probe_capture_update_speed() * RSG::rasterizer->get_frame_delta_time(); @@ -2296,177 +2557,192 @@ void RendererSceneCull::_frustum_cull(CullData &cull_data, FrustumCullResult &cu  	for (uint64_t i = p_from; i < p_to; i++) {  		bool mesh_visible = false; -		if (cull_data.scenario->instance_aabbs[i].in_frustum(cull_data.cull->frustum) && (cull_data.occlusion_buffer == nullptr || cull_data.scenario->instance_data[i].flags & InstanceData::FLAG_IGNORE_OCCLUSION_CULLING || -																								 !cull_data.occlusion_buffer->is_occluded(cull_data.scenario->instance_aabbs[i].bounds, cull_data.cam_transform.origin, inv_cam_transform, *cull_data.camera_matrix, z_near))) { -			InstanceData &idata = cull_data.scenario->instance_data[i]; -			uint32_t base_type = idata.flags & InstanceData::FLAG_BASE_TYPE_MASK; - -			if ((cull_data.visible_layers & idata.layer_mask) == 0) { -				//failure -			} else if (base_type == RS::INSTANCE_LIGHT) { -				cull_result.lights.push_back(idata.instance); -				cull_result.light_instances.push_back(RID::from_uint64(idata.instance_data_rid)); -				if (cull_data.shadow_atlas.is_valid() && RSG::storage->light_has_shadow(idata.base_rid)) { -					scene_render->light_instance_mark_visible(RID::from_uint64(idata.instance_data_rid)); //mark it visible for shadow allocation later -				} - -			} else if (base_type == RS::INSTANCE_REFLECTION_PROBE) { -				if (cull_data.render_reflection_probe != idata.instance) { -					//avoid entering The Matrix +		InstanceData &idata = cull_data.scenario->instance_data[i]; +		uint32_t visibility_flags = idata.flags & (InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN_CLOSE_RANGE | InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN); +		int32_t visibility_check = -1; -					if ((idata.flags & InstanceData::FLAG_REFLECTION_PROBE_DIRTY) || scene_render->reflection_probe_instance_needs_redraw(RID::from_uint64(idata.instance_data_rid))) { -						InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(idata.instance->base_data); -						cull_data.cull->lock.lock(); -						if (!reflection_probe->update_list.in_list()) { -							reflection_probe->render_step = 0; -							reflection_probe_render_list.add_last(&reflection_probe->update_list); -						} -						cull_data.cull->lock.unlock(); +#define HIDDEN_BY_VISIBILITY_CHECKS (visibility_flags == InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN_CLOSE_RANGE || visibility_flags == InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN) +#define LAYER_CHECK (cull_data.visible_layers & idata.layer_mask) +#define IN_FRUSTUM(f) (cull_data.scenario->instance_aabbs[i].in_frustum(f)) +#define VIS_RANGE_CHECK ((idata.visibility_index == -1) || _visibility_range_check(cull_data.scenario->instance_visibility[idata.visibility_index], cull_data.cam_transform.origin, cull_data.visibility_cull_data->viewport_mask) == 0) +#define VIS_PARENT_CHECK ((idata.parent_array_index == -1) || ((cull_data.scenario->instance_data[idata.parent_array_index].flags & InstanceData::FLAG_VISIBILITY_DEPENDENCY_NEEDS_CHECK) == InstanceData::FLAG_VISIBILITY_DEPENDENCY_HIDDEN_CLOSE_RANGE)) +#define VIS_CHECK (visibility_check < 0 ? (visibility_check = (visibility_flags != InstanceData::FLAG_VISIBILITY_DEPENDENCY_NEEDS_CHECK || (VIS_RANGE_CHECK && VIS_PARENT_CHECK))) : visibility_check) +#define OCCLUSION_CULLED (cull_data.occlusion_buffer != nullptr && cull_data.scenario->instance_data[i].flags & InstanceData::FLAG_IGNORE_OCCLUSION_CULLING && cull_data.occlusion_buffer->is_occluded(cull_data.scenario->instance_aabbs[i].bounds, cull_data.cam_transform.origin, inv_cam_transform, *cull_data.camera_matrix, z_near)) -						idata.flags &= ~uint32_t(InstanceData::FLAG_REFLECTION_PROBE_DIRTY); +		if (!HIDDEN_BY_VISIBILITY_CHECKS) { +			if (LAYER_CHECK && IN_FRUSTUM(cull_data.cull->frustum) && VIS_CHECK && !OCCLUSION_CULLED) { +				uint32_t base_type = idata.flags & InstanceData::FLAG_BASE_TYPE_MASK; +				if (base_type == RS::INSTANCE_LIGHT) { +					cull_result.lights.push_back(idata.instance); +					cull_result.light_instances.push_back(RID::from_uint64(idata.instance_data_rid)); +					if (cull_data.shadow_atlas.is_valid() && RSG::storage->light_has_shadow(idata.base_rid)) { +						scene_render->light_instance_mark_visible(RID::from_uint64(idata.instance_data_rid)); //mark it visible for shadow allocation later  					} -					if (scene_render->reflection_probe_instance_has_reflection(RID::from_uint64(idata.instance_data_rid))) { -						cull_result.reflections.push_back(RID::from_uint64(idata.instance_data_rid)); -					} -				} -			} else if (base_type == RS::INSTANCE_DECAL) { -				cull_result.decals.push_back(RID::from_uint64(idata.instance_data_rid)); +				} else if (base_type == RS::INSTANCE_REFLECTION_PROBE) { +					if (cull_data.render_reflection_probe != idata.instance) { +						//avoid entering The Matrix -			} else if (base_type == RS::INSTANCE_VOXEL_GI) { -				InstanceVoxelGIData *voxel_gi = static_cast<InstanceVoxelGIData *>(idata.instance->base_data); -				cull_data.cull->lock.lock(); -				if (!voxel_gi->update_element.in_list()) { -					voxel_gi_update_list.add(&voxel_gi->update_element); -				} -				cull_data.cull->lock.unlock(); -				cull_result.voxel_gi_instances.push_back(RID::from_uint64(idata.instance_data_rid)); +						if ((idata.flags & InstanceData::FLAG_REFLECTION_PROBE_DIRTY) || scene_render->reflection_probe_instance_needs_redraw(RID::from_uint64(idata.instance_data_rid))) { +							InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(idata.instance->base_data); +							cull_data.cull->lock.lock(); +							if (!reflection_probe->update_list.in_list()) { +								reflection_probe->render_step = 0; +								reflection_probe_render_list.add_last(&reflection_probe->update_list); +							} +							cull_data.cull->lock.unlock(); + +							idata.flags &= ~uint32_t(InstanceData::FLAG_REFLECTION_PROBE_DIRTY); +						} -			} else if (base_type == RS::INSTANCE_LIGHTMAP) { -				cull_result.lightmaps.push_back(RID::from_uint64(idata.instance_data_rid)); -			} else if (((1 << base_type) & RS::INSTANCE_GEOMETRY_MASK) && !(idata.flags & InstanceData::FLAG_CAST_SHADOWS_ONLY)) { -				bool keep = true; +						if (scene_render->reflection_probe_instance_has_reflection(RID::from_uint64(idata.instance_data_rid))) { +							cull_result.reflections.push_back(RID::from_uint64(idata.instance_data_rid)); +						} +					} +				} else if (base_type == RS::INSTANCE_DECAL) { +					cull_result.decals.push_back(RID::from_uint64(idata.instance_data_rid)); + +				} else if (base_type == RS::INSTANCE_VOXEL_GI) { +					InstanceVoxelGIData *voxel_gi = static_cast<InstanceVoxelGIData *>(idata.instance->base_data); +					cull_data.cull->lock.lock(); +					if (!voxel_gi->update_element.in_list()) { +						voxel_gi_update_list.add(&voxel_gi->update_element); +					} +					cull_data.cull->lock.unlock(); +					cull_result.voxel_gi_instances.push_back(RID::from_uint64(idata.instance_data_rid)); -				if (idata.flags & InstanceData::FLAG_REDRAW_IF_VISIBLE) { -					RenderingServerDefault::redraw_request(); -				} +				} else if (base_type == RS::INSTANCE_LIGHTMAP) { +					cull_result.lightmaps.push_back(RID::from_uint64(idata.instance_data_rid)); +				} else if (((1 << base_type) & RS::INSTANCE_GEOMETRY_MASK) && !(idata.flags & InstanceData::FLAG_CAST_SHADOWS_ONLY)) { +					bool keep = true; -				if (base_type == RS::INSTANCE_MESH) { -					mesh_visible = true; -				} else if (base_type == RS::INSTANCE_PARTICLES) { -					//particles visible? process them -					if (RSG::storage->particles_is_inactive(idata.base_rid)) { -						//but if nothing is going on, don't do it. -						keep = false; -					} else { -						cull_data.cull->lock.lock(); -						RSG::storage->particles_request_process(idata.base_rid); -						cull_data.cull->lock.unlock(); -						RSG::storage->particles_set_view_axis(idata.base_rid, -cull_data.cam_transform.basis.get_axis(2).normalized(), cull_data.cam_transform.basis.get_axis(1).normalized()); -						//particles visible? request redraw +					if (idata.flags & InstanceData::FLAG_REDRAW_IF_VISIBLE) {  						RenderingServerDefault::redraw_request();  					} -				} - -				if (geometry_instance_pair_mask & (1 << RS::INSTANCE_LIGHT) && (idata.flags & InstanceData::FLAG_GEOM_LIGHTING_DIRTY)) { -					InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data); -					uint32_t idx = 0; -					for (Set<Instance *>::Element *E = geom->lights.front(); E; E = E->next()) { -						InstanceLightData *light = static_cast<InstanceLightData *>(E->get()->base_data); -						instance_pair_buffer[idx++] = light->instance; -						if (idx == MAX_INSTANCE_PAIRS) { -							break; +					if (base_type == RS::INSTANCE_MESH) { +						mesh_visible = true; +					} else if (base_type == RS::INSTANCE_PARTICLES) { +						//particles visible? process them +						if (RSG::storage->particles_is_inactive(idata.base_rid)) { +							//but if nothing is going on, don't do it. +							keep = false; +						} else { +							cull_data.cull->lock.lock(); +							RSG::storage->particles_request_process(idata.base_rid); +							cull_data.cull->lock.unlock(); +							RSG::storage->particles_set_view_axis(idata.base_rid, -cull_data.cam_transform.basis.get_axis(2).normalized(), cull_data.cam_transform.basis.get_axis(1).normalized()); +							//particles visible? request redraw +							RenderingServerDefault::redraw_request();  						}  					} -					scene_render->geometry_instance_pair_light_instances(geom->geometry_instance, instance_pair_buffer, idx); -					idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_LIGHTING_DIRTY); -				} +					if (geometry_instance_pair_mask & (1 << RS::INSTANCE_LIGHT) && (idata.flags & InstanceData::FLAG_GEOM_LIGHTING_DIRTY)) { +						InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data); +						uint32_t idx = 0; + +						for (Set<Instance *>::Element *E = geom->lights.front(); E; E = E->next()) { +							InstanceLightData *light = static_cast<InstanceLightData *>(E->get()->base_data); +							instance_pair_buffer[idx++] = light->instance; +							if (idx == MAX_INSTANCE_PAIRS) { +								break; +							} +						} + +						scene_render->geometry_instance_pair_light_instances(geom->geometry_instance, instance_pair_buffer, idx); +						idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_LIGHTING_DIRTY); +					} -				if (geometry_instance_pair_mask & (1 << RS::INSTANCE_REFLECTION_PROBE) && (idata.flags & InstanceData::FLAG_GEOM_REFLECTION_DIRTY)) { -					InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data); -					uint32_t idx = 0; +					if (geometry_instance_pair_mask & (1 << RS::INSTANCE_REFLECTION_PROBE) && (idata.flags & InstanceData::FLAG_GEOM_REFLECTION_DIRTY)) { +						InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data); +						uint32_t idx = 0; -					for (Set<Instance *>::Element *E = geom->reflection_probes.front(); E; E = E->next()) { -						InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(E->get()->base_data); +						for (Set<Instance *>::Element *E = geom->reflection_probes.front(); E; E = E->next()) { +							InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(E->get()->base_data); -						instance_pair_buffer[idx++] = reflection_probe->instance; -						if (idx == MAX_INSTANCE_PAIRS) { -							break; +							instance_pair_buffer[idx++] = reflection_probe->instance; +							if (idx == MAX_INSTANCE_PAIRS) { +								break; +							}  						} -					} -					scene_render->geometry_instance_pair_reflection_probe_instances(geom->geometry_instance, instance_pair_buffer, idx); -					idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_REFLECTION_DIRTY); -				} +						scene_render->geometry_instance_pair_reflection_probe_instances(geom->geometry_instance, instance_pair_buffer, idx); +						idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_REFLECTION_DIRTY); +					} -				if (geometry_instance_pair_mask & (1 << RS::INSTANCE_DECAL) && (idata.flags & InstanceData::FLAG_GEOM_DECAL_DIRTY)) { -					InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data); -					uint32_t idx = 0; +					if (geometry_instance_pair_mask & (1 << RS::INSTANCE_DECAL) && (idata.flags & InstanceData::FLAG_GEOM_DECAL_DIRTY)) { +						InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data); +						uint32_t idx = 0; -					for (Set<Instance *>::Element *E = geom->decals.front(); E; E = E->next()) { -						InstanceDecalData *decal = static_cast<InstanceDecalData *>(E->get()->base_data); +						for (Set<Instance *>::Element *E = geom->decals.front(); E; E = E->next()) { +							InstanceDecalData *decal = static_cast<InstanceDecalData *>(E->get()->base_data); -						instance_pair_buffer[idx++] = decal->instance; -						if (idx == MAX_INSTANCE_PAIRS) { -							break; +							instance_pair_buffer[idx++] = decal->instance; +							if (idx == MAX_INSTANCE_PAIRS) { +								break; +							}  						} +						scene_render->geometry_instance_pair_decal_instances(geom->geometry_instance, instance_pair_buffer, idx); +						idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_DECAL_DIRTY);  					} -					scene_render->geometry_instance_pair_decal_instances(geom->geometry_instance, instance_pair_buffer, idx); -					idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_DECAL_DIRTY); -				} -				if (idata.flags & InstanceData::FLAG_GEOM_VOXEL_GI_DIRTY) { -					InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data); -					uint32_t idx = 0; -					for (Set<Instance *>::Element *E = geom->voxel_gi_instances.front(); E; E = E->next()) { -						InstanceVoxelGIData *voxel_gi = static_cast<InstanceVoxelGIData *>(E->get()->base_data); +					if (idata.flags & InstanceData::FLAG_GEOM_VOXEL_GI_DIRTY) { +						InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data); +						uint32_t idx = 0; +						for (Set<Instance *>::Element *E = geom->voxel_gi_instances.front(); E; E = E->next()) { +							InstanceVoxelGIData *voxel_gi = static_cast<InstanceVoxelGIData *>(E->get()->base_data); -						instance_pair_buffer[idx++] = voxel_gi->probe_instance; -						if (idx == MAX_INSTANCE_PAIRS) { -							break; +							instance_pair_buffer[idx++] = voxel_gi->probe_instance; +							if (idx == MAX_INSTANCE_PAIRS) { +								break; +							}  						} -					} -					scene_render->geometry_instance_pair_voxel_gi_instances(geom->geometry_instance, instance_pair_buffer, idx); -					idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_VOXEL_GI_DIRTY); -				} +						scene_render->geometry_instance_pair_voxel_gi_instances(geom->geometry_instance, instance_pair_buffer, idx); +						idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_VOXEL_GI_DIRTY); +					} -				if ((idata.flags & InstanceData::FLAG_LIGHTMAP_CAPTURE) && idata.instance->last_frame_pass != frame_number && !idata.instance->lightmap_target_sh.is_empty() && !idata.instance->lightmap_sh.is_empty()) { -					InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data); -					Color *sh = idata.instance->lightmap_sh.ptrw(); -					const Color *target_sh = idata.instance->lightmap_target_sh.ptr(); -					for (uint32_t j = 0; j < 9; j++) { -						sh[j] = sh[j].lerp(target_sh[j], MIN(1.0, lightmap_probe_update_speed)); +					if ((idata.flags & InstanceData::FLAG_LIGHTMAP_CAPTURE) && idata.instance->last_frame_pass != frame_number && !idata.instance->lightmap_target_sh.is_empty() && !idata.instance->lightmap_sh.is_empty()) { +						InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data); +						Color *sh = idata.instance->lightmap_sh.ptrw(); +						const Color *target_sh = idata.instance->lightmap_target_sh.ptr(); +						for (uint32_t j = 0; j < 9; j++) { +							sh[j] = sh[j].lerp(target_sh[j], MIN(1.0, lightmap_probe_update_speed)); +						} +						scene_render->geometry_instance_set_lightmap_capture(geom->geometry_instance, sh); +						idata.instance->last_frame_pass = frame_number;  					} -					scene_render->geometry_instance_set_lightmap_capture(geom->geometry_instance, sh); -					idata.instance->last_frame_pass = frame_number; -				} -				if (keep) { -					cull_result.geometry_instances.push_back(idata.instance_geometry); +					if (keep) { +						cull_result.geometry_instances.push_back(idata.instance_geometry); +					}  				}  			} -		} -		for (uint32_t j = 0; j < cull_data.cull->shadow_count; j++) { -			for (uint32_t k = 0; k < cull_data.cull->shadows[j].cascade_count; k++) { -				if (cull_data.scenario->instance_aabbs[i].in_frustum(cull_data.cull->shadows[j].cascades[k].frustum)) { -					InstanceData &idata = cull_data.scenario->instance_data[i]; -					uint32_t base_type = idata.flags & InstanceData::FLAG_BASE_TYPE_MASK; +			for (uint32_t j = 0; j < cull_data.cull->shadow_count; j++) { +				for (uint32_t k = 0; k < cull_data.cull->shadows[j].cascade_count; k++) { +					if (IN_FRUSTUM(cull_data.cull->shadows[j].cascades[k].frustum) && VIS_CHECK) { +						uint32_t base_type = idata.flags & InstanceData::FLAG_BASE_TYPE_MASK; -					if (((1 << base_type) & RS::INSTANCE_GEOMETRY_MASK) && idata.flags & InstanceData::FLAG_CAST_SHADOWS) { -						cull_result.directional_shadows[j].cascade_geometry_instances[k].push_back(idata.instance_geometry); -						mesh_visible = true; +						if (((1 << base_type) & RS::INSTANCE_GEOMETRY_MASK) && idata.flags & InstanceData::FLAG_CAST_SHADOWS) { +							cull_result.directional_shadows[j].cascade_geometry_instances[k].push_back(idata.instance_geometry); +							mesh_visible = true; +						}  					}  				}  			}  		} +#undef HIDDEN_BY_VISIBILITY_CHECKS +#undef LAYER_CHECK +#undef IN_FRUSTUM +#undef VIS_RANGE_CHECK +#undef VIS_PARENT_CHECK +#undef VIS_CHECK +#undef OCCLUSION_CULLED +  		for (uint32_t j = 0; j < cull_data.cull->sdfgi.region_count; j++) {  			if (cull_data.scenario->instance_aabbs[i].in_aabb(cull_data.cull->sdfgi.region_aabb[j])) { -				InstanceData &idata = cull_data.scenario->instance_data[i];  				uint32_t base_type = idata.flags & InstanceData::FLAG_BASE_TYPE_MASK;  				if (base_type == RS::INSTANCE_LIGHT) { @@ -2507,7 +2783,35 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c  		scene_render->sdfgi_update(p_render_buffers, p_environment, p_camera_data->main_transform.origin); //update conditions for SDFGI (whether its used or not)  	} -	RENDER_TIMESTAMP("Frustum Culling"); +	RENDER_TIMESTAMP("Visibility Dependencies"); + +	VisibilityCullData visibility_cull_data; +	if (scenario->instance_visibility.get_bin_count() > 0) { +		if (!scenario->viewport_visibility_masks.has(p_viewport)) { +			scenario_add_viewport_visibility_mask(scenario->self, p_viewport); +		} + +		visibility_cull_data.scenario = scenario; +		visibility_cull_data.viewport_mask = scenario->viewport_visibility_masks[p_viewport]; +		visibility_cull_data.camera_position = p_camera_data->main_transform.origin; + +		for (int i = scenario->instance_visibility.get_bin_count() - 1; i > 0; i--) { // We skip bin 0 +			visibility_cull_data.cull_offset = scenario->instance_visibility.get_bin_start(i); +			visibility_cull_data.cull_count = scenario->instance_visibility.get_bin_size(i); + +			if (visibility_cull_data.cull_count == 0) { +				continue; +			} + +			if (visibility_cull_data.cull_count > thread_cull_threshold) { +				RendererThreadPool::singleton->thread_work_pool.do_work(RendererThreadPool::singleton->thread_work_pool.get_thread_count(), this, &RendererSceneCull::_visibility_cull_threaded, &visibility_cull_data); +			} else { +				_visibility_cull(visibility_cull_data, visibility_cull_data.cull_offset, visibility_cull_data.cull_offset + visibility_cull_data.cull_count); +			} +		} +	} + +	RENDER_TIMESTAMP("Culling");  	//rasterizer->set_camera(p_camera_data->main_transform, p_camera_data.main_projection, p_camera_data.is_ortogonal); @@ -2580,7 +2884,7 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c  		}  	} -	frustum_cull_result.clear(); +	scene_cull_result.clear();  	{  		uint64_t cull_from = 0; @@ -2603,19 +2907,19 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c  #endif  		if (cull_to > thread_cull_threshold) {  			//multiple threads -			for (uint32_t i = 0; i < frustum_cull_result_threads.size(); i++) { -				frustum_cull_result_threads[i].clear(); +			for (uint32_t i = 0; i < scene_cull_result_threads.size(); i++) { +				scene_cull_result_threads[i].clear();  			} -			RendererThreadPool::singleton->thread_work_pool.do_work(frustum_cull_result_threads.size(), this, &RendererSceneCull::_frustum_cull_threaded, &cull_data); +			RendererThreadPool::singleton->thread_work_pool.do_work(scene_cull_result_threads.size(), this, &RendererSceneCull::_scene_cull_threaded, &cull_data); -			for (uint32_t i = 0; i < frustum_cull_result_threads.size(); i++) { -				frustum_cull_result.append_from(frustum_cull_result_threads[i]); +			for (uint32_t i = 0; i < scene_cull_result_threads.size(); i++) { +				scene_cull_result.append_from(scene_cull_result_threads[i]);  			}  		} else {  			//single threaded -			_frustum_cull(cull_data, frustum_cull_result, cull_from, cull_to); +			_scene_cull(cull_data, scene_cull_result, cull_from, cull_to);  		}  #ifdef DEBUG_CULL_TIME @@ -2626,9 +2930,9 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c  		print_line("time taken: " + rtos(time_avg / time_count));  #endif -		if (frustum_cull_result.mesh_instances.size()) { -			for (uint64_t i = 0; i < frustum_cull_result.mesh_instances.size(); i++) { -				RSG::storage->mesh_instance_check_for_update(frustum_cull_result.mesh_instances[i]); +		if (scene_cull_result.mesh_instances.size()) { +			for (uint64_t i = 0; i < scene_cull_result.mesh_instances.size(); i++) { +				RSG::storage->mesh_instance_check_for_update(scene_cull_result.mesh_instances[i]);  			}  			RSG::storage->update_mesh_instances();  		} @@ -2652,14 +2956,14 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c  				}  				render_shadow_data[max_shadows_used].light = cull.shadows[i].light_instance;  				render_shadow_data[max_shadows_used].pass = j; -				render_shadow_data[max_shadows_used].instances.merge_unordered(frustum_cull_result.directional_shadows[i].cascade_geometry_instances[j]); +				render_shadow_data[max_shadows_used].instances.merge_unordered(scene_cull_result.directional_shadows[i].cascade_geometry_instances[j]);  				max_shadows_used++;  			}  		}  		// Positional Shadowss -		for (uint32_t i = 0; i < (uint32_t)frustum_cull_result.lights.size(); i++) { -			Instance *ins = frustum_cull_result.lights[i]; +		for (uint32_t i = 0; i < (uint32_t)scene_cull_result.lights.size(); i++) { +			Instance *ins = scene_cull_result.lights[i];  			if (!p_shadow_atlas.is_valid() || !RSG::storage->light_has_shadow(ins->base)) {  				continue; @@ -2763,13 +3067,13 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c  		if (cull.sdfgi.region_count > 0) {  			//update regions  			for (uint32_t i = 0; i < cull.sdfgi.region_count; i++) { -				render_sdfgi_data[i].instances.merge_unordered(frustum_cull_result.sdfgi_region_geometry_instances[i]); +				render_sdfgi_data[i].instances.merge_unordered(scene_cull_result.sdfgi_region_geometry_instances[i]);  				render_sdfgi_data[i].region = i;  			}  			//check if static lights were culled  			bool static_lights_culled = false;  			for (uint32_t i = 0; i < cull.sdfgi.cascade_light_count; i++) { -				if (frustum_cull_result.sdfgi_cascade_lights[i].size()) { +				if (scene_cull_result.sdfgi_cascade_lights[i].size()) {  					static_lights_culled = true;  					break;  				} @@ -2778,7 +3082,7 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c  			if (static_lights_culled) {  				sdfgi_update_data.static_cascade_count = cull.sdfgi.cascade_light_count;  				sdfgi_update_data.static_cascade_indices = cull.sdfgi.cascade_light_index; -				sdfgi_update_data.static_positional_lights = frustum_cull_result.sdfgi_cascade_lights; +				sdfgi_update_data.static_positional_lights = scene_cull_result.sdfgi_cascade_lights;  				sdfgi_update_data.update_static = true;  			}  		} @@ -2792,7 +3096,7 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c  	//append the directional lights to the lights culled  	for (int i = 0; i < directional_lights.size(); i++) { -		frustum_cull_result.light_instances.push_back(directional_lights[i]); +		scene_cull_result.light_instances.push_back(directional_lights[i]);  	}  	RID camera_effects; @@ -2809,7 +3113,7 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c  	}  	RENDER_TIMESTAMP("Render Scene "); -	scene_render->render_scene(p_render_buffers, p_camera_data, frustum_cull_result.geometry_instances, frustum_cull_result.light_instances, frustum_cull_result.reflections, frustum_cull_result.voxel_gi_instances, frustum_cull_result.decals, frustum_cull_result.lightmaps, p_environment, camera_effects, p_shadow_atlas, occluders_tex, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass, p_screen_lod_threshold, render_shadow_data, max_shadows_used, render_sdfgi_data, cull.sdfgi.region_count, &sdfgi_update_data); +	scene_render->render_scene(p_render_buffers, p_camera_data, scene_cull_result.geometry_instances, scene_cull_result.light_instances, scene_cull_result.reflections, scene_cull_result.voxel_gi_instances, scene_cull_result.decals, scene_cull_result.lightmaps, p_environment, camera_effects, p_shadow_atlas, occluders_tex, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass, p_screen_lod_threshold, render_shadow_data, max_shadows_used, render_sdfgi_data, cull.sdfgi.region_count, &sdfgi_update_data);  	for (uint32_t i = 0; i < max_shadows_used; i++) {  		render_shadow_data[i].instances.clear(); @@ -3144,7 +3448,7 @@ void RendererSceneCull::render_probes() {  			update_lights = true;  		} -		frustum_cull_result.geometry_instances.clear(); +		scene_cull_result.geometry_instances.clear();  		RID instance_pair_buffer[MAX_INSTANCE_PAIRS]; @@ -3171,10 +3475,10 @@ void RendererSceneCull::render_probes() {  				ins->scenario->instance_data[ins->array_index].flags &= ~uint32_t(InstanceData::FLAG_GEOM_VOXEL_GI_DIRTY);  			} -			frustum_cull_result.geometry_instances.push_back(geom->geometry_instance); +			scene_cull_result.geometry_instances.push_back(geom->geometry_instance);  		} -		scene_render->voxel_gi_update(probe->probe_instance, update_lights, probe->light_instances, frustum_cull_result.geometry_instances); +		scene_render->voxel_gi_update(probe->probe_instance, update_lights, probe->light_instances, scene_cull_result.geometry_instances);  		voxel_gi_update_list.remove(voxel_gi); @@ -3189,7 +3493,7 @@ void RendererSceneCull::render_particle_colliders() {  		if (hfpc->scenario && hfpc->base_type == RS::INSTANCE_PARTICLES_COLLISION && RSG::storage->particles_collision_is_heightfield(hfpc->base)) {  			//update heightfield  			instance_cull_result.clear(); -			frustum_cull_result.geometry_instances.clear(); +			scene_cull_result.geometry_instances.clear();  			struct CullAABB {  				PagedArray<Instance *> *result; @@ -3211,10 +3515,10 @@ void RendererSceneCull::render_particle_colliders() {  					continue;  				}  				InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data); -				frustum_cull_result.geometry_instances.push_back(geom->geometry_instance); +				scene_cull_result.geometry_instances.push_back(geom->geometry_instance);  			} -			scene_render->render_particle_collider_heightfield(hfpc->base, hfpc->transform, frustum_cull_result.geometry_instances); +			scene_render->render_particle_collider_heightfield(hfpc->base, hfpc->transform, scene_cull_result.geometry_instances);  		}  		heightfield_particle_colliders_update_list.erase(heightfield_particle_colliders_update_list.front());  	} @@ -3503,6 +3807,7 @@ bool RendererSceneCull::free(RID p_rid) {  		}  		scenario->instance_aabbs.reset();  		scenario->instance_data.reset(); +		scenario->instance_visibility.reset();  		scene_render->free(scenario->reflection_probe_shadow_atlas);  		scene_render->free(scenario->reflection_atlas); @@ -3571,10 +3876,10 @@ RendererSceneCull::RendererSceneCull() {  		render_sdfgi_data[i].instances.set_page_pool(&geometry_instance_cull_page_pool);  	} -	frustum_cull_result.init(&rid_cull_page_pool, &geometry_instance_cull_page_pool, &instance_cull_page_pool); -	frustum_cull_result_threads.resize(RendererThreadPool::singleton->thread_work_pool.get_thread_count()); -	for (uint32_t i = 0; i < frustum_cull_result_threads.size(); i++) { -		frustum_cull_result_threads[i].init(&rid_cull_page_pool, &geometry_instance_cull_page_pool, &instance_cull_page_pool); +	scene_cull_result.init(&rid_cull_page_pool, &geometry_instance_cull_page_pool, &instance_cull_page_pool); +	scene_cull_result_threads.resize(RendererThreadPool::singleton->thread_work_pool.get_thread_count()); +	for (uint32_t i = 0; i < scene_cull_result_threads.size(); i++) { +		scene_cull_result_threads[i].init(&rid_cull_page_pool, &geometry_instance_cull_page_pool, &instance_cull_page_pool);  	}  	indexer_update_iterations = GLOBAL_GET("rendering/limits/spatial_indexer/update_iterations_per_frame"); @@ -3595,11 +3900,11 @@ RendererSceneCull::~RendererSceneCull() {  		render_sdfgi_data[i].instances.reset();  	} -	frustum_cull_result.reset(); -	for (uint32_t i = 0; i < frustum_cull_result_threads.size(); i++) { -		frustum_cull_result_threads[i].reset(); +	scene_cull_result.reset(); +	for (uint32_t i = 0; i < scene_cull_result_threads.size(); i++) { +		scene_cull_result_threads[i].reset();  	} -	frustum_cull_result_threads.clear(); +	scene_cull_result_threads.clear();  	if (dummy_occlusion_culling) {  		memdelete(dummy_occlusion_culling); diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h index e42d4bb46c..bdfbea95a2 100644 --- a/servers/rendering/renderer_scene_cull.h +++ b/servers/rendering/renderer_scene_cull.h @@ -31,6 +31,7 @@  #ifndef RENDERING_SERVER_SCENE_CULL_H  #define RENDERING_SERVER_SCENE_CULL_H +#include "core/templates/bin_sorted_array.h"  #include "core/templates/pass_func.h"  #include "servers/rendering/renderer_compositor.h" @@ -259,6 +260,9 @@ public:  			FLAG_USES_MESH_INSTANCE = (1 << 17),  			FLAG_REFLECTION_PROBE_DIRTY = (1 << 18),  			FLAG_IGNORE_OCCLUSION_CULLING = (1 << 19), +			FLAG_VISIBILITY_DEPENDENCY_NEEDS_CHECK = (3 << 20), // 2 bits, overlaps with the other vis. dependency flags +			FLAG_VISIBILITY_DEPENDENCY_HIDDEN_CLOSE_RANGE = (1 << 20), +			FLAG_VISIBILITY_DEPENDENCY_HIDDEN = (1 << 21),  		};  		uint32_t flags = 0; @@ -269,10 +273,33 @@ public:  			RendererSceneRender::GeometryInstance *instance_geometry;  		};  		Instance *instance = nullptr; +		int32_t parent_array_index = -1; +		int32_t visibility_index = -1; +	}; + +	struct InstanceVisibilityData { +		uint64_t viewport_state = 0; +		int32_t array_index = -1; +		Vector3 position; +		Instance *instance = nullptr; +		float range_begin = 0.0f; +		float range_end = 0.0f; +		float range_begin_margin = 0.0f; +		float range_end_margin = 0.0f; +	}; + +	class VisibilityArray : public BinSortedArray<InstanceVisibilityData> { +		_FORCE_INLINE_ virtual void _update_idx(InstanceVisibilityData &r_element, uint64_t p_idx) { +			r_element.instance->visibility_index = p_idx; +			if (r_element.instance->scenario && r_element.instance->array_index != -1) { +				r_element.instance->scenario->instance_data[r_element.instance->array_index].visibility_index = p_idx; +			} +		}  	};  	PagedArrayPool<InstanceBounds> instance_aabb_page_pool;  	PagedArrayPool<InstanceData> instance_data_page_pool; +	PagedArrayPool<InstanceVisibilityData> instance_visibility_data_page_pool;  	struct Scenario {  		enum IndexerType { @@ -292,6 +319,8 @@ public:  		RID camera_effects;  		RID reflection_probe_shadow_atlas;  		RID reflection_atlas; +		uint64_t used_viewport_visibility_bits; +		Map<RID, uint64_t> viewport_visibility_masks;  		SelfList<Instance>::List instances; @@ -299,11 +328,13 @@ public:  		PagedArray<InstanceBounds> instance_aabbs;  		PagedArray<InstanceData> instance_data; +		VisibilityArray instance_visibility;  		Scenario() {  			indexers[INDEXER_GEOMETRY].set_index(INDEXER_GEOMETRY);  			indexers[INDEXER_VOLUMES].set_index(INDEXER_VOLUMES);  			debug = RS::SCENARIO_DEBUG_DISABLED; +			used_viewport_visibility_bits = 0;  		}  	}; @@ -326,6 +357,8 @@ public:  	virtual void scenario_set_reflection_atlas_size(RID p_scenario, int p_reflection_size, int p_reflection_count);  	virtual bool is_scenario(RID p_scenario) const;  	virtual RID scenario_get_environment(RID p_scenario); +	virtual void scenario_add_viewport_visibility_mask(RID p_scenario, RID p_viewport); +	virtual void scenario_remove_viewport_visibility_mask(RID p_scenario, RID p_viewport);  	/* INSTANCING API */ @@ -399,6 +432,12 @@ public:  		//scenario stuff  		DynamicBVH::ID indexer_id;  		int32_t array_index; +		int32_t visibility_index = -1; +		float visibility_range_begin; +		float visibility_range_end; +		float visibility_range_begin_margin; +		float visibility_range_end_margin; +		Instance *visibility_parent = nullptr;  		Scenario *scenario;  		SelfList<Instance> scenario_item; @@ -412,12 +451,6 @@ public:  		float extra_margin;  		ObjectID object_id; -		float lod_begin; -		float lod_end; -		float lod_begin_hysteresis; -		float lod_end_hysteresis; -		RID lod_instance; -  		Vector<Color> lightmap_target_sh; //target is used for incrementally changing the SH over time, this avoids pops in some corner cases and when going interior <-> exterior  		uint64_t last_frame_pass; @@ -495,10 +528,10 @@ public:  			visible = true; -			lod_begin = 0; -			lod_end = 0; -			lod_begin_hysteresis = 0; -			lod_end_hysteresis = 0; +			visibility_range_begin = 0; +			visibility_range_end = 0; +			visibility_range_begin_margin = 0; +			visibility_range_end_margin = 0;  			last_frame_pass = 0;  			version = 1; @@ -537,6 +570,8 @@ public:  		Set<Instance *> reflection_probes;  		Set<Instance *> voxel_gi_instances;  		Set<Instance *> lightmap_captures; +		Set<Instance *> visibility_dependencies; +		uint32_t visibility_dependencies_depth = 0;  		InstanceGeometryData() {  			can_cast_shadows = true; @@ -717,7 +752,7 @@ public:  	PagedArray<Instance *> instance_cull_result;  	PagedArray<Instance *> instance_shadow_cull_result; -	struct FrustumCullResult { +	struct InstanceCullResult {  		PagedArray<RendererSceneRender::GeometryInstance *> geometry_instances;  		PagedArray<Instance *> lights;  		PagedArray<RID> light_instances; @@ -782,7 +817,7 @@ public:  			}  		} -		void append_from(FrustumCullResult &p_cull_result) { +		void append_from(InstanceCullResult &p_cull_result) {  			geometry_instances.merge_unordered(p_cull_result.geometry_instances);  			lights.merge_unordered(p_cull_result.lights);  			light_instances.merge_unordered(p_cull_result.light_instances); @@ -832,8 +867,8 @@ public:  		}  	}; -	FrustumCullResult frustum_cull_result; -	LocalVector<FrustumCullResult> frustum_cull_result_threads; +	InstanceCullResult scene_cull_result; +	LocalVector<InstanceCullResult> scene_cull_result_threads;  	RendererSceneRender::RenderShadowData render_shadow_data[MAX_UPDATE_SHADOWS];  	uint32_t max_shadows_used = 0; @@ -866,6 +901,11 @@ public:  	virtual void instance_set_extra_visibility_margin(RID p_instance, real_t p_margin); +	virtual void instance_set_visibility_parent(RID p_instance, RID p_parent_instance); + +	void _update_instance_visibility_depth(Instance *p_instance); +	void _update_instance_visibility_dependencies(Instance *p_instance); +  	// don't use these in a game!  	virtual Vector<ObjectID> instances_cull_aabb(const AABB &p_aabb, RID p_scenario = RID()) const;  	virtual Vector<ObjectID> instances_cull_ray(const Vector3 &p_from, const Vector3 &p_to, RID p_scenario = RID()) const; @@ -875,8 +915,8 @@ public:  	virtual void instance_geometry_set_cast_shadows_setting(RID p_instance, RS::ShadowCastingSetting p_shadow_casting_setting);  	virtual void instance_geometry_set_material_override(RID p_instance, RID p_material); -	virtual void instance_geometry_set_draw_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin); -	virtual void instance_geometry_set_as_instance_lod(RID p_instance, RID p_as_lod_of_instance); +	virtual void instance_geometry_set_visibility_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin); +  	virtual void instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_slice_index);  	virtual void instance_geometry_set_lod_bias(RID p_instance, float p_lod_bias); @@ -937,6 +977,19 @@ public:  		Frustum frustum;  	} cull; +	struct VisibilityCullData { +		uint64_t viewport_mask; +		Scenario *scenario; +		Vector3 camera_position; +		uint32_t cull_offset; +		uint32_t cull_count; +	}; + +	void _visibility_cull_threaded(uint32_t p_thread, VisibilityCullData *cull_data); +	void _visibility_cull(const VisibilityCullData &cull_data, uint64_t p_from, uint64_t p_to); +	_FORCE_INLINE_ void _visibility_cull(const VisibilityCullData &cull_data, uint64_t p_idx); +	_FORCE_INLINE_ int _visibility_range_check(InstanceVisibilityData &r_vis_data, const Vector3 &p_camera_pos, uint64_t p_viewport_mask); +  	struct CullData {  		Cull *cull;  		Scenario *scenario; @@ -946,10 +999,11 @@ public:  		Instance *render_reflection_probe;  		const RendererSceneOcclusionCull::HZBuffer *occlusion_buffer;  		const CameraMatrix *camera_matrix; +		const VisibilityCullData *visibility_cull_data;  	}; -	void _frustum_cull_threaded(uint32_t p_thread, CullData *cull_data); -	void _frustum_cull(CullData &cull_data, FrustumCullResult &cull_result, uint64_t p_from, uint64_t p_to); +	void _scene_cull_threaded(uint32_t p_thread, CullData *cull_data); +	void _scene_cull(CullData &cull_data, InstanceCullResult &cull_result, uint64_t p_from, uint64_t p_to);  	bool _render_reflection_probe_step(Instance *p_instance, int p_step);  	void _render_scene(const RendererSceneRender::CameraData *p_camera_data, RID p_render_buffers, RID p_environment, RID p_force_camera_effects, uint32_t p_visible_layers, RID p_scenario, RID p_viewport, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold, bool p_using_shadows = true); diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp index 21f849e822..34bdb15c62 100644 --- a/servers/rendering/renderer_viewport.cpp +++ b/servers/rendering/renderer_viewport.cpp @@ -824,6 +824,10 @@ void RendererViewport::viewport_set_scenario(RID p_viewport, RID p_scenario) {  	Viewport *viewport = viewport_owner.getornull(p_viewport);  	ERR_FAIL_COND(!viewport); +	if (viewport->scenario.is_valid()) { +		RSG::scene->scenario_remove_viewport_visibility_mask(viewport->scenario, p_viewport); +	} +  	viewport->scenario = p_scenario;  	if (viewport->use_occlusion_culling) {  		RendererSceneOcclusionCull::get_singleton()->buffer_set_scenario(p_viewport, p_scenario); diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h index 6476d7c75d..e4d319ed6c 100644 --- a/servers/rendering/rendering_server_default.h +++ b/servers/rendering/rendering_server_default.h @@ -726,6 +726,7 @@ public:  	FUNC2(instance_set_exterior, RID, bool)  	FUNC2(instance_set_extra_visibility_margin, RID, real_t) +	FUNC2(instance_set_visibility_parent, RID, RID)  	// don't use these in a game!  	FUNC2RC(Vector<ObjectID>, instances_cull_aabb, const AABB &, RID) @@ -736,8 +737,7 @@ public:  	FUNC2(instance_geometry_set_cast_shadows_setting, RID, ShadowCastingSetting)  	FUNC2(instance_geometry_set_material_override, RID, RID) -	FUNC5(instance_geometry_set_draw_range, RID, float, float, float, float) -	FUNC2(instance_geometry_set_as_instance_lod, RID, RID) +	FUNC5(instance_geometry_set_visibility_range, RID, float, float, float, float)  	FUNC4(instance_geometry_set_lightmap, RID, RID, const Rect2 &, int)  	FUNC2(instance_geometry_set_lod_bias, RID, float) diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 7b535a0bda..f25f255321 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -1725,11 +1725,11 @@ void RenderingServer::_bind_methods() {  	ClassDB::bind_method(D_METHOD("instance_attach_skeleton", "instance", "skeleton"), &RenderingServer::instance_attach_skeleton);  	ClassDB::bind_method(D_METHOD("instance_set_exterior", "instance", "enabled"), &RenderingServer::instance_set_exterior);  	ClassDB::bind_method(D_METHOD("instance_set_extra_visibility_margin", "instance", "margin"), &RenderingServer::instance_set_extra_visibility_margin); +	ClassDB::bind_method(D_METHOD("instance_set_visibility_parent", "instance", "parent"), &RenderingServer::instance_set_visibility_parent);  	ClassDB::bind_method(D_METHOD("instance_geometry_set_flag", "instance", "flag", "enabled"), &RenderingServer::instance_geometry_set_flag);  	ClassDB::bind_method(D_METHOD("instance_geometry_set_cast_shadows_setting", "instance", "shadow_casting_setting"), &RenderingServer::instance_geometry_set_cast_shadows_setting);  	ClassDB::bind_method(D_METHOD("instance_geometry_set_material_override", "instance", "material"), &RenderingServer::instance_geometry_set_material_override); -	ClassDB::bind_method(D_METHOD("instance_geometry_set_draw_range", "instance", "min", "max", "min_margin", "max_margin"), &RenderingServer::instance_geometry_set_draw_range); -	ClassDB::bind_method(D_METHOD("instance_geometry_set_as_instance_lod", "instance", "as_lod_of_instance"), &RenderingServer::instance_geometry_set_as_instance_lod); +	ClassDB::bind_method(D_METHOD("instance_geometry_set_visibility_range", "instance", "min", "max", "min_margin", "max_margin"), &RenderingServer::instance_geometry_set_visibility_range);  	ClassDB::bind_method(D_METHOD("instances_cull_aabb", "aabb", "scenario"), &RenderingServer::_instances_cull_aabb_bind, DEFVAL(RID()));  	ClassDB::bind_method(D_METHOD("instances_cull_ray", "from", "to", "scenario"), &RenderingServer::_instances_cull_ray_bind, DEFVAL(RID())); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index 3247717e98..1806f1da18 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -1172,6 +1172,7 @@ public:  	virtual void instance_set_exterior(RID p_instance, bool p_enabled) = 0;  	virtual void instance_set_extra_visibility_margin(RID p_instance, real_t p_margin) = 0; +	virtual void instance_set_visibility_parent(RID p_instance, RID p_parent_instance) = 0;  	// don't use these in a game!  	virtual Vector<ObjectID> instances_cull_aabb(const AABB &p_aabb, RID p_scenario = RID()) const = 0; @@ -1201,8 +1202,7 @@ public:  	virtual void instance_geometry_set_cast_shadows_setting(RID p_instance, ShadowCastingSetting p_shadow_casting_setting) = 0;  	virtual void instance_geometry_set_material_override(RID p_instance, RID p_material) = 0; -	virtual void instance_geometry_set_draw_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin) = 0; -	virtual void instance_geometry_set_as_instance_lod(RID p_instance, RID p_as_lod_of_instance) = 0; +	virtual void instance_geometry_set_visibility_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin) = 0;  	virtual void instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice) = 0;  	virtual void instance_geometry_set_lod_bias(RID p_instance, float p_lod_bias) = 0;  |