diff options
150 files changed, 1853 insertions, 1937 deletions
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index c1cf061854..d9cc77feb3 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -2583,17 +2583,17 @@ _Semaphore::~_Semaphore() { void _Mutex::lock() { - mutex->lock(); + mutex.lock(); } Error _Mutex::try_lock() { - return mutex->try_lock(); + return mutex.try_lock(); } void _Mutex::unlock() { - mutex->unlock(); + mutex.unlock(); } void _Mutex::_bind_methods() { @@ -2603,16 +2603,6 @@ void _Mutex::_bind_methods() { ClassDB::bind_method(D_METHOD("unlock"), &_Mutex::unlock); } -_Mutex::_Mutex() { - - mutex = Mutex::create(); -} - -_Mutex::~_Mutex() { - - memdelete(mutex); -} - /////////////// void _Thread::_start_func(void *ud) { diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index ae569ea189..e68c40c9e4 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -609,7 +609,7 @@ public: class _Mutex : public Reference { GDCLASS(_Mutex, Reference); - Mutex *mutex; + Mutex mutex; static void _bind_methods(); @@ -617,9 +617,6 @@ public: void lock(); Error try_lock(); void unlock(); - - _Mutex(); - ~_Mutex(); }; class _Semaphore : public Reference { diff --git a/core/command_queue_mt.cpp b/core/command_queue_mt.cpp index 861ca8d1d3..b88f773ed8 100644 --- a/core/command_queue_mt.cpp +++ b/core/command_queue_mt.cpp @@ -34,14 +34,12 @@ void CommandQueueMT::lock() { - if (mutex) - mutex->lock(); + mutex.lock(); } void CommandQueueMT::unlock() { - if (mutex) - mutex->unlock(); + mutex.unlock(); } void CommandQueueMT::wait_for_flush() { @@ -106,7 +104,6 @@ CommandQueueMT::CommandQueueMT(bool p_sync) { read_ptr = 0; write_ptr = 0; dealloc_ptr = 0; - mutex = Mutex::create(); command_mem = (uint8_t *)memalloc(COMMAND_MEM_SIZE); for (int i = 0; i < SYNC_SEMAPHORES; i++) { @@ -124,7 +121,6 @@ CommandQueueMT::~CommandQueueMT() { if (sync) memdelete(sync); - memdelete(mutex); for (int i = 0; i < SYNC_SEMAPHORES; i++) { memdelete(sync_sems[i].sem); diff --git a/core/command_queue_mt.h b/core/command_queue_mt.h index 2b6e0201f0..7407557e7e 100644 --- a/core/command_queue_mt.h +++ b/core/command_queue_mt.h @@ -341,7 +341,7 @@ class CommandQueueMT { uint32_t write_ptr; uint32_t dealloc_ptr; SyncSemaphore sync_sems[SYNC_SEMAPHORES]; - Mutex *mutex; + Mutex mutex; SemaphoreOld *sync; template <class T> diff --git a/core/io/file_access_network.cpp b/core/io/file_access_network.cpp index 202eb89dbd..7f1eb6fd90 100644 --- a/core/io/file_access_network.cpp +++ b/core/io/file_access_network.cpp @@ -42,14 +42,14 @@ void FileAccessNetworkClient::lock_mutex() { - mutex->lock(); + mutex.lock(); lockcount++; } void FileAccessNetworkClient::unlock_mutex() { lockcount--; - mutex->unlock(); + mutex.unlock(); } void FileAccessNetworkClient::put_32(int p_32) { @@ -97,15 +97,16 @@ void FileAccessNetworkClient::_thread_func() { lock_mutex(); DEBUG_PRINT("MUTEX PASS"); - blockrequest_mutex->lock(); - while (block_requests.size()) { - put_32(block_requests.front()->get().id); - put_32(FileAccessNetwork::COMMAND_READ_BLOCK); - put_64(block_requests.front()->get().offset); - put_32(block_requests.front()->get().size); - block_requests.pop_front(); + { + MutexLock lock(blockrequest_mutex); + while (block_requests.size()) { + put_32(block_requests.front()->get().id); + put_32(FileAccessNetwork::COMMAND_READ_BLOCK); + put_64(block_requests.front()->get().offset); + put_32(block_requests.front()->get().size); + block_requests.pop_front(); + } } - blockrequest_mutex->unlock(); DEBUG_PRINT("THREAD ITER"); @@ -225,8 +226,6 @@ FileAccessNetworkClient *FileAccessNetworkClient::singleton = NULL; FileAccessNetworkClient::FileAccessNetworkClient() { thread = NULL; - mutex = Mutex::create(); - blockrequest_mutex = Mutex::create(); quit = false; singleton = this; last_id = 0; @@ -244,8 +243,6 @@ FileAccessNetworkClient::~FileAccessNetworkClient() { memdelete(thread); } - memdelete(blockrequest_mutex); - memdelete(mutex); memdelete(sem); } @@ -259,10 +256,11 @@ void FileAccessNetwork::_set_block(int p_offset, const Vector<uint8_t> &p_block) ERR_FAIL_COND((p_block.size() != (int)(total_size % page_size))); } - buffer_mutex->lock(); - pages.write[page].buffer = p_block; - pages.write[page].queued = false; - buffer_mutex->unlock(); + { + MutexLock lock(buffer_mutex); + pages.write[page].buffer = p_block; + pages.write[page].queued = false; + } if (waiting_on_page == page) { waiting_on_page = -1; @@ -384,15 +382,16 @@ void FileAccessNetwork::_queue_page(int p_page) const { if (pages[p_page].buffer.empty() && !pages[p_page].queued) { FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton; - - nc->blockrequest_mutex->lock(); - FileAccessNetworkClient::BlockRequest br; - br.id = id; - br.offset = size_t(p_page) * page_size; - br.size = page_size; - nc->block_requests.push_back(br); - pages.write[p_page].queued = true; - nc->blockrequest_mutex->unlock(); + { + MutexLock lock(nc->blockrequest_mutex); + + FileAccessNetworkClient::BlockRequest br; + br.id = id; + br.offset = size_t(p_page) * page_size; + br.size = page_size; + nc->block_requests.push_back(br); + pages.write[p_page].queued = true; + } DEBUG_PRINT("QUEUE PAGE POST"); nc->sem->post(); DEBUG_PRINT("queued " + itos(p_page)); @@ -418,14 +417,14 @@ int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const { int page = pos / page_size; if (page != last_page) { - buffer_mutex->lock(); + buffer_mutex.lock(); if (pages[page].buffer.empty()) { waiting_on_page = page; for (int j = 0; j < read_ahead; j++) { _queue_page(page + j); } - buffer_mutex->unlock(); + buffer_mutex.unlock(); DEBUG_PRINT("wait"); page_sem->wait(); DEBUG_PRINT("done"); @@ -436,7 +435,7 @@ int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const { _queue_page(page + j); } //queue pages - buffer_mutex->unlock(); + buffer_mutex.unlock(); } buff = pages.write[page].buffer.ptrw(); @@ -524,7 +523,6 @@ FileAccessNetwork::FileAccessNetwork() { pos = 0; sem = SemaphoreOld::create(); page_sem = SemaphoreOld::create(); - buffer_mutex = Mutex::create(); FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton; nc->lock_mutex(); id = nc->last_id++; @@ -542,7 +540,6 @@ FileAccessNetwork::~FileAccessNetwork() { close(); memdelete(sem); memdelete(page_sem); - memdelete(buffer_mutex); FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton; nc->lock_mutex(); diff --git a/core/io/file_access_network.h b/core/io/file_access_network.h index f329abf7c5..38d9b8e8a6 100644 --- a/core/io/file_access_network.h +++ b/core/io/file_access_network.h @@ -52,8 +52,8 @@ class FileAccessNetworkClient { SemaphoreOld *sem; Thread *thread; bool quit; - Mutex *mutex; - Mutex *blockrequest_mutex; + Mutex mutex; + Mutex blockrequest_mutex; Map<int, FileAccessNetwork *> accesses; Ref<StreamPeerTCP> client; int last_id; @@ -87,7 +87,7 @@ class FileAccessNetwork : public FileAccess { SemaphoreOld *sem; SemaphoreOld *page_sem; - Mutex *buffer_mutex; + Mutex buffer_mutex; bool opened; size_t total_size; mutable size_t pos; diff --git a/core/io/ip.cpp b/core/io/ip.cpp index 7d18117711..af534e4bb7 100644 --- a/core/io/ip.cpp +++ b/core/io/ip.cpp @@ -70,7 +70,7 @@ struct _IP_ResolverPrivate { return IP::RESOLVER_INVALID_ID; } - Mutex *mutex; + Mutex mutex; SemaphoreOld *sem; Thread *thread; @@ -100,9 +100,8 @@ struct _IP_ResolverPrivate { ipr->sem->wait(); - ipr->mutex->lock(); + MutexLock lock(ipr->mutex); ipr->resolve_queues(); - ipr->mutex->unlock(); } } @@ -115,30 +114,27 @@ struct _IP_ResolverPrivate { IP_Address IP::resolve_hostname(const String &p_hostname, IP::Type p_type) { - resolver->mutex->lock(); + MutexLock lock(resolver->mutex); String key = _IP_ResolverPrivate::get_cache_key(p_hostname, p_type); if (resolver->cache.has(key) && resolver->cache[key].is_valid()) { IP_Address res = resolver->cache[key]; - resolver->mutex->unlock(); return res; } IP_Address res = _resolve_hostname(p_hostname, p_type); resolver->cache[key] = res; - resolver->mutex->unlock(); return res; } IP::ResolverID IP::resolve_hostname_queue_item(const String &p_hostname, IP::Type p_type) { - resolver->mutex->lock(); + MutexLock lock(resolver->mutex); ResolverID id = resolver->find_empty_id(); if (id == RESOLVER_INVALID_ID) { WARN_PRINT("Out of resolver queries"); - resolver->mutex->unlock(); return id; } @@ -157,7 +153,6 @@ IP::ResolverID IP::resolve_hostname_queue_item(const String &p_hostname, IP::Typ resolver->resolve_queues(); } - resolver->mutex->unlock(); return id; } @@ -165,50 +160,43 @@ IP::ResolverStatus IP::get_resolve_item_status(ResolverID p_id) const { ERR_FAIL_INDEX_V(p_id, IP::RESOLVER_MAX_QUERIES, IP::RESOLVER_STATUS_NONE); - resolver->mutex->lock(); + MutexLock lock(resolver->mutex); + if (resolver->queue[p_id].status == IP::RESOLVER_STATUS_NONE) { ERR_PRINT("Condition status == IP::RESOLVER_STATUS_NONE"); - resolver->mutex->unlock(); + resolver->mutex.unlock(); return IP::RESOLVER_STATUS_NONE; } - IP::ResolverStatus res = resolver->queue[p_id].status; - - resolver->mutex->unlock(); - return res; + return resolver->queue[p_id].status; } IP_Address IP::get_resolve_item_address(ResolverID p_id) const { ERR_FAIL_INDEX_V(p_id, IP::RESOLVER_MAX_QUERIES, IP_Address()); - resolver->mutex->lock(); + MutexLock lock(resolver->mutex); if (resolver->queue[p_id].status != IP::RESOLVER_STATUS_DONE) { ERR_PRINT("Resolve of '" + resolver->queue[p_id].hostname + "'' didn't complete yet."); - resolver->mutex->unlock(); + resolver->mutex.unlock(); return IP_Address(); } - IP_Address res = resolver->queue[p_id].response; - - resolver->mutex->unlock(); - return res; + return resolver->queue[p_id].response; } void IP::erase_resolve_item(ResolverID p_id) { ERR_FAIL_INDEX(p_id, IP::RESOLVER_MAX_QUERIES); - resolver->mutex->lock(); + MutexLock lock(resolver->mutex); resolver->queue[p_id].status = IP::RESOLVER_STATUS_NONE; - - resolver->mutex->unlock(); } void IP::clear_cache(const String &p_hostname) { - resolver->mutex->lock(); + MutexLock lock(resolver->mutex); if (p_hostname.empty()) { resolver->cache.clear(); @@ -218,8 +206,6 @@ void IP::clear_cache(const String &p_hostname) { resolver->cache.erase(_IP_ResolverPrivate::get_cache_key(p_hostname, IP::TYPE_IPV6)); resolver->cache.erase(_IP_ResolverPrivate::get_cache_key(p_hostname, IP::TYPE_ANY)); } - - resolver->mutex->unlock(); } Array IP::_get_local_addresses() const { @@ -315,7 +301,6 @@ IP::IP() { singleton = this; resolver = memnew(_IP_ResolverPrivate); resolver->sem = NULL; - resolver->mutex = Mutex::create(); #ifndef NO_THREADS @@ -349,6 +334,5 @@ IP::~IP() { #endif - memdelete(resolver->mutex); memdelete(resolver); } diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 39bbebefa6..b43cd7f1a2 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -288,9 +288,7 @@ RES ResourceLoader::_load(const String &p_path, const String &p_original_path, c bool ResourceLoader::_add_to_loading_map(const String &p_path) { bool success; - if (loading_map_mutex) { - loading_map_mutex->lock(); - } + MutexLock lock(loading_map_mutex); LoadingMapKey key; key.path = p_path; @@ -303,43 +301,27 @@ bool ResourceLoader::_add_to_loading_map(const String &p_path) { success = true; } - if (loading_map_mutex) { - loading_map_mutex->unlock(); - } - return success; } void ResourceLoader::_remove_from_loading_map(const String &p_path) { - if (loading_map_mutex) { - loading_map_mutex->lock(); - } + MutexLock lock(loading_map_mutex); LoadingMapKey key; key.path = p_path; key.thread = Thread::get_caller_id(); loading_map.erase(key); - - if (loading_map_mutex) { - loading_map_mutex->unlock(); - } } void ResourceLoader::_remove_from_loading_map_and_thread(const String &p_path, Thread::ID p_thread) { - if (loading_map_mutex) { - loading_map_mutex->lock(); - } + MutexLock lock(loading_map_mutex); LoadingMapKey key; key.path = p_path; key.thread = p_thread; loading_map.erase(key); - - if (loading_map_mutex) { - loading_map_mutex->unlock(); - } } RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p_no_cache, Error *r_error) { @@ -1002,13 +984,10 @@ void ResourceLoader::remove_custom_loaders() { } } -Mutex *ResourceLoader::loading_map_mutex = NULL; +Mutex ResourceLoader::loading_map_mutex; HashMap<ResourceLoader::LoadingMapKey, int, ResourceLoader::LoadingMapKeyHasher> ResourceLoader::loading_map; void ResourceLoader::initialize() { -#ifndef NO_THREADS - loading_map_mutex = Mutex::create(); -#endif } void ResourceLoader::finalize() { @@ -1018,8 +997,6 @@ void ResourceLoader::finalize() { ERR_PRINT("Exited while resource is being loaded: " + K->path); } loading_map.clear(); - memdelete(loading_map_mutex); - loading_map_mutex = NULL; #endif } diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index 4e83427fae..172f8e979b 100644 --- a/core/io/resource_loader.h +++ b/core/io/resource_loader.h @@ -120,7 +120,7 @@ class ResourceLoader { static ResourceLoadedCallback _loaded_callback; static Ref<ResourceFormatLoader> _find_custom_resource_format_loader(String path); - static Mutex *loading_map_mutex; + static Mutex loading_map_mutex; //used to track paths being loaded in a thread, avoids cyclic recursion struct LoadingMapKey { diff --git a/core/os/mutex.cpp b/core/os/mutex.cpp index f099b4319a..74c308f646 100644 --- a/core/os/mutex.cpp +++ b/core/os/mutex.cpp @@ -30,31 +30,17 @@ #include "mutex.h" -#include "core/error_macros.h" - -#include <stddef.h> - -Mutex *(*Mutex::create_func)(bool) = 0; - -Mutex *Mutex::create(bool p_recursive) { - - ERR_FAIL_COND_V(!create_func, 0); - - return create_func(p_recursive); -} - -Mutex::~Mutex() { -} - -Mutex *_global_mutex = NULL; +static Mutex _global_mutex; void _global_lock() { - - if (_global_mutex) - _global_mutex->lock(); + _global_mutex.lock(); } -void _global_unlock() { - if (_global_mutex) - _global_mutex->unlock(); +void _global_unlock() { + _global_mutex.unlock(); } + +template class MutexImpl<std::recursive_mutex>; +template class MutexImpl<std::mutex>; +template class MutexLock<MutexImpl<std::recursive_mutex> >; +template class MutexLock<MutexImpl<std::mutex> >; diff --git a/core/os/mutex.h b/core/os/mutex.h index db82eb64f5..6cf8ee7c40 100644 --- a/core/os/mutex.h +++ b/core/os/mutex.h @@ -32,42 +32,69 @@ #define MUTEX_H #include "core/error_list.h" +#include "core/typedefs.h" -/** - * @class Mutex - * @author Juan Linietsky - * Portable Mutex (thread-safe locking) implementation. - * Mutexes are always recursive ( they don't self-lock in a single thread ). - * Mutexes can be used with a Lockp object like this, to avoid having to worry about unlocking: - * Lockp( mutex ); - */ +#if !(defined NO_THREADS) -class Mutex { -protected: - static Mutex *(*create_func)(bool); +#include <mutex> + +template <class StdMutexT> +class MutexImpl { + mutable StdMutexT mutex; public: - virtual void lock() = 0; ///< Lock the mutex, block if locked by someone else - virtual void unlock() = 0; ///< Unlock the mutex, let other threads continue - virtual Error try_lock() = 0; ///< Attempt to lock the mutex, OK on success, ERROR means it can't lock. + _ALWAYS_INLINE_ void lock() const { + mutex.lock(); + } - static Mutex *create(bool p_recursive = true); ///< Create a mutex + _ALWAYS_INLINE_ void unlock() const { + mutex.unlock(); + } - virtual ~Mutex(); + _ALWAYS_INLINE_ Error try_lock() const { + return mutex.try_lock() ? OK : ERR_BUSY; + } }; +template <class MutexT> class MutexLock { - - Mutex *mutex; + const MutexT &mutex; public: - MutexLock(Mutex *p_mutex) { - mutex = p_mutex; - if (mutex) mutex->lock(); + _ALWAYS_INLINE_ explicit MutexLock(const MutexT &p_mutex) : + mutex(p_mutex) { + mutex.lock(); } - ~MutexLock() { - if (mutex) mutex->unlock(); + + _ALWAYS_INLINE_ ~MutexLock() { + mutex.unlock(); } }; +#else + +template <class StdMutexType> +class MutexImpl { +public: + _ALWAYS_INLINE_ void lock() const {} + _ALWAYS_INLINE_ void unlock() const {} + _ALWAYS_INLINE_ Error try_lock() const { return OK; } +}; + +template <class MutexT> +class MutexLock { +public: + explicit MutexLock(const MutexT &p_mutex) {} +}; + +#endif // !NO_THREADS + +using Mutex = MutexImpl<std::recursive_mutex>; // Recursive, for general use +using BinaryMutex = MutexImpl<std::mutex>; // Non-recursive, handle with care + +extern template class MutexImpl<std::recursive_mutex>; +extern template class MutexImpl<std::mutex>; +extern template class MutexLock<MutexImpl<std::recursive_mutex> >; +extern template class MutexLock<MutexImpl<std::mutex> >; + #endif diff --git a/core/os/os.h b/core/os/os.h index 77391c3a8b..1d3619b1e6 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -41,8 +41,6 @@ #include <stdarg.h> -class Mutex; - class OS { static OS *singleton; diff --git a/core/os/thread_dummy.cpp b/core/os/thread_dummy.cpp index 916aeeda30..097c90c1fb 100644 --- a/core/os/thread_dummy.cpp +++ b/core/os/thread_dummy.cpp @@ -40,14 +40,6 @@ void ThreadDummy::make_default() { Thread::create_func = &ThreadDummy::create; }; -Mutex *MutexDummy::create(bool p_recursive) { - return memnew(MutexDummy); -}; - -void MutexDummy::make_default() { - Mutex::create_func = &MutexDummy::create; -}; - SemaphoreOld *SemaphoreDummy::create() { return memnew(SemaphoreDummy); }; diff --git a/core/os/thread_dummy.h b/core/os/thread_dummy.h index 9329cdaa32..c0976ec299 100644 --- a/core/os/thread_dummy.h +++ b/core/os/thread_dummy.h @@ -31,7 +31,6 @@ #ifndef THREAD_DUMMY_H #define THREAD_DUMMY_H -#include "core/os/mutex.h" #include "core/os/rw_lock.h" #include "core/os/semaphore.h" #include "core/os/thread.h" @@ -46,18 +45,6 @@ public: static void make_default(); }; -class MutexDummy : public Mutex { - - static Mutex *create(bool p_recursive); - -public: - virtual void lock(){}; - virtual void unlock(){}; - virtual Error try_lock() { return OK; }; - - static void make_default(); -}; - class SemaphoreDummy : public SemaphoreOld { static SemaphoreOld *create(); diff --git a/core/os/thread_safe.cpp b/core/os/thread_safe.cpp deleted file mode 100644 index d8d783ae16..0000000000 --- a/core/os/thread_safe.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/*************************************************************************/ -/* thread_safe.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 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. */ -/*************************************************************************/ - -#include "thread_safe.h" - -#include "core/error_macros.h" -#include "core/os/memory.h" - -ThreadSafe::ThreadSafe() { - - mutex = Mutex::create(); - if (!mutex) { - - WARN_PRINT("THREAD_SAFE defined, but no default mutex type"); - } -} - -ThreadSafe::~ThreadSafe() { - - if (mutex) - memdelete(mutex); -} diff --git a/core/os/thread_safe.h b/core/os/thread_safe.h index a4238a9225..0221edf491 100644 --- a/core/os/thread_safe.h +++ b/core/os/thread_safe.h @@ -33,50 +33,9 @@ #include "core/os/mutex.h" -class ThreadSafe { - - Mutex *mutex; - -public: - inline void lock() const { - if (mutex) mutex->lock(); - } - inline void unlock() const { - if (mutex) mutex->unlock(); - } - - ThreadSafe(); - ~ThreadSafe(); -}; - -class ThreadSafeMethod { - - const ThreadSafe *_ts; - -public: - ThreadSafeMethod(const ThreadSafe *p_ts) { - - _ts = p_ts; - _ts->lock(); - } - - ~ThreadSafeMethod() { _ts->unlock(); } -}; - -#ifndef NO_THREADS - -#define _THREAD_SAFE_CLASS_ ThreadSafe __thread__safe__; -#define _THREAD_SAFE_METHOD_ ThreadSafeMethod __thread_safe_method__(&__thread__safe__); -#define _THREAD_SAFE_LOCK_ __thread__safe__.lock(); -#define _THREAD_SAFE_UNLOCK_ __thread__safe__.unlock(); - -#else - -#define _THREAD_SAFE_CLASS_ -#define _THREAD_SAFE_METHOD_ -#define _THREAD_SAFE_LOCK_ -#define _THREAD_SAFE_UNLOCK_ - -#endif +#define _THREAD_SAFE_CLASS_ mutable Mutex _thread_safe_; +#define _THREAD_SAFE_METHOD_ MutexLock _thread_safe_method_(_thread_safe_); +#define _THREAD_SAFE_LOCK_ _thread_safe_.lock(); +#define _THREAD_SAFE_UNLOCK_ _thread_safe_.unlock(); #endif diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp index bb017f43e5..ac60061c67 100644 --- a/core/register_core_types.cpp +++ b/core/register_core_types.cpp @@ -90,7 +90,7 @@ static IP *ip = NULL; static _Geometry *_geometry = NULL; -extern Mutex *_global_mutex; +extern Mutex _global_mutex; extern void register_global_constants(); extern void unregister_global_constants(); @@ -105,8 +105,6 @@ void register_core_types() { ObjectDB::setup(); ResourceCache::setup(); - _global_mutex = Mutex::create(); - StringName::setup(); ResourceLoader::initialize(); @@ -319,9 +317,4 @@ void unregister_core_types() { ResourceCache::clear(); CoreStringNames::free(); StringName::cleanup(); - - if (_global_mutex) { - memdelete(_global_mutex); - _global_mutex = NULL; //still needed at a few places - }; } diff --git a/core/script_debugger_remote.cpp b/core/script_debugger_remote.cpp index fdb6135edd..67375da6e2 100644 --- a/core/script_debugger_remote.cpp +++ b/core/script_debugger_remote.cpp @@ -601,7 +601,8 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script, bool p_can_continue, void ScriptDebuggerRemote::_get_output() { - mutex->lock(); + MutexLock lock(mutex); + if (output_strings.size()) { locking = true; @@ -666,7 +667,6 @@ void ScriptDebuggerRemote::_get_output() { errors.pop_front(); locking = false; } - mutex->unlock(); } void ScriptDebuggerRemote::line_poll() { @@ -914,7 +914,8 @@ void ScriptDebuggerRemote::_send_network_bandwidth_usage() { void ScriptDebuggerRemote::send_message(const String &p_message, const Array &p_args) { - mutex->lock(); + MutexLock lock(mutex); + if (!locking && is_peer_connected()) { if (messages.size() >= max_messages_per_frame) { @@ -926,7 +927,6 @@ void ScriptDebuggerRemote::send_message(const String &p_message, const Array &p_ messages.push_back(msg); } } - mutex->unlock(); } void ScriptDebuggerRemote::send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, ErrorHandlerType p_type, const Vector<ScriptLanguage::StackInfo> &p_stack_info) { @@ -972,7 +972,7 @@ void ScriptDebuggerRemote::send_error(const String &p_func, const String &p_file err_count++; } - mutex->lock(); + MutexLock lock(mutex); if (!locking && is_peer_connected()) { @@ -990,8 +990,6 @@ void ScriptDebuggerRemote::send_error(const String &p_func, const String &p_file } } } - - mutex->unlock(); } void ScriptDebuggerRemote::_print_handler(void *p_this, const String &p_string, bool p_error) { @@ -1020,19 +1018,21 @@ void ScriptDebuggerRemote::_print_handler(void *p_this, const String &p_string, sdr->char_count += allowed_chars; bool overflowed = sdr->char_count >= sdr->max_cps; - sdr->mutex->lock(); - if (!sdr->locking && sdr->is_peer_connected()) { + { + MutexLock lock(sdr->mutex); - if (overflowed) - s += "[...]"; + if (!sdr->locking && sdr->is_peer_connected()) { - sdr->output_strings.push_back(s); + if (overflowed) + s += "[...]"; - if (overflowed) { - sdr->output_strings.push_back("[output overflow, print less text!]"); + sdr->output_strings.push_back(s); + + if (overflowed) { + sdr->output_strings.push_back("[output overflow, print less text!]"); + } } } - sdr->mutex->unlock(); } void ScriptDebuggerRemote::request_quit() { @@ -1106,7 +1106,6 @@ ScriptDebuggerRemote::ScriptDebuggerRemote() : last_net_bandwidth_time(0), performance(Engine::get_singleton()->get_singleton_object("Performance")), requested_quit(false), - mutex(Mutex::create()), max_messages_per_frame(GLOBAL_GET("network/limits/debugger_stdout/max_messages_per_frame")), n_messages_dropped(0), max_errors_per_second(GLOBAL_GET("network/limits/debugger_stdout/max_errors_per_second")), @@ -1141,5 +1140,4 @@ ScriptDebuggerRemote::~ScriptDebuggerRemote() { remove_print_handler(&phl); remove_error_handler(&eh); - memdelete(mutex); } diff --git a/core/script_debugger_remote.h b/core/script_debugger_remote.h index 682da1d276..b7a309b2f9 100644 --- a/core/script_debugger_remote.h +++ b/core/script_debugger_remote.h @@ -230,7 +230,7 @@ protected: uint64_t last_net_bandwidth_time; Object *performance; bool requested_quit; - Mutex *mutex; + Mutex mutex; List<String> output_strings; List<Message> messages; diff --git a/core/string_name.cpp b/core/string_name.cpp index 6f7b10c5fe..dd6868f6d2 100644 --- a/core/string_name.cpp +++ b/core/string_name.cpp @@ -47,12 +47,10 @@ StringName _scs_create(const char *p_chr) { } bool StringName::configured = false; -Mutex *StringName::lock = NULL; +Mutex StringName::lock; void StringName::setup() { - lock = Mutex::create(); - ERR_FAIL_COND(configured); for (int i = 0; i < STRING_TABLE_LEN; i++) { @@ -63,7 +61,7 @@ void StringName::setup() { void StringName::cleanup() { - lock->lock(); + MutexLock lock(StringName::lock); int lost_strings = 0; for (int i = 0; i < STRING_TABLE_LEN; i++) { @@ -87,9 +85,6 @@ void StringName::cleanup() { if (lost_strings) { print_verbose("StringName: " + itos(lost_strings) + " unclaimed string names at exit."); } - lock->unlock(); - - memdelete(lock); } void StringName::unref() { @@ -98,7 +93,7 @@ void StringName::unref() { if (_data && _data->refcount.unref()) { - lock->lock(); + MutexLock lock(StringName::lock); if (_data->prev) { _data->prev->next = _data->next; @@ -113,7 +108,6 @@ void StringName::unref() { _data->next->prev = _data->prev; } memdelete(_data); - lock->unlock(); } _data = NULL; @@ -184,7 +178,7 @@ StringName::StringName(const char *p_name) { if (!p_name || p_name[0] == 0) return; //empty, ignore - lock->lock(); + MutexLock lock(StringName::lock); uint32_t hash = String::hash(p_name); @@ -203,7 +197,6 @@ StringName::StringName(const char *p_name) { if (_data) { if (_data->refcount.ref()) { // exists - lock->unlock(); return; } } @@ -219,8 +212,6 @@ StringName::StringName(const char *p_name) { if (_table[idx]) _table[idx]->prev = _data; _table[idx] = _data; - - lock->unlock(); } StringName::StringName(const StaticCString &p_static_string) { @@ -231,7 +222,7 @@ StringName::StringName(const StaticCString &p_static_string) { ERR_FAIL_COND(!p_static_string.ptr || !p_static_string.ptr[0]); - lock->lock(); + MutexLock lock(StringName::lock); uint32_t hash = String::hash(p_static_string.ptr); @@ -250,7 +241,6 @@ StringName::StringName(const StaticCString &p_static_string) { if (_data) { if (_data->refcount.ref()) { // exists - lock->unlock(); return; } } @@ -266,8 +256,6 @@ StringName::StringName(const StaticCString &p_static_string) { if (_table[idx]) _table[idx]->prev = _data; _table[idx] = _data; - - lock->unlock(); } StringName::StringName(const String &p_name) { @@ -279,10 +267,9 @@ StringName::StringName(const String &p_name) { if (p_name == String()) return; - lock->lock(); + MutexLock lock(StringName::lock); uint32_t hash = p_name.hash(); - uint32_t idx = hash & STRING_TABLE_MASK; _data = _table[idx]; @@ -297,7 +284,6 @@ StringName::StringName(const String &p_name) { if (_data) { if (_data->refcount.ref()) { // exists - lock->unlock(); return; } } @@ -313,8 +299,6 @@ StringName::StringName(const String &p_name) { if (_table[idx]) _table[idx]->prev = _data; _table[idx] = _data; - - lock->unlock(); } StringName StringName::search(const char *p_name) { @@ -325,10 +309,9 @@ StringName StringName::search(const char *p_name) { if (!p_name[0]) return StringName(); - lock->lock(); + MutexLock lock(StringName::lock); uint32_t hash = String::hash(p_name); - uint32_t idx = hash & STRING_TABLE_MASK; _Data *_data = _table[idx]; @@ -342,12 +325,9 @@ StringName StringName::search(const char *p_name) { } if (_data && _data->refcount.ref()) { - lock->unlock(); - return StringName(_data); } - lock->unlock(); return StringName(); //does not exist } @@ -359,7 +339,7 @@ StringName StringName::search(const CharType *p_name) { if (!p_name[0]) return StringName(); - lock->lock(); + MutexLock lock(StringName::lock); uint32_t hash = String::hash(p_name); @@ -376,18 +356,16 @@ StringName StringName::search(const CharType *p_name) { } if (_data && _data->refcount.ref()) { - lock->unlock(); return StringName(_data); } - lock->unlock(); return StringName(); //does not exist } StringName StringName::search(const String &p_name) { ERR_FAIL_COND_V(p_name == "", StringName()); - lock->lock(); + MutexLock lock(StringName::lock); uint32_t hash = p_name.hash(); @@ -404,11 +382,9 @@ StringName StringName::search(const String &p_name) { } if (_data && _data->refcount.ref()) { - lock->unlock(); return StringName(_data); } - lock->unlock(); return StringName(); //does not exist } diff --git a/core/string_name.h b/core/string_name.h index 4096b8f650..0cf2f126aa 100644 --- a/core/string_name.h +++ b/core/string_name.h @@ -82,7 +82,7 @@ class StringName { friend void register_core_types(); friend void unregister_core_types(); - static Mutex *lock; + static Mutex lock; static void setup(); static void cleanup(); static bool configured; diff --git a/doc/classes/Array.xml b/doc/classes/Array.xml index a294967fc9..234949277a 100644 --- a/doc/classes/Array.xml +++ b/doc/classes/Array.xml @@ -14,6 +14,12 @@ array[2] = "Three" print(array[-2]) # Three. [/codeblock] + Arrays can be concatenated using the [code]+[/code] operator: + [codeblock] + var array1 = ["One", 2] + var array2 = [3, "Four"] + print(array1 + array2) # ["One", 2, 3, "Four"] + [/codeblock] Arrays are always passed by reference. </description> <tutorials> diff --git a/doc/classes/Engine.xml b/doc/classes/Engine.xml index 8cdb9c1c3f..45c153b6dc 100644 --- a/doc/classes/Engine.xml +++ b/doc/classes/Engine.xml @@ -147,10 +147,10 @@ If [code]true[/code], it is running inside the editor. Useful for tool scripts. </member> <member name="iterations_per_second" type="int" setter="set_iterations_per_second" getter="get_iterations_per_second" default="60"> - The number of fixed iterations per second (for fixed process and physics). + The number of fixed iterations per second. This controls how often physics simulation and [method Node._physics_process] methods are run. This value should generally always be set to [code]60[/code] or above, as Godot doesn't interpolate the physics step. As a result, values lower than [code]60[/code] will look stuttery. This value can be increased to make input more reactive or work around tunneling issues, but keep in mind doing so will increase CPU usage. </member> <member name="physics_jitter_fix" type="float" setter="set_physics_jitter_fix" getter="get_physics_jitter_fix" default="0.5"> - Controls how much physic ticks are synchronized with real time. For 0 or less, the ticks are synchronized. Such values are recommended for network games, where clock synchronization matters. Higher values cause higher deviation of in-game clock and real clock, but allows to smooth out framerate jitters. The default value of 0.5 should be fine for most; values above 2 could cause the game to react to dropped frames with a noticeable delay and are not recommended. + Controls how much physics ticks are synchronized with real time. For 0 or less, the ticks are synchronized. Such values are recommended for network games, where clock synchronization matters. Higher values cause higher deviation of in-game clock and real clock, but allows to smooth out framerate jitters. The default value of 0.5 should be fine for most; values above 2 could cause the game to react to dropped frames with a noticeable delay and are not recommended. </member> <member name="target_fps" type="int" setter="set_target_fps" getter="get_target_fps" default="0"> The desired frames per second. If the hardware cannot keep up, this setting may not be respected. A value of 0 means no limit. diff --git a/doc/classes/Navigation.xml b/doc/classes/Navigation.xml index 0000ca6bd5..93170bca4a 100644 --- a/doc/classes/Navigation.xml +++ b/doc/classes/Navigation.xml @@ -4,7 +4,7 @@ Mesh-based navigation and pathfinding node. </brief_description> <description> - Provides navigation and pathfinding within a collection of [NavigationMesh]es. These will be automatically collected from child [NavigationMeshInstance] nodes. In addition to basic pathfinding, this class also assists with aligning navigation agents with the meshes they are navigating on. + Provides navigation and pathfinding within a collection of [NavigationMesh]es. These will be automatically collected from child [NavigationRegion] nodes. In addition to basic pathfinding, this class also assists with aligning navigation agents with the meshes they are navigating on. </description> <tutorials> </tutorials> diff --git a/doc/classes/Navigation2D.xml b/doc/classes/Navigation2D.xml index 0d016a3210..dcbfbc2350 100644 --- a/doc/classes/Navigation2D.xml +++ b/doc/classes/Navigation2D.xml @@ -4,7 +4,7 @@ 2D navigation and pathfinding node. </brief_description> <description> - Navigation2D provides navigation and pathfinding within a 2D area, specified as a collection of [NavigationPolygon] resources. These are automatically collected from child [NavigationPolygonInstance] nodes. + Navigation2D provides navigation and pathfinding within a 2D area, specified as a collection of [NavigationPolygon] resources. These are automatically collected from child [NavigationRegion2D] nodes. </description> <tutorials> </tutorials> diff --git a/doc/classes/NavigationPolygon.xml b/doc/classes/NavigationPolygon.xml index da291b7337..b0f77dff83 100644 --- a/doc/classes/NavigationPolygon.xml +++ b/doc/classes/NavigationPolygon.xml @@ -11,7 +11,7 @@ var outline = PackedVector2Array([Vector2(0, 0), Vector2(0, 50), Vector2(50, 50), Vector2(50, 0)]) polygon.add_outline(outline) polygon.make_polygons_from_outlines() - $NavigationPolygonInstance.navpoly = polygon + $NavigationRegion2D.navpoly = polygon [/codeblock] Using [method add_polygon] and indices of the vertices array. [codeblock] @@ -20,7 +20,7 @@ polygon.set_vertices(vertices) var indices = PackedInt32Array(0, 3, 1) polygon.add_polygon(indices) - $NavigationPolygonInstance.navpoly = polygon + $NavigationRegion2D.navpoly = polygon [/codeblock] </description> <tutorials> diff --git a/doc/classes/NavigationMeshInstance.xml b/doc/classes/NavigationRegion.xml index 75bd62e278..41fac70654 100644 --- a/doc/classes/NavigationMeshInstance.xml +++ b/doc/classes/NavigationRegion.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="NavigationMeshInstance" inherits="Spatial" version="4.0"> +<class name="NavigationRegion" inherits="Spatial" version="4.0"> <brief_description> - An instance of a [NavigationMesh]. + A region of the navigation map. </brief_description> <description> - An instance of a [NavigationMesh]. It tells the [Navigation] node what can be navigated and what cannot, based on the [NavigationMesh] resource. This should be a child of a [Navigation] node. + A region of the navigation map. It tells the [Navigation] node what can be navigated and what cannot, based on the [NavigationMesh] resource. This should be a child of a [Navigation] node (even not a direct child). </description> <tutorials> </tutorials> @@ -19,7 +19,7 @@ </methods> <members> <member name="enabled" type="bool" setter="set_enabled" getter="is_enabled" default="true"> - Determines if the [NavigationMeshInstance] is enabled or disabled. + Determines if the [NavigationRegion] is enabled or disabled. </member> <member name="navmesh" type="NavigationMesh" setter="set_navigation_mesh" getter="get_navigation_mesh"> The [NavigationMesh] resource to use. diff --git a/doc/classes/NavigationPolygonInstance.xml b/doc/classes/NavigationRegion2D.xml index 34c6b09859..aef114e1db 100644 --- a/doc/classes/NavigationPolygonInstance.xml +++ b/doc/classes/NavigationRegion2D.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="NavigationPolygonInstance" inherits="Node2D" version="4.0"> +<class name="NavigationRegion2D" inherits="Node2D" version="4.0"> <brief_description> </brief_description> <description> diff --git a/doc/classes/PhysicsServer.xml b/doc/classes/PhysicsServer.xml index 592d3d8e4e..c9f4accee2 100644 --- a/doc/classes/PhysicsServer.xml +++ b/doc/classes/PhysicsServer.xml @@ -1467,7 +1467,7 @@ If [code]set[/code] there is a linear motor on this axis that targets a specific velocity. </constant> <constant name="SHAPE_PLANE" value="0" enum="ShapeType"> - The [Shape] is a [PlaneShape]. + The [Shape] is a [WorldMarginShape]. </constant> <constant name="SHAPE_RAY" value="1" enum="ShapeType"> The [Shape] is a [RayShape]. diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 236931f877..a2c6ed34e0 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -968,10 +968,12 @@ Enables [member Viewport.physics_object_picking] on the root viewport. </member> <member name="physics/common/physics_fps" type="int" setter="" getter="" default="60"> - Frames per second used in the physics. Physics always needs a fixed amount of frames per second. + The number of fixed iterations per second. This controls how often physics simulation and [method Node._physics_process] methods are run. + [b]Note:[/b] This property is only read when the project starts. To change the physics FPS at runtime, set [member Engine.iterations_per_second] instead. </member> <member name="physics/common/physics_jitter_fix" type="float" setter="" getter="" default="0.5"> Fix to improve physics jitter, specially on monitors where refresh rate is different than the physics FPS. + [b]Note:[/b] This property is only read when the project starts. To change the physics FPS at runtime, set [member Engine.physics_jitter_fix] instead. </member> <member name="rendering/environment/default_clear_color" type="Color" setter="" getter="" default="Color( 0.3, 0.3, 0.3, 1 )"> Default background clear color. Overridable per [Viewport] using its [Environment]. See [member Environment.background_mode] and [member Environment.background_color] in particular. To change this default color programmatically, use [method VisualServer.set_default_clear_color]. @@ -1035,23 +1037,28 @@ Lower-end override for [member rendering/quality/intended_usage/framebuffer_allocation] on mobile devices, due to performance concerns or driver support. </member> <member name="rendering/quality/reflection_atlas/reflection_count" type="int" setter="" getter="" default="64"> + Number of cubemaps to store in the reflection atlas. The number of [ReflectionProbe]s in a scene will be limited by this amount. A higher number requires more VRAM. </member> - <member name="rendering/quality/reflection_atlas/reflection_size" type="int" setter="" getter="" default="256"> + <member name="rendering/quality/reflection_atlas/reflection_size" type="int" setter="" getter="" default="128"> + Size of cubemap faces for [ReflectionProbe]s. A higher number requires more VRAM and may make reflection probe updating slower. </member> <member name="rendering/quality/reflection_atlas/reflection_size.mobile" type="int" setter="" getter="" default="128"> + Lower-end override for [member rendering/quality/reflection_atlas/reflection_size] on mobile devices, due to performance concerns or driver support. + </member> + <member name="rendering/quality/reflections/fast_filter_high_quality" type="bool" setter="" getter="" default="false"> + Use a higher quality variant of the fast filtering algorithm. Significantly slower than using default quality, but results in smoother reflections. Should only be used when the scene is especially detailed. </member> <member name="rendering/quality/reflections/ggx_samples" type="int" setter="" getter="" default="1024"> + Sets the number of samples to take when using importance sampling for [Sky]s and [ReflectionProbe]s. A higher value will result in smoother, higher quality reflections, but increases time to calculate radiance maps. In general, fewer samples are needed for simpler, low dynamic range environments while more samples are needed for HDR environments and environments with a high level of detail. </member> <member name="rendering/quality/reflections/ggx_samples.mobile" type="int" setter="" getter="" default="128"> - </member> - <member name="rendering/quality/reflections/ggx_samples_realtime" type="int" setter="" getter="" default="64"> - </member> - <member name="rendering/quality/reflections/ggx_samples_realtime.mobile" type="int" setter="" getter="" default="16"> + Lower-end override for [member rendering/quality/reflections/ggx_samples] on mobile devices, due to performance concerns or driver support. </member> <member name="rendering/quality/reflections/roughness_layers" type="int" setter="" getter="" default="6"> + Limits the number of layers to use in radiance maps when using importance sampling. A lower number will be slightly faster and take up less VRAM. </member> <member name="rendering/quality/reflections/texture_array_reflections" type="bool" setter="" getter="" default="true"> - If [code]true[/code], uses texture arrays instead of mipmaps for reflection probes and panorama backgrounds (sky). This reduces jitter noise on reflections, but costs more performance and memory. + If [code]true[/code], uses texture arrays instead of mipmaps for reflection probes and panorama backgrounds (sky). This reduces jitter noise and upscaling artifacts on reflections, but is significantly slower to compute and uses [member rendering/quality/reflections/roughness_layers] times more memory. </member> <member name="rendering/quality/reflections/texture_array_reflections.mobile" type="bool" setter="" getter="" default="false"> Lower-end override for [member rendering/quality/reflections/texture_array_reflections] on mobile devices, due to performance concerns or driver support. diff --git a/doc/classes/ReflectionProbe.xml b/doc/classes/ReflectionProbe.xml index 9c7a645fec..e138af6841 100644 --- a/doc/classes/ReflectionProbe.xml +++ b/doc/classes/ReflectionProbe.xml @@ -4,7 +4,7 @@ Captures its surroundings to create reflections. </brief_description> <description> - Capture its surroundings as a dual parabolid image, and stores versions of it with increasing levels of blur to simulate different material roughnesses. + Captures its surroundings as a cubemap, and stores versions of it with increasing levels of blur to simulate different material roughnesses. The [ReflectionProbe] is used to create high-quality reflections at the cost of performance. It can be combined with [GIProbe]s and Screen Space Reflections to achieve high quality reflections. [ReflectionProbe]s render all objects within their [member cull_mask], so updating them can be quite expensive. It is best to update them once with the important static objects and then leave them. </description> <tutorials> @@ -52,7 +52,7 @@ </members> <constants> <constant name="UPDATE_ONCE" value="0" enum="UpdateMode"> - Update the probe once on the next frame. + Update the probe once on the next frame. The corresponding radiance map will be generated over the following six frames. This is slower to update than [constant UPDATE_ALWAYS] but can result in higher quality reflections. </constant> <constant name="UPDATE_ALWAYS" value="1" enum="UpdateMode"> Update the probe every frame. This is needed when you want to capture dynamic objects. However, it results in an increased render time. Use [constant UPDATE_ONCE] whenever possible. diff --git a/doc/classes/Sky.xml b/doc/classes/Sky.xml index 72599a323d..ba9c5ee661 100644 --- a/doc/classes/Sky.xml +++ b/doc/classes/Sky.xml @@ -12,6 +12,7 @@ </methods> <members> <member name="process_mode" type="int" setter="set_process_mode" getter="get_process_mode" enum="Sky.ProcessMode" default="0"> + Sets the method for generating the radiance map from the sky. The radiance map is a cubemap with increasingly blurry versions of the sky corresponding to different levels of roughness. Radiance maps can be expensive to calculate. See [enum ProcessMode] for options. </member> <member name="radiance_size" type="int" setter="set_radiance_size" getter="get_radiance_size" enum="Sky.RadianceSize" default="2"> The [Sky]'s radiance map size. The higher the radiance map size, the more detailed the lighting from the [Sky] will be. @@ -45,8 +46,11 @@ Represents the size of the [enum RadianceSize] enum. </constant> <constant name="PROCESS_MODE_QUALITY" value="0" enum="ProcessMode"> + Uses high quality importance sampling to process the radiance map. In general, this results in much higher quality than [constant PROCESS_MODE_REALTIME] but takes much longer to generate. This should not be used if you plan on changing the sky at runtime. </constant> <constant name="PROCESS_MODE_REALTIME" value="1" enum="ProcessMode"> + Uses the fast filtering algorithm to process the radiance map. In general this results in lower quality, but substantially faster run times. + [b]Note:[/b] The fast filtering algorithm is limited to 128x128 cubemaps, so [member radiance_size] must be set to [constant RADIANCE_SIZE_128]. </constant> </constants> </class> diff --git a/doc/classes/PlaneShape.xml b/doc/classes/WorldMarginShape.xml index b40e133d00..54f76a066b 100644 --- a/doc/classes/PlaneShape.xml +++ b/doc/classes/WorldMarginShape.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="PlaneShape" inherits="Shape" version="4.0"> +<class name="WorldMarginShape" inherits="Shape" version="4.0"> <brief_description> Infinite plane shape for 3D collisions. </brief_description> <description> - An infinite plane shape for 3D collisions. Note that the [Plane]'s normal matters; anything "below" the plane will collide with it. If the [PlaneShape] is used in a [PhysicsBody], it will cause colliding objects placed "below" it to teleport "above" the plane. + An infinite plane shape for 3D collisions. Note that the [Plane]'s normal matters; anything "below" the plane will collide with it. If the [WorldMarginShape] is used in a [PhysicsBody], it will cause colliding objects placed "below" it to teleport "above" the plane. </description> <tutorials> </tutorials> @@ -12,7 +12,7 @@ </methods> <members> <member name="plane" type="Plane" setter="set_plane" getter="get_plane" default="Plane( 0, 1, 0, 0 )"> - The [Plane] used by the [PlaneShape] for collision. + The [Plane] used by the [WorldMarginShape] for collision. </member> </members> <constants> diff --git a/drivers/alsa/audio_driver_alsa.cpp b/drivers/alsa/audio_driver_alsa.cpp index fe6cd091b7..400ce31bf7 100644 --- a/drivers/alsa/audio_driver_alsa.cpp +++ b/drivers/alsa/audio_driver_alsa.cpp @@ -154,7 +154,6 @@ Error AudioDriverALSA::init() { Error err = init_device(); if (err == OK) { - mutex = Mutex::create(); thread = Thread::create(AudioDriverALSA::thread_func, this); } @@ -299,16 +298,16 @@ void AudioDriverALSA::set_device(String device) { void AudioDriverALSA::lock() { - if (!thread || !mutex) + if (!thread) return; - mutex->lock(); + mutex.lock(); } void AudioDriverALSA::unlock() { - if (!thread || !mutex) + if (!thread) return; - mutex->unlock(); + mutex.unlock(); } void AudioDriverALSA::finish_device() { @@ -327,11 +326,6 @@ void AudioDriverALSA::finish() { memdelete(thread); thread = NULL; - - if (mutex) { - memdelete(mutex); - mutex = NULL; - } } finish_device(); @@ -339,7 +333,6 @@ void AudioDriverALSA::finish() { AudioDriverALSA::AudioDriverALSA() : thread(NULL), - mutex(NULL), pcm_handle(NULL), device_name("Default"), new_device("Default") { diff --git a/drivers/alsa/audio_driver_alsa.h b/drivers/alsa/audio_driver_alsa.h index fb793df6cd..a8caf0fbae 100644 --- a/drivers/alsa/audio_driver_alsa.h +++ b/drivers/alsa/audio_driver_alsa.h @@ -40,7 +40,7 @@ class AudioDriverALSA : public AudioDriver { Thread *thread; - Mutex *mutex; + Mutex mutex; snd_pcm_t *pcm_handle; diff --git a/drivers/alsamidi/midi_driver_alsamidi.cpp b/drivers/alsamidi/midi_driver_alsamidi.cpp index 670d7e0a4a..0cecf1de3e 100644 --- a/drivers/alsamidi/midi_driver_alsamidi.cpp +++ b/drivers/alsamidi/midi_driver_alsamidi.cpp @@ -148,7 +148,6 @@ Error MIDIDriverALSAMidi::open() { } snd_device_name_free_hint(hints); - mutex = Mutex::create(); exit_thread = false; thread = Thread::create(MIDIDriverALSAMidi::thread_func, this); @@ -165,11 +164,6 @@ void MIDIDriverALSAMidi::close() { thread = NULL; } - if (mutex) { - memdelete(mutex); - mutex = NULL; - } - for (int i = 0; i < connected_inputs.size(); i++) { snd_rawmidi_t *midi_in = connected_inputs[i]; snd_rawmidi_close(midi_in); @@ -179,14 +173,12 @@ void MIDIDriverALSAMidi::close() { void MIDIDriverALSAMidi::lock() const { - if (mutex) - mutex->lock(); + mutex.lock(); } void MIDIDriverALSAMidi::unlock() const { - if (mutex) - mutex->unlock(); + mutex.unlock(); } PackedStringArray MIDIDriverALSAMidi::get_connected_inputs() { @@ -210,7 +202,6 @@ PackedStringArray MIDIDriverALSAMidi::get_connected_inputs() { MIDIDriverALSAMidi::MIDIDriverALSAMidi() { - mutex = NULL; thread = NULL; exit_thread = false; diff --git a/drivers/alsamidi/midi_driver_alsamidi.h b/drivers/alsamidi/midi_driver_alsamidi.h index 9900d90553..6797c7c138 100644 --- a/drivers/alsamidi/midi_driver_alsamidi.h +++ b/drivers/alsamidi/midi_driver_alsamidi.h @@ -44,7 +44,7 @@ class MIDIDriverALSAMidi : public MIDIDriver { Thread *thread; - Mutex *mutex; + Mutex mutex; Vector<snd_rawmidi_t *> connected_inputs; diff --git a/drivers/coreaudio/audio_driver_coreaudio.cpp b/drivers/coreaudio/audio_driver_coreaudio.cpp index d8229f7bf2..1e95bcf5d9 100644 --- a/drivers/coreaudio/audio_driver_coreaudio.cpp +++ b/drivers/coreaudio/audio_driver_coreaudio.cpp @@ -69,8 +69,6 @@ OSStatus AudioDriverCoreAudio::output_device_address_cb(AudioObjectID inObjectID #endif Error AudioDriverCoreAudio::init() { - mutex = Mutex::create(); - AudioComponentDescription desc; zeromem(&desc, sizeof(desc)); desc.componentType = kAudioUnitType_Output; @@ -280,19 +278,15 @@ AudioDriver::SpeakerMode AudioDriverCoreAudio::get_speaker_mode() const { }; void AudioDriverCoreAudio::lock() { - if (mutex) - mutex->lock(); + mutex.lock(); }; void AudioDriverCoreAudio::unlock() { - if (mutex) - mutex->unlock(); + mutex.unlock(); }; bool AudioDriverCoreAudio::try_lock() { - if (mutex) - return mutex->try_lock() == OK; - return true; + return mutex.try_lock() == OK; } void AudioDriverCoreAudio::finish() { @@ -344,11 +338,6 @@ void AudioDriverCoreAudio::finish() { audio_unit = NULL; unlock(); } - - if (mutex) { - memdelete(mutex); - mutex = NULL; - } } Error AudioDriverCoreAudio::capture_init() { @@ -691,7 +680,6 @@ AudioDriverCoreAudio::AudioDriverCoreAudio() : audio_unit(NULL), input_unit(NULL), active(false), - mutex(NULL), device_name("Default"), capture_device_name("Default"), mix_rate(0), diff --git a/drivers/coreaudio/audio_driver_coreaudio.h b/drivers/coreaudio/audio_driver_coreaudio.h index 05aa759078..fb9473e230 100644 --- a/drivers/coreaudio/audio_driver_coreaudio.h +++ b/drivers/coreaudio/audio_driver_coreaudio.h @@ -46,7 +46,7 @@ class AudioDriverCoreAudio : public AudioDriver { AudioComponentInstance input_unit; bool active; - Mutex *mutex; + Mutex mutex; String device_name; String capture_device_name; diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.cpp b/drivers/pulseaudio/audio_driver_pulseaudio.cpp index df9303fbec..ee9278fb8f 100644 --- a/drivers/pulseaudio/audio_driver_pulseaudio.cpp +++ b/drivers/pulseaudio/audio_driver_pulseaudio.cpp @@ -291,7 +291,6 @@ Error AudioDriverPulseAudio::init() { Error err = init_device(); if (err == OK) { - mutex = Mutex::create(); thread = Thread::create(AudioDriverPulseAudio::thread_func, this); } @@ -597,16 +596,16 @@ void AudioDriverPulseAudio::set_device(String device) { void AudioDriverPulseAudio::lock() { - if (!thread || !mutex) + if (!thread) return; - mutex->lock(); + mutex.lock(); } void AudioDriverPulseAudio::unlock() { - if (!thread || !mutex) + if (!thread) return; - mutex->unlock(); + mutex.unlock(); } void AudioDriverPulseAudio::finish_device() { @@ -640,10 +639,6 @@ void AudioDriverPulseAudio::finish() { } memdelete(thread); - if (mutex) { - memdelete(mutex); - mutex = NULL; - } thread = NULL; } @@ -800,7 +795,6 @@ String AudioDriverPulseAudio::capture_get_device() { AudioDriverPulseAudio::AudioDriverPulseAudio() : thread(NULL), - mutex(NULL), pa_ml(NULL), pa_ctx(NULL), pa_str(NULL), diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.h b/drivers/pulseaudio/audio_driver_pulseaudio.h index 15948fa763..1ece332a8a 100644 --- a/drivers/pulseaudio/audio_driver_pulseaudio.h +++ b/drivers/pulseaudio/audio_driver_pulseaudio.h @@ -42,7 +42,7 @@ class AudioDriverPulseAudio : public AudioDriver { Thread *thread; - Mutex *mutex; + Mutex mutex; pa_mainloop *pa_ml; pa_context *pa_ctx; diff --git a/drivers/unix/mutex_posix.cpp b/drivers/unix/mutex_posix.cpp deleted file mode 100644 index a9fc12fb06..0000000000 --- a/drivers/unix/mutex_posix.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/*************************************************************************/ -/* mutex_posix.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 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. */ -/*************************************************************************/ - -#include "mutex_posix.h" - -#include "core/os/memory.h" - -#if defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED) - -void MutexPosix::lock() { - - pthread_mutex_lock(&mutex); -} -void MutexPosix::unlock() { - - pthread_mutex_unlock(&mutex); -} -Error MutexPosix::try_lock() { - - return (pthread_mutex_trylock(&mutex) == 0) ? OK : ERR_BUSY; -} - -Mutex *MutexPosix::create_func_posix(bool p_recursive) { - - return memnew(MutexPosix(p_recursive)); -} - -void MutexPosix::make_default() { - - create_func = create_func_posix; -} - -MutexPosix::MutexPosix(bool p_recursive) { - - pthread_mutexattr_init(&attr); - if (p_recursive) - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(&mutex, &attr); -} - -MutexPosix::~MutexPosix() { - - pthread_mutex_destroy(&mutex); -} - -#endif diff --git a/drivers/unix/mutex_posix.h b/drivers/unix/mutex_posix.h deleted file mode 100644 index bd67106836..0000000000 --- a/drivers/unix/mutex_posix.h +++ /dev/null @@ -1,61 +0,0 @@ -/*************************************************************************/ -/* mutex_posix.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 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 MUTEX_POSIX_H -#define MUTEX_POSIX_H - -#if defined(UNIX_ENABLED) || defined(PTHREAD_ENABLED) - -#include "core/os/mutex.h" - -#include <pthread.h> - -class MutexPosix : public Mutex { - - pthread_mutexattr_t attr; - pthread_mutex_t mutex; - - static Mutex *create_func_posix(bool p_recursive); - -public: - virtual void lock(); - virtual void unlock(); - virtual Error try_lock(); - - static void make_default(); - - MutexPosix(bool p_recursive); - - ~MutexPosix(); -}; - -#endif - -#endif diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index 2d8d37b2f1..1d94b9618d 100644 --- a/drivers/unix/os_unix.cpp +++ b/drivers/unix/os_unix.cpp @@ -36,7 +36,6 @@ #include "core/project_settings.h" #include "drivers/unix/dir_access_unix.h" #include "drivers/unix/file_access_unix.h" -#include "drivers/unix/mutex_posix.h" #include "drivers/unix/net_socket_posix.h" #include "drivers/unix/rw_lock_posix.h" #include "drivers/unix/semaphore_posix.h" @@ -123,14 +122,12 @@ void OS_Unix::initialize_core() { #ifdef NO_THREADS ThreadDummy::make_default(); SemaphoreDummy::make_default(); - MutexDummy::make_default(); RWLockDummy::make_default(); #else ThreadPosix::make_default(); #if !defined(OSX_ENABLED) && !defined(IPHONE_ENABLED) SemaphorePosix::make_default(); #endif - MutexPosix::make_default(); RWLockPosix::make_default(); #endif FileAccess::make_default<FileAccessUnix>(FileAccess::ACCESS_RESOURCES); diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp index 8aa6fb96c9..fa78771993 100644 --- a/drivers/wasapi/audio_driver_wasapi.cpp +++ b/drivers/wasapi/audio_driver_wasapi.cpp @@ -406,7 +406,6 @@ Error AudioDriverWASAPI::init() { exit_thread = false; thread_exited = false; - mutex = Mutex::create(true); thread = Thread::create(thread_func, this); return OK; @@ -782,14 +781,12 @@ void AudioDriverWASAPI::start() { void AudioDriverWASAPI::lock() { - if (mutex) - mutex->lock(); + mutex.lock(); } void AudioDriverWASAPI::unlock() { - if (mutex) - mutex->unlock(); + mutex.unlock(); } void AudioDriverWASAPI::finish() { @@ -804,11 +801,6 @@ void AudioDriverWASAPI::finish() { finish_capture_device(); finish_render_device(); - - if (mutex) { - memdelete(mutex); - mutex = NULL; - } } Error AudioDriverWASAPI::capture_start() { @@ -863,7 +855,6 @@ String AudioDriverWASAPI::capture_get_device() { AudioDriverWASAPI::AudioDriverWASAPI() { - mutex = NULL; thread = NULL; samples_in.clear(); diff --git a/drivers/wasapi/audio_driver_wasapi.h b/drivers/wasapi/audio_driver_wasapi.h index ebceedd431..3ea61c6010 100644 --- a/drivers/wasapi/audio_driver_wasapi.h +++ b/drivers/wasapi/audio_driver_wasapi.h @@ -75,7 +75,7 @@ class AudioDriverWASAPI : public AudioDriver { AudioDeviceWASAPI audio_input; AudioDeviceWASAPI audio_output; - Mutex *mutex; + Mutex mutex; Thread *thread; Vector<int32_t> samples_in; diff --git a/drivers/windows/mutex_windows.cpp b/drivers/windows/mutex_windows.cpp deleted file mode 100644 index 1f14adb48f..0000000000 --- a/drivers/windows/mutex_windows.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/*************************************************************************/ -/* mutex_windows.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 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. */ -/*************************************************************************/ - -#include "mutex_windows.h" - -#include "core/os/memory.h" - -#ifdef WINDOWS_ENABLED - -void MutexWindows::lock() { - -#ifdef WINDOWS_USE_MUTEX - WaitForSingleObject(mutex, INFINITE); -#else - EnterCriticalSection(&mutex); -#endif -} - -void MutexWindows::unlock() { - -#ifdef WINDOWS_USE_MUTEX - ReleaseMutex(mutex); -#else - LeaveCriticalSection(&mutex); -#endif -} - -Error MutexWindows::try_lock() { - -#ifdef WINDOWS_USE_MUTEX - return (WaitForSingleObject(mutex, 0) == WAIT_TIMEOUT) ? ERR_BUSY : OK; -#else - - if (TryEnterCriticalSection(&mutex)) - return OK; - else - return ERR_BUSY; -#endif -} - -Mutex *MutexWindows::create_func_windows(bool p_recursive) { - - return memnew(MutexWindows); -} - -void MutexWindows::make_default() { - - create_func = create_func_windows; -} - -MutexWindows::MutexWindows() { - -#ifdef WINDOWS_USE_MUTEX - mutex = CreateMutex(NULL, FALSE, NULL); -#else -#ifdef UWP_ENABLED - InitializeCriticalSectionEx(&mutex, 0, 0); -#else - InitializeCriticalSection(&mutex); -#endif -#endif -} - -MutexWindows::~MutexWindows() { - -#ifdef WINDOWS_USE_MUTEX - CloseHandle(mutex); -#else - - DeleteCriticalSection(&mutex); -#endif -} - -#endif diff --git a/drivers/windows/mutex_windows.h b/drivers/windows/mutex_windows.h deleted file mode 100644 index 28b97540b7..0000000000 --- a/drivers/windows/mutex_windows.h +++ /dev/null @@ -1,63 +0,0 @@ -/*************************************************************************/ -/* mutex_windows.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 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 MUTEX_WINDOWS_H -#define MUTEX_WINDOWS_H - -#ifdef WINDOWS_ENABLED - -#include "core/os/mutex.h" - -#include <windows.h> - -class MutexWindows : public Mutex { - -#ifdef WINDOWS_USE_MUTEX - HANDLE mutex; -#else - CRITICAL_SECTION mutex; -#endif - - static Mutex *create_func_windows(bool p_recursive); - -public: - virtual void lock(); - virtual void unlock(); - virtual Error try_lock(); - - static void make_default(); - - MutexWindows(); - ~MutexWindows(); -}; - -#endif - -#endif diff --git a/drivers/xaudio2/audio_driver_xaudio2.cpp b/drivers/xaudio2/audio_driver_xaudio2.cpp index 85e505009b..9c7cb4f0f3 100644 --- a/drivers/xaudio2/audio_driver_xaudio2.cpp +++ b/drivers/xaudio2/audio_driver_xaudio2.cpp @@ -79,7 +79,6 @@ Error AudioDriverXAudio2::init() { hr = xaudio->CreateSourceVoice(&source_voice, &wave_format, 0, XAUDIO2_MAX_FREQ_RATIO, &voice_callback); ERR_FAIL_COND_V_MSG(hr != S_OK, ERR_UNAVAILABLE, "Error creating XAudio2 source voice. Error code: " + itos(hr) + "."); - mutex = Mutex::create(); thread = Thread::create(AudioDriverXAudio2::thread_func, this); return OK; @@ -158,15 +157,15 @@ float AudioDriverXAudio2::get_latency() { void AudioDriverXAudio2::lock() { - if (!thread || !mutex) + if (!thread) return; - mutex->lock(); + mutex.lock(); } void AudioDriverXAudio2::unlock() { - if (!thread || !mutex) + if (!thread) return; - mutex->unlock(); + mutex.unlock(); } void AudioDriverXAudio2::finish() { @@ -194,14 +193,11 @@ void AudioDriverXAudio2::finish() { mastering_voice->DestroyVoice(); memdelete(thread); - if (mutex) - memdelete(mutex); thread = NULL; } AudioDriverXAudio2::AudioDriverXAudio2() : thread(NULL), - mutex(NULL), current_buffer(0) { wave_format = { 0 }; for (int i = 0; i < AUDIO_BUFFERS; i++) { diff --git a/drivers/xaudio2/audio_driver_xaudio2.h b/drivers/xaudio2/audio_driver_xaudio2.h index 98950851d0..108891a288 100644 --- a/drivers/xaudio2/audio_driver_xaudio2.h +++ b/drivers/xaudio2/audio_driver_xaudio2.h @@ -65,7 +65,7 @@ class AudioDriverXAudio2 : public AudioDriver { }; Thread *thread; - Mutex *mutex; + Mutex mutex; int32_t *samples_in; int16_t *samples_out[AUDIO_BUFFERS]; diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 9cc6134f27..e889298aa3 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -5554,7 +5554,7 @@ void EditorNode::_print_handler(void *p_this, const String &p_string, bool p_err static void _execute_thread(void *p_ud) { EditorNode::ExecuteThreadArgs *eta = (EditorNode::ExecuteThreadArgs *)p_ud; - Error err = OS::get_singleton()->execute(eta->path, eta->args, true, NULL, &eta->output, &eta->exitcode, true, eta->execute_output_mutex); + Error err = OS::get_singleton()->execute(eta->path, eta->args, true, NULL, &eta->output, &eta->exitcode, true, &eta->execute_output_mutex); print_verbose("Thread exit status: " + itos(eta->exitcode)); if (err != OK) { eta->exitcode = err; @@ -5574,7 +5574,6 @@ int EditorNode::execute_and_show_output(const String &p_title, const String &p_p ExecuteThreadArgs eta; eta.path = p_path; eta.args = p_arguments; - eta.execute_output_mutex = Mutex::create(); eta.exitcode = 255; eta.done = false; @@ -5585,20 +5584,20 @@ int EditorNode::execute_and_show_output(const String &p_title, const String &p_p ERR_FAIL_COND_V(!eta.execute_output_thread, 0); while (!eta.done) { - eta.execute_output_mutex->lock(); - if (prev_len != eta.output.length()) { - String to_add = eta.output.substr(prev_len, eta.output.length()); - prev_len = eta.output.length(); - execute_outputs->add_text(to_add); - Main::iteration(); - } - eta.execute_output_mutex->unlock(); + { + MutexLock lock(eta.execute_output_mutex); + if (prev_len != eta.output.length()) { + String to_add = eta.output.substr(prev_len, eta.output.length()); + prev_len = eta.output.length(); + execute_outputs->add_text(to_add); + Main::iteration(); + } + } OS::get_singleton()->delay_usec(1000); } Thread::wait_to_finish(eta.execute_output_thread); memdelete(eta.execute_output_thread); - memdelete(eta.execute_output_mutex); execute_outputs->add_text("\nExit Code: " + itos(eta.exitcode)); if (p_close_on_errors && eta.exitcode != 0) { diff --git a/editor/editor_node.h b/editor/editor_node.h index a982b9d85f..0b3de5c142 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -107,7 +107,7 @@ public: List<String> args; String output; Thread *execute_output_thread; - Mutex *execute_output_mutex; + Mutex execute_output_mutex; int exitcode; volatile bool done; }; diff --git a/editor/editor_resource_preview.cpp b/editor/editor_resource_preview.cpp index c0f58c9aae..40482dc367 100644 --- a/editor/editor_resource_preview.cpp +++ b/editor/editor_resource_preview.cpp @@ -109,29 +109,28 @@ void EditorResourcePreview::_thread_func(void *ud) { void EditorResourcePreview::_preview_ready(const String &p_str, const Ref<Texture2D> &p_texture, const Ref<Texture2D> &p_small_texture, ObjectID id, const StringName &p_func, const Variant &p_ud) { - preview_mutex->lock(); - + MutexLock lock(preview_mutex); String path = p_str; - uint32_t hash = 0; - uint64_t modified_time = 0; - - if (p_str.begins_with("ID:")) { - hash = uint32_t(p_str.get_slicec(':', 2).to_int64()); - path = "ID:" + p_str.get_slicec(':', 1); - } else { - modified_time = FileAccess::get_modified_time(path); - } + { + uint32_t hash = 0; + uint64_t modified_time = 0; - Item item; - item.order = order++; - item.preview = p_texture; - item.small_preview = p_small_texture; - item.last_hash = hash; - item.modified_time = modified_time; + if (p_str.begins_with("ID:")) { + hash = uint32_t(p_str.get_slicec(':', 2).to_int64()); + path = "ID:" + p_str.get_slicec(':', 1); + } else { + modified_time = FileAccess::get_modified_time(path); + } - cache[path] = item; + Item item; + item.order = order++; + item.preview = p_texture; + item.small_preview = p_small_texture; + item.last_hash = hash; + item.modified_time = modified_time; - preview_mutex->unlock(); + cache[path] = item; + } MessageQueue::get_singleton()->push_call(id, p_func, path, p_texture, p_small_texture, p_ud); } @@ -219,7 +218,7 @@ void EditorResourcePreview::_thread() { while (!exit) { preview_sem->wait(); - preview_mutex->lock(); + preview_mutex.lock(); if (queue.size()) { @@ -235,10 +234,10 @@ void EditorResourcePreview::_thread() { _preview_ready(path, cache[item.path].preview, cache[item.path].small_preview, item.id, item.function, item.userdata); - preview_mutex->unlock(); + preview_mutex.unlock(); } else { - preview_mutex->unlock(); + preview_mutex.unlock(); Ref<ImageTexture> texture; Ref<ImageTexture> small_texture; @@ -345,7 +344,7 @@ void EditorResourcePreview::_thread() { } } else { - preview_mutex->unlock(); + preview_mutex.unlock(); } } exited = true; @@ -356,51 +355,54 @@ void EditorResourcePreview::queue_edited_resource_preview(const Ref<Resource> &p ERR_FAIL_NULL(p_receiver); ERR_FAIL_COND(!p_res.is_valid()); - preview_mutex->lock(); + { + MutexLock lock(preview_mutex); - String path_id = "ID:" + itos(p_res->get_instance_id()); + String path_id = "ID:" + itos(p_res->get_instance_id()); - if (cache.has(path_id) && cache[path_id].last_hash == p_res->hash_edited_version()) { + if (cache.has(path_id) && cache[path_id].last_hash == p_res->hash_edited_version()) { - cache[path_id].order = order++; - p_receiver->call(p_receiver_func, path_id, cache[path_id].preview, cache[path_id].small_preview, p_userdata); - preview_mutex->unlock(); - return; - } + cache[path_id].order = order++; + p_receiver->call(p_receiver_func, path_id, cache[path_id].preview, cache[path_id].small_preview, p_userdata); + preview_mutex.unlock(); + return; + } - cache.erase(path_id); //erase if exists, since it will be regen + cache.erase(path_id); //erase if exists, since it will be regen - QueueItem item; - item.function = p_receiver_func; - item.id = p_receiver->get_instance_id(); - item.resource = p_res; - item.path = path_id; - item.userdata = p_userdata; + QueueItem item; + item.function = p_receiver_func; + item.id = p_receiver->get_instance_id(); + item.resource = p_res; + item.path = path_id; + item.userdata = p_userdata; - queue.push_back(item); - preview_mutex->unlock(); + queue.push_back(item); + } preview_sem->post(); } void EditorResourcePreview::queue_resource_preview(const String &p_path, Object *p_receiver, const StringName &p_receiver_func, const Variant &p_userdata) { ERR_FAIL_NULL(p_receiver); - preview_mutex->lock(); - if (cache.has(p_path)) { - cache[p_path].order = order++; - p_receiver->call(p_receiver_func, p_path, cache[p_path].preview, cache[p_path].small_preview, p_userdata); - preview_mutex->unlock(); - return; - } + { + MutexLock lock(preview_mutex); + + if (cache.has(p_path)) { + cache[p_path].order = order++; + p_receiver->call(p_receiver_func, p_path, cache[p_path].preview, cache[p_path].small_preview, p_userdata); + preview_mutex.unlock(); + return; + } - QueueItem item; - item.function = p_receiver_func; - item.id = p_receiver->get_instance_id(); - item.path = p_path; - item.userdata = p_userdata; + QueueItem item; + item.function = p_receiver_func; + item.id = p_receiver->get_instance_id(); + item.path = p_path; + item.userdata = p_userdata; - queue.push_back(item); - preview_mutex->unlock(); + queue.push_back(item); + } preview_sem->post(); } @@ -434,20 +436,19 @@ void EditorResourcePreview::_bind_methods() { void EditorResourcePreview::check_for_invalidation(const String &p_path) { - preview_mutex->lock(); - + MutexLock lock(preview_mutex); bool call_invalidated = false; - if (cache.has(p_path)) { + { + if (cache.has(p_path)) { - uint64_t modified_time = FileAccess::get_modified_time(p_path); - if (modified_time != cache[p_path].modified_time) { - cache.erase(p_path); - call_invalidated = true; + uint64_t modified_time = FileAccess::get_modified_time(p_path); + if (modified_time != cache[p_path].modified_time) { + cache.erase(p_path); + call_invalidated = true; + } } } - preview_mutex->unlock(); - if (call_invalidated) { //do outside mutex call_deferred("emit_signal", "preview_invalidated", p_path); } @@ -475,7 +476,6 @@ void EditorResourcePreview::stop() { EditorResourcePreview::EditorResourcePreview() { thread = NULL; singleton = this; - preview_mutex = Mutex::create(); preview_sem = SemaphoreOld::create(); order = 0; exit = false; @@ -485,6 +485,5 @@ EditorResourcePreview::EditorResourcePreview() { EditorResourcePreview::~EditorResourcePreview() { stop(); - memdelete(preview_mutex); memdelete(preview_sem); } diff --git a/editor/editor_resource_preview.h b/editor/editor_resource_preview.h index 0a89154243..ae347c0469 100644 --- a/editor/editor_resource_preview.h +++ b/editor/editor_resource_preview.h @@ -70,7 +70,7 @@ class EditorResourcePreview : public Node { List<QueueItem> queue; - Mutex *preview_mutex; + Mutex preview_mutex; SemaphoreOld *preview_sem; Thread *thread; volatile bool exit; diff --git a/editor/fileserver/editor_file_server.cpp b/editor/fileserver/editor_file_server.cpp index af7eb0c4c7..fb44c145b2 100644 --- a/editor/fileserver/editor_file_server.cpp +++ b/editor/fileserver/editor_file_server.cpp @@ -42,9 +42,10 @@ void EditorFileServer::_close_client(ClientData *cd) { cd->connection->disconnect_from_host(); - cd->efs->wait_mutex->lock(); - cd->efs->to_wait.insert(cd->thread); - cd->efs->wait_mutex->unlock(); + { + MutexLock lock(cd->efs->wait_mutex); + cd->efs->to_wait.insert(cd->thread); + } while (cd->files.size()) { memdelete(cd->files.front()->get()); cd->files.erase(cd->files.front()); @@ -295,16 +296,16 @@ void EditorFileServer::_thread_start(void *s) { } } - self->wait_mutex->lock(); + self->wait_mutex.lock(); while (self->to_wait.size()) { Thread *w = self->to_wait.front()->get(); self->to_wait.erase(w); - self->wait_mutex->unlock(); + self->wait_mutex.unlock(); Thread::wait_to_finish(w); memdelete(w); - self->wait_mutex->lock(); + self->wait_mutex.lock(); } - self->wait_mutex->unlock(); + self->wait_mutex.unlock(); OS::get_singleton()->delay_usec(100000); } @@ -331,7 +332,6 @@ void EditorFileServer::stop() { EditorFileServer::EditorFileServer() { server.instance(); - wait_mutex = Mutex::create(); quit = false; active = false; cmd = CMD_NONE; @@ -346,5 +346,4 @@ EditorFileServer::~EditorFileServer() { quit = true; Thread::wait_to_finish(thread); memdelete(thread); - memdelete(wait_mutex); } diff --git a/editor/fileserver/editor_file_server.h b/editor/fileserver/editor_file_server.h index 4ce4c0cda6..cc3cb44566 100644 --- a/editor/fileserver/editor_file_server.h +++ b/editor/fileserver/editor_file_server.h @@ -62,7 +62,7 @@ class EditorFileServer : public Object { static void _close_client(ClientData *cd); static void _subthread_start(void *s); - Mutex *wait_mutex; + Mutex wait_mutex; Thread *thread; static void _thread_start(void *); bool quit; diff --git a/editor/icons/NavigationMeshInstance.svg b/editor/icons/NavigationMeshInstance.svg deleted file mode 100644 index 737d9c319d..0000000000 --- a/editor/icons/NavigationMeshInstance.svg +++ /dev/null @@ -1 +0,0 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 1 1.7305v6.541a2 2 0 0 0 -1 1.7285 2 2 0 0 0 2 2 2 2 0 0 0 1.7305-1h2.5078l.75-2h-3.2598a2 2 0 0 0 -.72852-.73047v-5.8555l4.6973 4.6973.77148-2.0566-4.0547-4.0547h5.8574a2 2 0 0 0 .72852.73047v.27148a2.0002 2.0002 0 0 1 .023438 0 2.0002 2.0002 0 0 1 1.8496 1.2969l.12695.33789v-1.9082a2 2 0 0 0 1-1.7285 2 2 0 0 0 -2-2 2 2 0 0 0 -1.7305 1h-6.541a2 2 0 0 0 -1.7285-1zm9 6-3 8 3-2 3 2z" fill="#fc9c9c" fill-opacity=".99608"/></svg>
\ No newline at end of file diff --git a/editor/icons/NavigationPolygonInstance.svg b/editor/icons/NavigationPolygonInstance.svg deleted file mode 100644 index e16d10614e..0000000000 --- a/editor/icons/NavigationPolygonInstance.svg +++ /dev/null @@ -1 +0,0 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#a5b7f3" fill-opacity=".98824" fill-rule="evenodd" transform="translate(0 -1036.4)"><path d="m2 1a1.0001 1.0001 0 0 0 -1 1v12a1.0001 1.0001 0 0 0 1 1h4.9023a2.1002 2.1002 0 0 1 .13086-.73633l.47461-1.2637h-4.5078v-10h8.5859l-4.293 4.293a1.0001 1.0001 0 0 0 0 1.4141l1.3262 1.3262 1.4141-3.7695a2.1002 2.1002 0 0 1 1.9922-1.3613 2.1002 2.1002 0 0 1 .43555.050781l2.2461-2.2461a1.0001 1.0001 0 0 0 -.70703-1.707h-12z" transform="translate(0 1036.4)"/><path d="m15 1051.4-3-8-3 8 3-2z"/></g></svg>
\ No newline at end of file diff --git a/editor/icons/NavigationRegion.svg b/editor/icons/NavigationRegion.svg new file mode 100644 index 0000000000..92cc9afd91 --- /dev/null +++ b/editor/icons/NavigationRegion.svg @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + inkscape:version="1.0beta2 (unknown)" + sodipodi:docname="icon_navigation_region.svg" + id="svg4" + version="1.1" + width="16" + viewBox="0 0 16 16" + height="16"> + <metadata + id="metadata10"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs8" /> + <sodipodi:namedview + inkscape:current-layer="svg4" + inkscape:window-maximized="0" + inkscape:window-y="18" + inkscape:window-x="0" + inkscape:cy="6.4771531" + inkscape:cx="15.373896" + inkscape:zoom="32" + showgrid="false" + id="namedview6" + inkscape:window-height="1041" + inkscape:window-width="1916" + inkscape:pageshadow="2" + inkscape:pageopacity="0" + guidetolerance="10" + gridtolerance="10" + objecttolerance="10" + borderopacity="1" + inkscape:document-rotation="0" + bordercolor="#666666" + pagecolor="#ffffff" /> + <path + sodipodi:nodetypes="ccccccccccccccccccc" + inkscape:connector-curvature="0" + d="M 3,1 C 1.895431,1 1,1.895431 1,3 v 10 c 0,1.104569 0.895431,2 2,2 L 7.2383,14 C 8.917345,11.151816 9.09393,5.498579 11.99998,5.00198 h 0.02344 c 0.825004,0.0095 1.559551,0.524505 1.8496,1.2969 l 0.12695,0.33789 1,-3.6367 c 0,-1.104569 -0.895431,-2 -2,-2 H 8.20155 2.99997 Z m 9,6 -3,8 3,-2 3,2 z" + fill="#fc9c9c" + fill-opacity=".99608" + id="path2-3" /> +</svg> diff --git a/editor/icons/NavigationRegion2D.svg b/editor/icons/NavigationRegion2D.svg new file mode 100644 index 0000000000..a297216cb7 --- /dev/null +++ b/editor/icons/NavigationRegion2D.svg @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + inkscape:version="1.0beta2 (unknown)" + sodipodi:docname="icon_navigation_polygon_instance.svg" + id="svg8" + version="1.1" + width="16" + viewBox="0 0 16 16" + height="16"> + <metadata + id="metadata14"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs12" /> + <sodipodi:namedview + inkscape:current-layer="svg8" + inkscape:window-maximized="0" + inkscape:window-y="18" + inkscape:window-x="0" + inkscape:cy="10.058435" + inkscape:cx="5.8836841" + inkscape:zoom="19.64431" + showgrid="false" + id="namedview10" + inkscape:window-height="1041" + inkscape:window-width="1916" + inkscape:pageshadow="2" + inkscape:pageopacity="0" + guidetolerance="10" + gridtolerance="10" + objecttolerance="10" + borderopacity="1" + inkscape:document-rotation="0" + bordercolor="#666666" + pagecolor="#ffffff" /> + <g + id="g6" + transform="translate(0 -1036.4)" + fill-rule="evenodd" + fill-opacity=".98824" + fill="#a5b7f3"> + <path + sodipodi:nodetypes="cccccccccccccc" + inkscape:connector-curvature="0" + id="path2" + transform="translate(0,1036.4)" + d="M 2,1 C 1.4477381,1.0000552 1.0000552,1.4477381 1,2 v 12 c 5.52e-5,0.552262 0.4477381,0.999945 1,1 h 4.9023 c -7.836e-4,-0.251296 0.043539,-0.500692 0.13086,-0.73633 l 0.47461,-1.2637 2.5254,-6.7362 c 0.311135,-0.8280197 1.107723,-1.3723398 1.9922,-1.3613 0.146558,0.00168 0.292536,0.018702 0.43555,0.050781 l 2.2461,-2.2461 c 0.629502,-0.6299963 0.18357,-1.7066217 -0.70703,-1.707 h -12 z" /> + <path + id="path4" + d="m15 1051.4-3-8-3 8 3-2z" /> + </g> +</svg> diff --git a/editor/icons/PlaneMesh.svg b/editor/icons/PlaneMesh.svg deleted file mode 100644 index ddcc623c67..0000000000 --- a/editor/icons/PlaneMesh.svg +++ /dev/null @@ -1 +0,0 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 12h12l-3-8h-6z" fill="none" stroke="#ffd684" stroke-linejoin="round" stroke-width="2"/></svg>
\ No newline at end of file diff --git a/editor/icons/WorldMarginShape.svg b/editor/icons/WorldMarginShape.svg new file mode 100644 index 0000000000..2c90cf6d53 --- /dev/null +++ b/editor/icons/WorldMarginShape.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1044.4 7 3 7-3-7-3z" fill="#a2d2ff" fill-rule="evenodd" transform="translate(0 -1036.4)"/></svg>
\ No newline at end of file diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index 9fb6be50d9..5651197fa3 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -41,10 +41,10 @@ #include "scene/resources/animation.h" #include "scene/resources/box_shape.h" #include "scene/resources/packed_scene.h" -#include "scene/resources/plane_shape.h" #include "scene/resources/ray_shape.h" #include "scene/resources/resource_format_text.h" #include "scene/resources/sphere_shape.h" +#include "scene/resources/world_margin_shape.h" uint32_t EditorSceneImporter::get_import_flags() const { @@ -446,9 +446,9 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh> colshape->set_name("RayShape"); Object::cast_to<Spatial>(sb)->rotate_x(Math_PI / 2); } else if (empty_draw_type == "IMAGE") { - PlaneShape *planeShape = memnew(PlaneShape); - colshape->set_shape(planeShape); - colshape->set_name("PlaneShape"); + WorldMarginShape *world_margin_shape = memnew(WorldMarginShape); + colshape->set_shape(world_margin_shape); + colshape->set_name("WorldMarginShape"); } else { SphereShape *sphereShape = memnew(SphereShape); sphereShape->set_radius(1); @@ -559,7 +559,7 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh> Ref<ArrayMesh> mesh = mi->get_mesh(); ERR_FAIL_COND_V(mesh.is_null(), NULL); - NavigationMeshInstance *nmi = memnew(NavigationMeshInstance); + NavigationRegion *nmi = memnew(NavigationRegion); nmi->set_name(_fixstr(name, "navmesh")); Ref<NavigationMesh> nmesh = memnew(NavigationMesh); diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp index 3254b32dae..92ecda8508 100644 --- a/editor/import/resource_importer_texture.cpp +++ b/editor/import/resource_importer_texture.cpp @@ -38,7 +38,8 @@ void ResourceImporterTexture::_texture_reimport_roughness(const Ref<StreamTexture> &p_tex, const String &p_normal_path, VS::TextureDetectRoughnessChannel p_channel) { - singleton->mutex->lock(); + MutexLock lock(singleton->mutex); + StringName path = p_tex->get_path(); if (!singleton->make_flags.has(path)) { @@ -48,13 +49,12 @@ void ResourceImporterTexture::_texture_reimport_roughness(const Ref<StreamTextur singleton->make_flags[path].flags |= MAKE_ROUGHNESS_FLAG; singleton->make_flags[path].channel_for_roughness = p_channel; singleton->make_flags[path].normal_path_for_roughness = p_normal_path; - - singleton->mutex->unlock(); } void ResourceImporterTexture::_texture_reimport_3d(const Ref<StreamTexture> &p_tex) { - singleton->mutex->lock(); + MutexLock lock(singleton->mutex); + StringName path = p_tex->get_path(); if (!singleton->make_flags.has(path)) { @@ -62,13 +62,12 @@ void ResourceImporterTexture::_texture_reimport_3d(const Ref<StreamTexture> &p_t } singleton->make_flags[path].flags |= MAKE_3D_FLAG; - - singleton->mutex->unlock(); } void ResourceImporterTexture::_texture_reimport_normal(const Ref<StreamTexture> &p_tex) { - singleton->mutex->lock(); + MutexLock lock(singleton->mutex); + StringName path = p_tex->get_path(); if (!singleton->make_flags.has(path)) { @@ -76,8 +75,6 @@ void ResourceImporterTexture::_texture_reimport_normal(const Ref<StreamTexture> } singleton->make_flags[path].flags |= MAKE_NORMAL_FLAG; - - singleton->mutex->unlock(); } void ResourceImporterTexture::update_imports() { @@ -85,57 +82,56 @@ void ResourceImporterTexture::update_imports() { if (EditorFileSystem::get_singleton()->is_scanning() || EditorFileSystem::get_singleton()->is_importing()) { return; // do nothing for now } - mutex->lock(); - - if (make_flags.empty()) { - mutex->unlock(); - return; - } + MutexLock lock(mutex); Vector<String> to_reimport; - for (Map<StringName, MakeInfo>::Element *E = make_flags.front(); E; E = E->next()) { + { + if (make_flags.empty()) { + return; + } - Ref<ConfigFile> cf; - cf.instance(); - String src_path = String(E->key()) + ".import"; + for (Map<StringName, MakeInfo>::Element *E = make_flags.front(); E; E = E->next()) { - Error err = cf->load(src_path); - ERR_CONTINUE(err != OK); + Ref<ConfigFile> cf; + cf.instance(); + String src_path = String(E->key()) + ".import"; - bool changed = false; + Error err = cf->load(src_path); + ERR_CONTINUE(err != OK); - if (E->get().flags & MAKE_NORMAL_FLAG && int(cf->get_value("params", "compress/normal_map")) == 0) { - cf->set_value("params", "compress/normal_map", 1); - changed = true; - } + bool changed = false; - if (E->get().flags & MAKE_ROUGHNESS_FLAG && int(cf->get_value("params", "roughness/mode")) == 0) { - cf->set_value("params", "roughness/mode", E->get().channel_for_roughness + 2); - cf->set_value("params", "roughness/src_normal", E->get().normal_path_for_roughness); - changed = true; - } + if (E->get().flags & MAKE_NORMAL_FLAG && int(cf->get_value("params", "compress/normal_map")) == 0) { + cf->set_value("params", "compress/normal_map", 1); + changed = true; + } - if (E->get().flags & MAKE_3D_FLAG && bool(cf->get_value("params", "detect_3d/compress_to"))) { - int compress_to = cf->get_value("params", "detect_3d/compress_to"); - cf->set_value("params", "detect_3d/compress_to", 0); - if (compress_to == 1) { - cf->set_value("params", "compress/mode", COMPRESS_VRAM_COMPRESSED); - } else if (compress_to == 2) { - cf->set_value("params", "compress/mode", COMPRESS_BASIS_UNIVERSAL); + if (E->get().flags & MAKE_ROUGHNESS_FLAG && int(cf->get_value("params", "roughness/mode")) == 0) { + cf->set_value("params", "roughness/mode", E->get().channel_for_roughness + 2); + cf->set_value("params", "roughness/src_normal", E->get().normal_path_for_roughness); + changed = true; } - cf->set_value("params", "mipmaps/generate", true); - changed = true; - } - if (changed) { - cf->save(src_path); - to_reimport.push_back(E->key()); - } - } + if (E->get().flags & MAKE_3D_FLAG && bool(cf->get_value("params", "detect_3d/compress_to"))) { + int compress_to = cf->get_value("params", "detect_3d/compress_to"); + cf->set_value("params", "detect_3d/compress_to", 0); + if (compress_to == 1) { + cf->set_value("params", "compress/mode", COMPRESS_VRAM_COMPRESSED); + } else if (compress_to == 2) { + cf->set_value("params", "compress/mode", COMPRESS_BASIS_UNIVERSAL); + } + cf->set_value("params", "mipmaps/generate", true); + changed = true; + } - make_flags.clear(); + if (changed) { + cf->save(src_path); + to_reimport.push_back(E->key()); + } + } - mutex->unlock(); + make_flags.clear(); + } if (to_reimport.size()) { EditorFileSystem::get_singleton()->reimport_files(to_reimport); @@ -642,10 +638,7 @@ ResourceImporterTexture::ResourceImporterTexture() { StreamTexture::request_3d_callback = _texture_reimport_3d; StreamTexture::request_roughness_callback = _texture_reimport_roughness; StreamTexture::request_normal_callback = _texture_reimport_normal; - mutex = Mutex::create(); } ResourceImporterTexture::~ResourceImporterTexture() { - - memdelete(mutex); } diff --git a/editor/import/resource_importer_texture.h b/editor/import/resource_importer_texture.h index 19d5498b4a..ed0fe1be89 100644 --- a/editor/import/resource_importer_texture.h +++ b/editor/import/resource_importer_texture.h @@ -58,7 +58,7 @@ protected: MAKE_NORMAL_FLAG = 4 }; - Mutex *mutex; + Mutex mutex; struct MakeInfo { int flags; diff --git a/editor/plugins/mesh_instance_editor_plugin.cpp b/editor/plugins/mesh_instance_editor_plugin.cpp index 37cf16de58..c285bb4e1a 100644 --- a/editor/plugins/mesh_instance_editor_plugin.cpp +++ b/editor/plugins/mesh_instance_editor_plugin.cpp @@ -32,7 +32,7 @@ #include "editor/editor_scale.h" #include "scene/3d/collision_shape.h" -#include "scene/3d/navigation_mesh_instance.h" +#include "scene/3d/navigation_region.h" #include "scene/3d/physics_body.h" #include "scene/gui/box_container.h" #include "spatial_editor_plugin.h" @@ -233,7 +233,7 @@ void MeshInstanceEditor::_menu_option(int p_option) { return; nmesh->create_from_mesh(mesh); - NavigationMeshInstance *nmi = memnew(NavigationMeshInstance); + NavigationRegion *nmi = memnew(NavigationRegion); nmi->set_navigation_mesh(nmesh); Node *owner = node == get_tree()->get_edited_scene_root() ? node : node->get_owner(); diff --git a/editor/plugins/mesh_library_editor_plugin.cpp b/editor/plugins/mesh_library_editor_plugin.cpp index ea8842a56f..863ea451b5 100644 --- a/editor/plugins/mesh_library_editor_plugin.cpp +++ b/editor/plugins/mesh_library_editor_plugin.cpp @@ -34,7 +34,7 @@ #include "editor/editor_settings.h" #include "main/main.h" #include "scene/3d/mesh_instance.h" -#include "scene/3d/navigation_mesh_instance.h" +#include "scene/3d/navigation_region.h" #include "scene/3d/physics_body.h" #include "scene/main/viewport.h" #include "scene/resources/packed_scene.h" @@ -152,9 +152,9 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library, Transform navmesh_transform; for (int j = 0; j < mi->get_child_count(); j++) { Node *child2 = mi->get_child(j); - if (!Object::cast_to<NavigationMeshInstance>(child2)) + if (!Object::cast_to<NavigationRegion>(child2)) continue; - NavigationMeshInstance *sb = Object::cast_to<NavigationMeshInstance>(child2); + NavigationRegion *sb = Object::cast_to<NavigationRegion>(child2); navmesh = sb->get_navigation_mesh(); navmesh_transform = sb->get_transform(); if (!navmesh.is_null()) diff --git a/editor/plugins/navigation_polygon_editor_plugin.cpp b/editor/plugins/navigation_polygon_editor_plugin.cpp index c4e61f2488..6671d0b6b4 100644 --- a/editor/plugins/navigation_polygon_editor_plugin.cpp +++ b/editor/plugins/navigation_polygon_editor_plugin.cpp @@ -48,7 +48,7 @@ Node2D *NavigationPolygonEditor::_get_node() const { void NavigationPolygonEditor::_set_node(Node *p_polygon) { - node = Object::cast_to<NavigationPolygonInstance>(p_polygon); + node = Object::cast_to<NavigationRegion2D>(p_polygon); } int NavigationPolygonEditor::_get_polygon_count() const { @@ -127,5 +127,5 @@ NavigationPolygonEditor::NavigationPolygonEditor(EditorNode *p_editor) : } NavigationPolygonEditorPlugin::NavigationPolygonEditorPlugin(EditorNode *p_node) : - AbstractPolygon2DEditorPlugin(p_node, memnew(NavigationPolygonEditor(p_node)), "NavigationPolygonInstance") { + AbstractPolygon2DEditorPlugin(p_node, memnew(NavigationPolygonEditor(p_node)), "NavigationRegion2D") { } diff --git a/editor/plugins/navigation_polygon_editor_plugin.h b/editor/plugins/navigation_polygon_editor_plugin.h index 1cab336381..10f8cbc0a5 100644 --- a/editor/plugins/navigation_polygon_editor_plugin.h +++ b/editor/plugins/navigation_polygon_editor_plugin.h @@ -38,7 +38,7 @@ class NavigationPolygonEditor : public AbstractPolygon2DEditor { GDCLASS(NavigationPolygonEditor, AbstractPolygon2DEditor); - NavigationPolygonInstance *node; + NavigationRegion2D *node; Ref<NavigationPolygon> _ensure_navpoly() const; diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp index a61b291029..0d5741d84a 100644 --- a/editor/plugins/tile_set_editor_plugin.cpp +++ b/editor/plugins/tile_set_editor_plugin.cpp @@ -109,8 +109,8 @@ void TileSetEditor::_import_node(Node *p_node, Ref<TileSet> p_library) { Node *child2 = mi->get_child(j); - if (Object::cast_to<NavigationPolygonInstance>(child2)) - nav_poly = Object::cast_to<NavigationPolygonInstance>(child2)->get_navigation_polygon(); + if (Object::cast_to<NavigationRegion2D>(child2)) + nav_poly = Object::cast_to<NavigationRegion2D>(child2)->get_navigation_polygon(); if (Object::cast_to<LightOccluder2D>(child2)) occluder = Object::cast_to<LightOccluder2D>(child2)->get_occluder_polygon(); diff --git a/editor/spatial_editor_gizmos.cpp b/editor/spatial_editor_gizmos.cpp index 40e1be665c..c155430eae 100644 --- a/editor/spatial_editor_gizmos.cpp +++ b/editor/spatial_editor_gizmos.cpp @@ -41,7 +41,7 @@ #include "scene/3d/light.h" #include "scene/3d/listener.h" #include "scene/3d/mesh_instance.h" -#include "scene/3d/navigation_mesh_instance.h" +#include "scene/3d/navigation_region.h" #include "scene/3d/particles.h" #include "scene/3d/physics_joint.h" #include "scene/3d/position_3d.h" @@ -58,11 +58,11 @@ #include "scene/resources/convex_polygon_shape.h" #include "scene/resources/cylinder_shape.h" #include "scene/resources/height_map_shape.h" -#include "scene/resources/plane_shape.h" #include "scene/resources/primitive_meshes.h" #include "scene/resources/ray_shape.h" #include "scene/resources/sphere_shape.h" #include "scene/resources/surface_tool.h" +#include "scene/resources/world_margin_shape.h" #define HANDLE_HALF_SIZE 9.5 @@ -3575,9 +3575,9 @@ void CollisionShapeSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { p_gizmo->add_handles(handles, handles_material); } - if (Object::cast_to<PlaneShape>(*s)) { + if (Object::cast_to<WorldMarginShape>(*s)) { - Ref<PlaneShape> ps = s; + Ref<WorldMarginShape> ps = s; Plane p = ps->get_plane(); Vector<Vector3> points; @@ -3720,11 +3720,11 @@ NavigationMeshSpatialGizmoPlugin::NavigationMeshSpatialGizmoPlugin() { } bool NavigationMeshSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) { - return Object::cast_to<NavigationMeshInstance>(p_spatial) != NULL; + return Object::cast_to<NavigationRegion>(p_spatial) != NULL; } String NavigationMeshSpatialGizmoPlugin::get_name() const { - return "NavigationMeshInstance"; + return "NavigationRegion"; } int NavigationMeshSpatialGizmoPlugin::get_priority() const { @@ -3733,7 +3733,7 @@ int NavigationMeshSpatialGizmoPlugin::get_priority() const { void NavigationMeshSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { - NavigationMeshInstance *navmesh = Object::cast_to<NavigationMeshInstance>(p_gizmo->get_spatial_node()); + NavigationRegion *navmesh = Object::cast_to<NavigationRegion>(p_gizmo->get_spatial_node()); Ref<Material> edge_material = get_material("navigation_edge_material", p_gizmo); Ref<Material> edge_material_disabled = get_material("navigation_edge_material_disabled", p_gizmo); diff --git a/main/tests/test_physics.cpp b/main/tests/test_physics.cpp index 43958a9493..0304e8f6dd 100644 --- a/main/tests/test_physics.cpp +++ b/main/tests/test_physics.cpp @@ -110,13 +110,13 @@ protected: PhysicsServer *ps = PhysicsServer::get_singleton(); - RID plane_shape = ps->shape_create(PhysicsServer::SHAPE_PLANE); - ps->shape_set_data(plane_shape, p_plane); + RID world_margin_shape = ps->shape_create(PhysicsServer::SHAPE_PLANE); + ps->shape_set_data(world_margin_shape, p_plane); RID b = ps->body_create(PhysicsServer::BODY_MODE_STATIC); ps->body_set_space(b, space); //todo set space - ps->body_add_shape(b, plane_shape); + ps->body_add_shape(b, world_margin_shape); return b; } diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp index 8240ae2f83..0ec6ad71d9 100644 --- a/modules/gdnative/nativescript/nativescript.cpp +++ b/modules/gdnative/nativescript/nativescript.cpp @@ -222,15 +222,11 @@ ScriptInstance *NativeScript::instance_create(Object *p_this) { nsi->userdata = script_data->create_func.create_func((godot_object *)p_this, script_data->create_func.method_data); #endif -#ifndef NO_THREADS - owners_lock->lock(); -#endif - - instance_owners.insert(p_this); + { + MutexLock lock(owners_lock); -#ifndef NO_THREADS - owners_lock->unlock(); -#endif + instance_owners.insert(p_this); + } return nsi; } @@ -782,17 +778,10 @@ NativeScript::NativeScript() { library = Ref<GDNative>(); lib_path = ""; class_name = ""; -#ifndef NO_THREADS - owners_lock = Mutex::create(); -#endif } NativeScript::~NativeScript() { NSL->unregister_script(this); - -#ifndef NO_THREADS - memdelete(owners_lock); -#endif } #define GET_SCRIPT_DESC() script->get_script_desc() @@ -1140,16 +1129,9 @@ NativeScriptInstance::~NativeScriptInstance() { script_data->destroy_func.destroy_func((godot_object *)owner, script_data->destroy_func.method_data, userdata); if (owner) { - -#ifndef NO_THREADS - script->owners_lock->lock(); -#endif + MutexLock lock(script->owners_lock); script->instance_owners.erase(owner); - -#ifndef NO_THREADS - script->owners_lock->unlock(); -#endif } } @@ -1246,7 +1228,6 @@ NativeScriptLanguage::NativeScriptLanguage() { NativeScriptLanguage::singleton = this; #ifndef NO_THREADS has_objects_to_register = false; - mutex = Mutex::create(); #endif #ifdef DEBUG_ENABLED @@ -1283,10 +1264,6 @@ NativeScriptLanguage::~NativeScriptLanguage() { NSL->library_classes.clear(); NSL->library_gdnatives.clear(); NSL->library_script_users.clear(); - -#ifndef NO_THREADS - memdelete(mutex); -#endif } String NativeScriptLanguage::get_name() const { @@ -1413,9 +1390,7 @@ void NativeScriptLanguage::get_public_constants(List<Pair<String, Variant> > *p_ void NativeScriptLanguage::profiling_start() { #ifdef DEBUG_ENABLED -#ifndef NO_THREADS MutexLock lock(mutex); -#endif profile_data.clear(); profiling = true; @@ -1424,9 +1399,7 @@ void NativeScriptLanguage::profiling_start() { void NativeScriptLanguage::profiling_stop() { #ifdef DEBUG_ENABLED -#ifndef NO_THREADS MutexLock lock(mutex); -#endif profiling = false; #endif @@ -1434,9 +1407,8 @@ void NativeScriptLanguage::profiling_stop() { int NativeScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) { #ifdef DEBUG_ENABLED -#ifndef NO_THREADS MutexLock lock(mutex); -#endif + int current = 0; for (Map<StringName, ProfileData>::Element *d = profile_data.front(); d; d = d->next()) { @@ -1458,9 +1430,8 @@ int NativeScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_a int NativeScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max) { #ifdef DEBUG_ENABLED -#ifndef NO_THREADS MutexLock lock(mutex); -#endif + int current = 0; for (Map<StringName, ProfileData>::Element *d = profile_data.front(); d; d = d->next()) { @@ -1484,9 +1455,7 @@ int NativeScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, in void NativeScriptLanguage::profiling_add_data(StringName p_signature, uint64_t p_time) { #ifdef DEBUG_ENABLED -#ifndef NO_THREADS MutexLock lock(mutex); -#endif Map<StringName, ProfileData>::Element *d = profile_data.find(p_signature); if (d) { @@ -1705,9 +1674,8 @@ void NativeScriptLanguage::defer_init_library(Ref<GDNativeLibrary> lib, NativeSc #endif void NativeScriptLanguage::init_library(const Ref<GDNativeLibrary> &lib) { -#ifndef NO_THREADS MutexLock lock(mutex); -#endif + // See if this library was "registered" already. const String &lib_path = lib->get_current_library_path(); ERR_FAIL_COND_MSG(lib_path.length() == 0, lib->get_name() + " does not have a library for the current platform."); @@ -1743,16 +1711,14 @@ void NativeScriptLanguage::init_library(const Ref<GDNativeLibrary> &lib) { } void NativeScriptLanguage::register_script(NativeScript *script) { -#ifndef NO_THREADS MutexLock lock(mutex); -#endif + library_script_users[script->lib_path].insert(script); } void NativeScriptLanguage::unregister_script(NativeScript *script) { -#ifndef NO_THREADS MutexLock lock(mutex); -#endif + Map<String, Set<NativeScript *> >::Element *S = library_script_users.find(script->lib_path); if (S) { S->get().erase(script); @@ -1803,9 +1769,7 @@ void NativeScriptLanguage::frame() { #ifdef DEBUG_ENABLED { -#ifndef NO_THREADS MutexLock lock(mutex); -#endif for (Map<StringName, ProfileData>::Element *d = profile_data.front(); d; d = d->next()) { d->get().last_frame_call_count = d->get().frame_call_count; @@ -1867,9 +1831,7 @@ void NativeReloadNode::_notification(int p_what) { if (unloaded) break; -#ifndef NO_THREADS MutexLock lock(NSL->mutex); -#endif NSL->_unload_stuff(true); for (Map<String, Ref<GDNative> >::Element *L = NSL->library_gdnatives.front(); L; L = L->next()) { @@ -1904,9 +1866,8 @@ void NativeReloadNode::_notification(int p_what) { if (!unloaded) break; -#ifndef NO_THREADS MutexLock lock(NSL->mutex); -#endif + Set<StringName> libs_to_remove; for (Map<String, Ref<GDNative> >::Element *L = NSL->library_gdnatives.front(); L; L = L->next()) { diff --git a/modules/gdnative/nativescript/nativescript.h b/modules/gdnative/nativescript/nativescript.h index 609ffa2bd4..04670b952b 100644 --- a/modules/gdnative/nativescript/nativescript.h +++ b/modules/gdnative/nativescript/nativescript.h @@ -35,6 +35,7 @@ #include "core/io/resource_saver.h" #include "core/oa_hash_map.h" #include "core/ordered_hash_map.h" +#include "core/os/mutex.h" #include "core/os/thread_safe.h" #include "core/resource.h" #include "core/script_language.h" @@ -44,10 +45,6 @@ #include "modules/gdnative/gdnative.h" #include <nativescript/godot_nativescript.h> -#ifndef NO_THREADS -#include "core/os/mutex.h" -#endif - struct NativeScriptDesc { struct Method { @@ -127,9 +124,7 @@ class NativeScript : public Script { String script_class_name; String script_class_icon_path; -#ifndef NO_THREADS - Mutex *owners_lock; -#endif + Mutex owners_lock; Set<Object *> instance_owners; protected: @@ -266,9 +261,8 @@ private: void _unload_stuff(bool p_reload = false); + Mutex mutex; #ifndef NO_THREADS - Mutex *mutex; - Set<Ref<GDNativeLibrary> > libs_to_init; Set<NativeScript *> scripts_to_register; volatile bool has_objects_to_register; // so that we don't lock mutex every frame - it's rarely needed diff --git a/modules/gdnative/pluginscript/pluginscript_language.cpp b/modules/gdnative/pluginscript/pluginscript_language.cpp index 4e39f4b0a8..a40b59bb2e 100644 --- a/modules/gdnative/pluginscript/pluginscript_language.cpp +++ b/modules/gdnative/pluginscript/pluginscript_language.cpp @@ -399,39 +399,18 @@ void PluginScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool } void PluginScriptLanguage::lock() { -#ifndef NO_THREADS - if (_lock) { - _lock->lock(); - } -#endif + _lock.lock(); } void PluginScriptLanguage::unlock() { -#ifndef NO_THREADS - if (_lock) { - _lock->unlock(); - } -#endif + _lock.unlock(); } PluginScriptLanguage::PluginScriptLanguage(const godot_pluginscript_language_desc *desc) : _desc(*desc) { _resource_loader = Ref<ResourceFormatLoaderPluginScript>(memnew(ResourceFormatLoaderPluginScript(this))); _resource_saver = Ref<ResourceFormatSaverPluginScript>(memnew(ResourceFormatSaverPluginScript(this))); - -// TODO: totally remove _lock attribute if NO_THREADS is set -#ifdef NO_THREADS - _lock = NULL; -#else - _lock = Mutex::create(); -#endif } PluginScriptLanguage::~PluginScriptLanguage() { -#ifndef NO_THREADS - if (_lock) { - memdelete(_lock); - _lock = NULL; - } -#endif } diff --git a/modules/gdnative/pluginscript/pluginscript_language.h b/modules/gdnative/pluginscript/pluginscript_language.h index 037d7a4948..3f0d2b8d3d 100644 --- a/modules/gdnative/pluginscript/pluginscript_language.h +++ b/modules/gdnative/pluginscript/pluginscript_language.h @@ -53,7 +53,7 @@ class PluginScriptLanguage : public ScriptLanguage { const godot_pluginscript_language_desc _desc; godot_pluginscript_language_data *_data; - Mutex *_lock; + Mutex _lock; SelfList<PluginScript>::List _script_list; public: diff --git a/modules/gdnavigation/gd_navigation_server.cpp b/modules/gdnavigation/gd_navigation_server.cpp index 4129d1f65a..4db10cda78 100644 --- a/modules/gdnavigation/gd_navigation_server.cpp +++ b/modules/gdnavigation/gd_navigation_server.cpp @@ -115,31 +115,27 @@ GdNavigationServer::GdNavigationServer() : NavigationServer(), - commands_mutex(Mutex::create()), - operations_mutex(Mutex::create()), active(true) { } GdNavigationServer::~GdNavigationServer() { flush_queries(); - memdelete(operations_mutex); - memdelete(commands_mutex); } void GdNavigationServer::add_command(SetCommand *command) const { auto mut_this = const_cast<GdNavigationServer *>(this); - commands_mutex->lock(); - mut_this->commands.push_back(command); - commands_mutex->unlock(); + { + MutexLock lock(commands_mutex); + mut_this->commands.push_back(command); + } } RID GdNavigationServer::map_create() const { auto mut_this = const_cast<GdNavigationServer *>(this); - mut_this->operations_mutex->lock(); + MutexLock lock(mut_this->operations_mutex); NavMap *space = memnew(NavMap); RID rid = map_owner.make_rid(space); space->set_self(rid); - mut_this->operations_mutex->unlock(); return rid; } @@ -242,11 +238,10 @@ RID GdNavigationServer::map_get_closest_point_owner(RID p_map, const Vector3 &p_ RID GdNavigationServer::region_create() const { auto mut_this = const_cast<GdNavigationServer *>(this); - mut_this->operations_mutex->lock(); + MutexLock lock(mut_this->operations_mutex); NavRegion *reg = memnew(NavRegion); RID rid = region_owner.make_rid(reg); reg->set_self(rid); - mut_this->operations_mutex->unlock(); return rid; } @@ -298,11 +293,10 @@ void GdNavigationServer::region_bake_navmesh(Ref<NavigationMesh> r_mesh, Node *p RID GdNavigationServer::agent_create() const { auto mut_this = const_cast<GdNavigationServer *>(this); - mut_this->operations_mutex->lock(); + MutexLock lock(mut_this->operations_mutex); RvoAgent *agent = memnew(RvoAgent()); RID rid = agent_owner.make_rid(agent); agent->set_self(rid); - mut_this->operations_mutex->unlock(); return rid; } @@ -470,23 +464,20 @@ COMMAND_1(free, RID, p_object) { void GdNavigationServer::set_active(bool p_active) const { auto mut_this = const_cast<GdNavigationServer *>(this); - mut_this->operations_mutex->lock(); + MutexLock lock(mut_this->operations_mutex); mut_this->active = p_active; - mut_this->operations_mutex->unlock(); } void GdNavigationServer::flush_queries() { // In c++ we can't be sure that this is performed in the main thread // even with mutable functions. - commands_mutex->lock(); - operations_mutex->lock(); + MutexLock lock(commands_mutex); + MutexLock lock2(operations_mutex); for (size_t i(0); i < commands.size(); i++) { commands[i]->exec(this); memdelete(commands[i]); } commands.clear(); - operations_mutex->unlock(); - commands_mutex->unlock(); } void GdNavigationServer::process(real_t p_delta_time) { @@ -498,13 +489,12 @@ void GdNavigationServer::process(real_t p_delta_time) { // In c++ we can't be sure that this is performed in the main thread // even with mutable functions. - operations_mutex->lock(); + MutexLock lock(operations_mutex); for (int i(0); i < active_maps.size(); i++) { active_maps[i]->sync(); active_maps[i]->step(p_delta_time); active_maps[i]->dispatch_callbacks(); } - operations_mutex->unlock(); } #undef COMMAND_1 diff --git a/modules/gdnavigation/gd_navigation_server.h b/modules/gdnavigation/gd_navigation_server.h index 0400acf1a3..e9f5c1ffe6 100644 --- a/modules/gdnavigation/gd_navigation_server.h +++ b/modules/gdnavigation/gd_navigation_server.h @@ -61,7 +61,6 @@ void MERGE(_cmd_, F_NAME)(T_0 D_0, T_1 D_1, T_2 D_2, T_3 D_3) class GdNavigationServer; -class Mutex; struct SetCommand { virtual ~SetCommand() {} @@ -69,9 +68,9 @@ struct SetCommand { }; class GdNavigationServer : public NavigationServer { - Mutex *commands_mutex; + Mutex commands_mutex; /// Mutex used to make any operation threadsafe. - Mutex *operations_mutex; + Mutex operations_mutex; std::vector<SetCommand *> commands; diff --git a/modules/gdnavigation/navigation_mesh_editor_plugin.cpp b/modules/gdnavigation/navigation_mesh_editor_plugin.cpp index 28fe0bfd06..4ab90ac7eb 100644 --- a/modules/gdnavigation/navigation_mesh_editor_plugin.cpp +++ b/modules/gdnavigation/navigation_mesh_editor_plugin.cpp @@ -84,7 +84,7 @@ void NavigationMeshEditor::_clear_pressed() { } } -void NavigationMeshEditor::edit(NavigationMeshInstance *p_nav_mesh_instance) { +void NavigationMeshEditor::edit(NavigationRegion *p_nav_mesh_instance) { if (p_nav_mesh_instance == NULL || node == p_nav_mesh_instance) { return; @@ -128,12 +128,12 @@ NavigationMeshEditor::~NavigationMeshEditor() { void NavigationMeshEditorPlugin::edit(Object *p_object) { - navigation_mesh_editor->edit(Object::cast_to<NavigationMeshInstance>(p_object)); + navigation_mesh_editor->edit(Object::cast_to<NavigationRegion>(p_object)); } bool NavigationMeshEditorPlugin::handles(Object *p_object) const { - return p_object->is_class("NavigationMeshInstance"); + return p_object->is_class("NavigationRegion"); } void NavigationMeshEditorPlugin::make_visible(bool p_visible) { diff --git a/modules/gdnavigation/navigation_mesh_editor_plugin.h b/modules/gdnavigation/navigation_mesh_editor_plugin.h index f5833f3d7f..7c3faebf57 100644 --- a/modules/gdnavigation/navigation_mesh_editor_plugin.h +++ b/modules/gdnavigation/navigation_mesh_editor_plugin.h @@ -36,7 +36,7 @@ #include "editor/editor_node.h" #include "editor/editor_plugin.h" -class NavigationMeshInstance; +class NavigationRegion; class NavigationMeshEditor : public Control { friend class NavigationMeshEditorPlugin; @@ -50,7 +50,7 @@ class NavigationMeshEditor : public Control { ToolButton *button_reset; Label *bake_info; - NavigationMeshInstance *node; + NavigationRegion *node; void _bake_pressed(); void _clear_pressed(); @@ -61,7 +61,7 @@ protected: void _notification(int p_option); public: - void edit(NavigationMeshInstance *p_nav_mesh_instance); + void edit(NavigationRegion *p_nav_mesh_instance); NavigationMeshEditor(); ~NavigationMeshEditor(); }; diff --git a/modules/gdnavigation/navigation_mesh_generator.cpp b/modules/gdnavigation/navigation_mesh_generator.cpp index 7f8761dac8..e7038b38a2 100644 --- a/modules/gdnavigation/navigation_mesh_generator.cpp +++ b/modules/gdnavigation/navigation_mesh_generator.cpp @@ -42,10 +42,10 @@ #include "scene/resources/concave_polygon_shape.h" #include "scene/resources/convex_polygon_shape.h" #include "scene/resources/cylinder_shape.h" -#include "scene/resources/plane_shape.h" #include "scene/resources/primitive_meshes.h" #include "scene/resources/shape.h" #include "scene/resources/sphere_shape.h" +#include "scene/resources/world_margin_shape.h" #include "modules/modules_enabled.gen.h" #ifdef TOOLS_ENABLED diff --git a/modules/gdnavigation/navigation_mesh_generator.h b/modules/gdnavigation/navigation_mesh_generator.h index 27a56e1d7a..d1f2e4b56f 100644 --- a/modules/gdnavigation/navigation_mesh_generator.h +++ b/modules/gdnavigation/navigation_mesh_generator.h @@ -33,7 +33,7 @@ #ifndef _3D_DISABLED -#include "scene/3d/navigation_mesh_instance.h" +#include "scene/3d/navigation_region.h" #include <Recast.h> diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml index cf76c09294..2f6f9f30a4 100644 --- a/modules/gdscript/doc_classes/@GDScript.xml +++ b/modules/gdscript/doc_classes/@GDScript.xml @@ -481,9 +481,13 @@ <argument index="2" name="weight" type="float"> </argument> <description> - Returns a normalized value considering the given range. + Returns a normalized value considering the given range. This is the opposite of [method lerp]. [codeblock] - inverse_lerp(3, 5, 4) # Returns 0.5 + var middle = lerp(20, 30, 0.75) + # `middle` is now 27.5. + # Now, we pretend to have forgotten the original ratio and want to get it back. + var ratio = inverse_lerp(20, 30, 27.5) + # `ratio` is now 0.75. [/codeblock] </description> </method> @@ -558,7 +562,7 @@ <argument index="2" name="weight" type="float"> </argument> <description> - Linearly interpolates between two values by a normalized value. + Linearly interpolates between two values by a normalized value. This is the opposite of [method inverse_lerp]. If the [code]from[/code] and [code]to[/code] arguments are of type [int] or [float], the return value is a [float]. If both are of the same vector type ([Vector2], [Vector3] or [Color]), the return value will be of the same type ([code]lerp[/code] then calls the vector type's [code]linear_interpolate[/code] method). [codeblock] @@ -578,7 +582,7 @@ </argument> <description> Linearly interpolates between two angles (in radians) by a normalized value. - Similar to [method lerp] but interpolate correctly when the angles wrap around [constant @GDScript.TAU]. + Similar to [method lerp], but interpolates correctly when the angles wrap around [constant @GDScript.TAU]. [codeblock] extends Sprite var elapsed = 0.0 @@ -596,7 +600,13 @@ <argument index="0" name="nrg" type="float"> </argument> <description> - Converts from linear energy to decibels (audio). + Converts from linear energy to decibels (audio). This can be used to implement volume sliders that behave as expected (since volume isn't linear). Example: + [codeblock] + # "Slider" refers to a node that inherits Range such as HSlider or VSlider. + # Its range must be configured to go from 0 to 1. + # Change the bus name if you'd like to change the volume of a specific bus only. + AudioServer.set_bus_volume_db(AudioServer.get_bus_index("Master"), linear2db($Slider.value)) + [/codeblock] </description> </method> <method name="load"> diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index a72bb7ba49..6a4bf801f3 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -104,28 +104,21 @@ GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argco /* STEP 2, INITIALIZE AND CONSTRUCT */ -#ifndef NO_THREADS - GDScriptLanguage::singleton->lock->lock(); -#endif - - instances.insert(instance->owner); + { + MutexLock lock(GDScriptLanguage::singleton->lock); -#ifndef NO_THREADS - GDScriptLanguage::singleton->lock->unlock(); -#endif + instances.insert(instance->owner); + } initializer->call(instance, p_args, p_argcount, r_error); if (r_error.error != Callable::CallError::CALL_OK) { instance->script = Ref<GDScript>(); instance->owner->set_script_instance(NULL); -#ifndef NO_THREADS - GDScriptLanguage::singleton->lock->lock(); -#endif - instances.erase(p_owner); -#ifndef NO_THREADS - GDScriptLanguage::singleton->lock->unlock(); -#endif + { + MutexLock lock(GDScriptLanguage::singleton->lock); + instances.erase(p_owner); + } ERR_FAIL_COND_V(r_error.error != Callable::CallError::CALL_OK, NULL); //error constructing } @@ -346,16 +339,9 @@ PlaceHolderScriptInstance *GDScript::placeholder_instance_create(Object *p_this) bool GDScript::instance_has(const Object *p_this) const { -#ifndef NO_THREADS - GDScriptLanguage::singleton->lock->lock(); -#endif - bool hasit = instances.has((Object *)p_this); - -#ifndef NO_THREADS - GDScriptLanguage::singleton->lock->unlock(); -#endif + MutexLock lock(GDScriptLanguage::singleton->lock); - return hasit; + return instances.has((Object *)p_this); } bool GDScript::has_source_code() const { @@ -544,14 +530,12 @@ void GDScript::_set_subclass_path(Ref<GDScript> &p_sc, const String &p_path) { Error GDScript::reload(bool p_keep_state) { -#ifndef NO_THREADS - GDScriptLanguage::singleton->lock->lock(); -#endif - bool has_instances = instances.size(); + bool has_instances; + { + MutexLock lock(GDScriptLanguage::singleton->lock); -#ifndef NO_THREADS - GDScriptLanguage::singleton->lock->unlock(); -#endif + has_instances = instances.size(); + } ERR_FAIL_COND_V(!p_keep_state && has_instances, ERR_ALREADY_IN_USE); @@ -1007,13 +991,10 @@ GDScript::GDScript() : #endif #ifdef DEBUG_ENABLED - if (GDScriptLanguage::get_singleton()->lock) { - GDScriptLanguage::get_singleton()->lock->lock(); - } - GDScriptLanguage::get_singleton()->script_list.add(&script_list); + { + MutexLock lock(GDScriptLanguage::get_singleton()->lock); - if (GDScriptLanguage::get_singleton()->lock) { - GDScriptLanguage::get_singleton()->lock->unlock(); + GDScriptLanguage::get_singleton()->script_list.add(&script_list); } #endif } @@ -1057,13 +1038,10 @@ GDScript::~GDScript() { _save_orphaned_subclasses(); #ifdef DEBUG_ENABLED - if (GDScriptLanguage::get_singleton()->lock) { - GDScriptLanguage::get_singleton()->lock->lock(); - } - GDScriptLanguage::get_singleton()->script_list.remove(&script_list); + { + MutexLock lock(GDScriptLanguage::get_singleton()->lock); - if (GDScriptLanguage::get_singleton()->lock) { - GDScriptLanguage::get_singleton()->lock->unlock(); + GDScriptLanguage::get_singleton()->script_list.remove(&script_list); } #endif } @@ -1472,14 +1450,9 @@ GDScriptInstance::GDScriptInstance() { GDScriptInstance::~GDScriptInstance() { if (script.is_valid() && owner) { -#ifndef NO_THREADS - GDScriptLanguage::singleton->lock->lock(); -#endif + MutexLock lock(GDScriptLanguage::singleton->lock); script->instances.erase(owner); -#ifndef NO_THREADS - GDScriptLanguage::singleton->lock->unlock(); -#endif } } @@ -1580,9 +1553,7 @@ void GDScriptLanguage::finish() { void GDScriptLanguage::profiling_start() { #ifdef DEBUG_ENABLED - if (lock) { - lock->lock(); - } + MutexLock lock(this->lock); SelfList<GDScriptFunction> *elem = function_list.first(); while (elem) { @@ -1599,25 +1570,15 @@ void GDScriptLanguage::profiling_start() { } profiling = true; - if (lock) { - lock->unlock(); - } - #endif } void GDScriptLanguage::profiling_stop() { #ifdef DEBUG_ENABLED - if (lock) { - lock->lock(); - } + MutexLock lock(this->lock); profiling = false; - if (lock) { - lock->unlock(); - } - #endif } @@ -1625,9 +1586,8 @@ int GDScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int current = 0; #ifdef DEBUG_ENABLED - if (lock) { - lock->lock(); - } + + MutexLock lock(this->lock); SelfList<GDScriptFunction> *elem = function_list.first(); while (elem) { @@ -1640,11 +1600,6 @@ int GDScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr, elem = elem->next(); current++; } - - if (lock) { - lock->unlock(); - } - #endif return current; @@ -1655,9 +1610,7 @@ int GDScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_ int current = 0; #ifdef DEBUG_ENABLED - if (lock) { - lock->lock(); - } + MutexLock lock(this->lock); SelfList<GDScriptFunction> *elem = function_list.first(); while (elem) { @@ -1672,11 +1625,6 @@ int GDScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_ } elem = elem->next(); } - - if (lock) { - lock->unlock(); - } - #endif return current; @@ -1707,23 +1655,18 @@ void GDScriptLanguage::reload_all_scripts() { #ifdef DEBUG_ENABLED print_verbose("GDScript: Reloading all scripts"); - if (lock) { - lock->lock(); - } - List<Ref<GDScript> > scripts; + { + MutexLock lock(this->lock); - SelfList<GDScript> *elem = script_list.first(); - while (elem) { - if (elem->self()->get_path().is_resource_file()) { - print_verbose("GDScript: Found: " + elem->self()->get_path()); - scripts.push_back(Ref<GDScript>(elem->self())); //cast to gdscript to avoid being erased by accident + SelfList<GDScript> *elem = script_list.first(); + while (elem) { + if (elem->self()->get_path().is_resource_file()) { + print_verbose("GDScript: Found: " + elem->self()->get_path()); + scripts.push_back(Ref<GDScript>(elem->self())); //cast to gdscript to avoid being erased by accident + } + elem = elem->next(); } - elem = elem->next(); - } - - if (lock) { - lock->unlock(); } //as scripts are going to be reloaded, must proceed without locking here @@ -1743,23 +1686,18 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so #ifdef DEBUG_ENABLED - if (lock) { - lock->lock(); - } - List<Ref<GDScript> > scripts; + { + MutexLock lock(this->lock); - SelfList<GDScript> *elem = script_list.first(); - while (elem) { - if (elem->self()->get_path().is_resource_file()) { + SelfList<GDScript> *elem = script_list.first(); + while (elem) { + if (elem->self()->get_path().is_resource_file()) { - scripts.push_back(Ref<GDScript>(elem->self())); //cast to gdscript to avoid being erased by accident + scripts.push_back(Ref<GDScript>(elem->self())); //cast to gdscript to avoid being erased by accident + } + elem = elem->next(); } - elem = elem->next(); - } - - if (lock) { - lock->unlock(); } //when someone asks you why dynamically typed languages are easier to write.... @@ -1879,9 +1817,7 @@ void GDScriptLanguage::frame() { #ifdef DEBUG_ENABLED if (profiling) { - if (lock) { - lock->lock(); - } + MutexLock lock(this->lock); SelfList<GDScriptFunction> *elem = function_list.first(); while (elem) { @@ -1893,10 +1829,6 @@ void GDScriptLanguage::frame() { elem->self()->profile.frame_total_time = 0; elem = elem->next(); } - - if (lock) { - lock->unlock(); - } } #endif @@ -2262,11 +2194,6 @@ GDScriptLanguage::GDScriptLanguage() { _debug_parse_err_line = -1; _debug_parse_err_file = ""; -#ifdef NO_THREADS - lock = NULL; -#else - lock = Mutex::create(); -#endif profiling = false; script_frame_time = 0; @@ -2300,10 +2227,6 @@ GDScriptLanguage::GDScriptLanguage() { GDScriptLanguage::~GDScriptLanguage() { - if (lock) { - memdelete(lock); - lock = NULL; - } if (_call_stack) { memdelete_arr(_call_stack); } diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index 6598a0023b..6b53acd064 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -369,7 +369,7 @@ class GDScriptLanguage : public ScriptLanguage { friend class GDScriptInstance; - Mutex *lock; + Mutex lock; friend class GDScript; diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp index 27857ea91f..79c550c81c 100644 --- a/modules/gdscript/gdscript_function.cpp +++ b/modules/gdscript/gdscript_function.cpp @@ -1769,13 +1769,10 @@ GDScriptFunction::GDScriptFunction() : #ifdef DEBUG_ENABLED _func_cname = NULL; - if (GDScriptLanguage::get_singleton()->lock) { - GDScriptLanguage::get_singleton()->lock->lock(); - } - GDScriptLanguage::get_singleton()->function_list.add(&function_list); + { + MutexLock lock(GDScriptLanguage::get_singleton()->lock); - if (GDScriptLanguage::get_singleton()->lock) { - GDScriptLanguage::get_singleton()->lock->unlock(); + GDScriptLanguage::get_singleton()->function_list.add(&function_list); } profile.call_count = 0; @@ -1793,14 +1790,10 @@ GDScriptFunction::GDScriptFunction() : GDScriptFunction::~GDScriptFunction() { #ifdef DEBUG_ENABLED - if (GDScriptLanguage::get_singleton()->lock) { - GDScriptLanguage::get_singleton()->lock->lock(); - } - GDScriptLanguage::get_singleton()->function_list.remove(&function_list); - if (GDScriptLanguage::get_singleton()->lock) { - GDScriptLanguage::get_singleton()->lock->unlock(); - } + MutexLock lock(GDScriptLanguage::get_singleton()->lock); + + GDScriptLanguage::get_singleton()->function_list.remove(&function_list); #endif } diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 5c1c098e3e..404d2eb022 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -35,6 +35,7 @@ #include "core/io/json.h" #include "core/os/file_access.h" +#include "core/os/mutex.h" #include "core/os/os.h" #include "core/os/thread.h" #include "core/project_settings.h" @@ -58,7 +59,6 @@ #include "mono_gd/gd_mono_utils.h" #include "signal_awaiter_utils.h" #include "utils/macros.h" -#include "utils/mutex_utils.h" #include "utils/string_utils.h" #include "utils/thread_local.h" @@ -633,7 +633,7 @@ Vector<ScriptLanguage::StackInfo> CSharpLanguage::stack_trace_get_info(MonoObjec void CSharpLanguage::post_unsafe_reference(Object *p_obj) { #ifdef DEBUG_ENABLED - SCOPED_MUTEX_LOCK(unsafe_object_references_lock); + MutexLock lock(unsafe_object_references_lock); ObjectID id = p_obj->get_instance_id(); unsafe_object_references[id]++; #endif @@ -641,7 +641,7 @@ void CSharpLanguage::post_unsafe_reference(Object *p_obj) { void CSharpLanguage::pre_unsafe_unreference(Object *p_obj) { #ifdef DEBUG_ENABLED - SCOPED_MUTEX_LOCK(unsafe_object_references_lock); + MutexLock lock(unsafe_object_references_lock); ObjectID id = p_obj->get_instance_id(); Map<ObjectID, int>::Element *elem = unsafe_object_references.find(id); ERR_FAIL_NULL(elem); @@ -764,7 +764,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { List<Ref<CSharpScript> > scripts; { - SCOPED_MUTEX_LOCK(script_instances_mutex); + MutexLock lock(script_instances_mutex); for (SelfList<CSharpScript> *elem = script_list.first(); elem; elem = elem->next()) { // Cast to CSharpScript to avoid being erased by accident @@ -1204,7 +1204,7 @@ void CSharpLanguage::set_language_index(int p_idx) { void CSharpLanguage::release_script_gchandle(Ref<MonoGCHandle> &p_gchandle) { if (!p_gchandle->is_released()) { // Do not lock unnecessarily - SCOPED_MUTEX_LOCK(get_singleton()->script_gchandle_release_mutex); + MutexLock lock(get_singleton()->script_gchandle_release_mutex); p_gchandle->release(); } } @@ -1214,7 +1214,7 @@ void CSharpLanguage::release_script_gchandle(MonoObject *p_expected_obj, Ref<Mon uint32_t pinned_gchandle = MonoGCHandle::new_strong_handle_pinned(p_expected_obj); // We might lock after this, so pin it if (!p_gchandle->is_released()) { // Do not lock unnecessarily - SCOPED_MUTEX_LOCK(get_singleton()->script_gchandle_release_mutex); + MutexLock lock(get_singleton()->script_gchandle_release_mutex); MonoObject *target = p_gchandle->get_target(); @@ -1239,24 +1239,6 @@ CSharpLanguage::CSharpLanguage() { gdmono = NULL; -#ifdef NO_THREADS - script_instances_mutex = NULL; - script_gchandle_release_mutex = NULL; - language_bind_mutex = NULL; -#else - script_instances_mutex = Mutex::create(); - script_gchandle_release_mutex = Mutex::create(); - language_bind_mutex = Mutex::create(); -#endif - -#ifdef DEBUG_ENABLED -#ifdef NO_THREADS - unsafe_object_references_lock = NULL; -#else - unsafe_object_references_lock = Mutex::create(); -#endif -#endif - lang_idx = -1; scripts_metadata_invalidated = true; @@ -1269,29 +1251,6 @@ CSharpLanguage::CSharpLanguage() { CSharpLanguage::~CSharpLanguage() { finish(); - - if (script_instances_mutex) { - memdelete(script_instances_mutex); - script_instances_mutex = NULL; - } - - if (language_bind_mutex) { - memdelete(language_bind_mutex); - language_bind_mutex = NULL; - } - - if (script_gchandle_release_mutex) { - memdelete(script_gchandle_release_mutex); - script_gchandle_release_mutex = NULL; - } - -#ifdef DEBUG_ENABLED - if (unsafe_object_references_lock) { - memdelete(unsafe_object_references_lock); - unsafe_object_references_lock = NULL; - } -#endif - singleton = NULL; } @@ -1346,7 +1305,7 @@ bool CSharpLanguage::setup_csharp_script_binding(CSharpScriptBinding &r_script_b void *CSharpLanguage::alloc_instance_binding_data(Object *p_object) { - SCOPED_MUTEX_LOCK(language_bind_mutex); + MutexLock lock(language_bind_mutex); Map<Object *, CSharpScriptBinding>::Element *match = script_bindings.find(p_object); if (match) @@ -1381,7 +1340,7 @@ void CSharpLanguage::free_instance_binding_data(void *p_data) { GD_MONO_ASSERT_THREAD_ATTACHED; { - SCOPED_MUTEX_LOCK(language_bind_mutex); + MutexLock lock(language_bind_mutex); Map<Object *, CSharpScriptBinding>::Element *data = (Map<Object *, CSharpScriptBinding>::Element *)p_data; @@ -2187,7 +2146,7 @@ CSharpInstance::~CSharpInstance() { CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get(); if (!script_binding.inited) { - SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->get_language_bind_mutex()); + MutexLock lock(CSharpLanguage::get_singleton()->get_language_bind_mutex()); if (!script_binding.inited) { // Other thread may have set it up // Already had a binding that needs to be setup @@ -2203,7 +2162,7 @@ CSharpInstance::~CSharpInstance() { } if (script.is_valid() && owner) { - SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->script_instances_mutex); + MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex); #ifdef DEBUG_ENABLED // CSharpInstance must not be created unless it's going to be added to the list for sure @@ -2979,7 +2938,7 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg instance->_reference_owner_unsafe(); // Here, after assigning the gchandle (for the refcount_incremented callback) { - SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->script_instances_mutex); + MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex); instances.insert(instance->owner); } @@ -3067,7 +3026,7 @@ PlaceHolderScriptInstance *CSharpScript::placeholder_instance_create(Object *p_t bool CSharpScript::instance_has(const Object *p_this) const { - SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->script_instances_mutex); + MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex); return instances.has((Object *)p_this); } @@ -3140,7 +3099,7 @@ Error CSharpScript::reload(bool p_keep_state) { bool has_instances; { - SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->script_instances_mutex); + MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex); has_instances = instances.size(); } @@ -3476,7 +3435,7 @@ CSharpScript::CSharpScript() : #ifdef DEBUG_ENABLED { - SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->script_instances_mutex); + MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex); CSharpLanguage::get_singleton()->script_list.add(&this->script_list); } #endif @@ -3485,7 +3444,7 @@ CSharpScript::CSharpScript() : CSharpScript::~CSharpScript() { #ifdef DEBUG_ENABLED - SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->script_instances_mutex); + MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex); CSharpLanguage::get_singleton()->script_list.remove(&this->script_list); #endif } diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h index 627218eaf5..f44c4aebc4 100644 --- a/modules/mono/csharp_script.h +++ b/modules/mono/csharp_script.h @@ -325,16 +325,16 @@ class CSharpLanguage : public ScriptLanguage { GDMono *gdmono; SelfList<CSharpScript>::List script_list; - Mutex *script_instances_mutex; - Mutex *script_gchandle_release_mutex; - Mutex *language_bind_mutex; + Mutex script_instances_mutex; + Mutex script_gchandle_release_mutex; + Mutex language_bind_mutex; Map<Object *, CSharpScriptBinding> script_bindings; #ifdef DEBUG_ENABLED // List of unsafe object references Map<ObjectID, int> unsafe_object_references; - Mutex *unsafe_object_references_lock; + Mutex unsafe_object_references_lock; #endif struct StringNameCache { @@ -376,7 +376,7 @@ class CSharpLanguage : public ScriptLanguage { public: StringNameCache string_names; - Mutex *get_language_bind_mutex() { return language_bind_mutex; } + const Mutex &get_language_bind_mutex() { return language_bind_mutex; } _FORCE_INLINE_ int get_language_index() { return lang_idx; } void set_language_index(int p_idx); diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp index ae6625a6c6..41f49d8ac9 100644 --- a/modules/mono/mono_gd/gd_mono_utils.cpp +++ b/modules/mono/mono_gd/gd_mono_utils.cpp @@ -33,6 +33,7 @@ #include <mono/metadata/exception.h> #include "core/os/dir_access.h" +#include "core/os/mutex.h" #include "core/os/os.h" #include "core/project_settings.h" #include "core/reference.h" @@ -43,7 +44,6 @@ #include "../csharp_script.h" #include "../utils/macros.h" -#include "../utils/mutex_utils.h" #include "gd_mono.h" #include "gd_mono_cache.h" #include "gd_mono_class.h" @@ -74,7 +74,7 @@ MonoObject *unmanaged_get_managed(Object *unmanaged) { CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->value(); if (!script_binding.inited) { - SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->get_language_bind_mutex()); + MutexLock lock(CSharpLanguage::get_singleton()->get_language_bind_mutex()); if (!script_binding.inited) { // Other thread may have set it up // Already had a binding that needs to be setup diff --git a/modules/mono/utils/mutex_utils.h b/modules/mono/utils/mutex_utils.h deleted file mode 100644 index bafd875395..0000000000 --- a/modules/mono/utils/mutex_utils.h +++ /dev/null @@ -1,67 +0,0 @@ -/*************************************************************************/ -/* mutex_utils.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2020 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 MUTEX_UTILS_H -#define MUTEX_UTILS_H - -#include "core/error_macros.h" -#include "core/os/mutex.h" - -#include "macros.h" - -class ScopedMutexLock { - Mutex *mutex; - -public: - ScopedMutexLock(Mutex *mutex) { - this->mutex = mutex; -#ifndef NO_THREADS -#ifdef DEBUG_ENABLED - CRASH_COND(!mutex); -#endif - this->mutex->lock(); -#endif - } - - ~ScopedMutexLock() { -#ifndef NO_THREADS -#ifdef DEBUG_ENABLED - CRASH_COND(!mutex); -#endif - mutex->unlock(); -#endif - } -}; - -#define SCOPED_MUTEX_LOCK(m_mutex) ScopedMutexLock GD_UNIQUE_NAME(__scoped_mutex_lock__)(m_mutex); - -// TODO: Add version that receives a lambda instead, once C++11 is allowed - -#endif // MUTEX_UTILS_H diff --git a/modules/regex/doc_classes/RegEx.xml b/modules/regex/doc_classes/RegEx.xml index e9f46b9853..3130c53331 100644 --- a/modules/regex/doc_classes/RegEx.xml +++ b/modules/regex/doc_classes/RegEx.xml @@ -10,7 +10,7 @@ var regex = RegEx.new() regex.compile("\\w-(\\d+)") [/codeblock] - The search pattern must be escaped first for gdscript before it is escaped for the expression. For example, [code]compile("\\d+")[/code] would be read by RegEx as [code]\d+[/code]. Similarly, [code]compile("\"(?:\\\\.|[^\"])*\"")[/code] would be read as [code]"(?:\\.|[^"])*"[/code]. + The search pattern must be escaped first for GDScript before it is escaped for the expression. For example, [code]compile("\\d+")[/code] would be read by RegEx as [code]\d+[/code]. Similarly, [code]compile("\"(?:\\\\.|[^\"])*\"")[/code] would be read as [code]"(?:\\.|[^"])*"[/code]. Using [method search] you can find the pattern within the given text. If a pattern is found, [RegExMatch] is returned and you can retrieve details of the results using functions such as [method RegExMatch.get_string] and [method RegExMatch.get_start]. [codeblock] var regex = RegEx.new() @@ -35,6 +35,8 @@ # Would print 01 03 3f 42 # Note that d0c would not match [/codeblock] + [b]Note:[/b] Godot's regex implementation is based on the [url=https://www.pcre.org/]PCRE2[/url] library. You can view the full pattern reference [url=https://www.pcre.org/current/doc/html/pcre2pattern.html]here[/url]. + [b]Tip:[/b] You can use [url=https://regexr.com/]Regexr[/url] to test regular expressions online. </description> <tutorials> </tutorials> diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp index 70f650cfd3..5036840413 100644 --- a/modules/visual_script/visual_script.cpp +++ b/modules/visual_script/visual_script.cpp @@ -928,13 +928,11 @@ ScriptInstance *VisualScript::instance_create(Object *p_this) { VisualScriptInstance *instance = memnew(VisualScriptInstance); instance->create(Ref<VisualScript>(this), p_this); - if (VisualScriptLanguage::singleton->lock) - VisualScriptLanguage::singleton->lock->lock(); - - instances[p_this] = instance; + { + MutexLock lock(VisualScriptLanguage::singleton->lock); - if (VisualScriptLanguage::singleton->lock) - VisualScriptLanguage::singleton->lock->unlock(); + instances[p_this] = instance; + } return instance; } @@ -2391,13 +2389,11 @@ VisualScriptInstance::VisualScriptInstance() { VisualScriptInstance::~VisualScriptInstance() { - if (VisualScriptLanguage::singleton->lock) - VisualScriptLanguage::singleton->lock->lock(); - - script->instances.erase(owner); + { + MutexLock lock(VisualScriptLanguage::singleton->lock); - if (VisualScriptLanguage::singleton->lock) - VisualScriptLanguage::singleton->lock->unlock(); + script->instances.erase(owner); + } for (Map<int, VisualScriptNodeInstance *>::Element *E = instances.front(); E; E = E->next()) { memdelete(E->get()); @@ -2836,9 +2832,6 @@ VisualScriptLanguage::VisualScriptLanguage() { _step = "_step"; _subcall = "_subcall"; singleton = this; -#ifndef NO_THREADS - lock = Mutex::create(); -#endif _debug_parse_err_node = -1; _debug_parse_err_file = ""; @@ -2859,9 +2852,6 @@ VisualScriptLanguage::VisualScriptLanguage() { VisualScriptLanguage::~VisualScriptLanguage() { - if (lock) - memdelete(lock); - if (_call_stack) { memdelete_arr(_call_stack); } diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h index 08b84bce1d..0a6daba64f 100644 --- a/modules/visual_script/visual_script.h +++ b/modules/visual_script/visual_script.h @@ -530,7 +530,7 @@ public: static VisualScriptLanguage *singleton; - Mutex *lock; + Mutex lock; bool debug_break(const String &p_error, bool p_allow_continue = true); bool debug_break_parse(const String &p_file, int p_node, const String &p_error); diff --git a/platform/android/audio_driver_jandroid.cpp b/platform/android/audio_driver_jandroid.cpp index 5a8e3b94da..e94dad9ac6 100644 --- a/platform/android/audio_driver_jandroid.cpp +++ b/platform/android/audio_driver_jandroid.cpp @@ -48,7 +48,7 @@ int AudioDriverAndroid::mix_rate = 44100; bool AudioDriverAndroid::quit = false; jobject AudioDriverAndroid::audioBuffer = NULL; void *AudioDriverAndroid::audioBufferPinned = NULL; -Mutex *AudioDriverAndroid::mutex = NULL; +Mutex AudioDriverAndroid::mutex; int32_t *AudioDriverAndroid::audioBuffer32 = NULL; const char *AudioDriverAndroid::get_name() const { @@ -58,7 +58,6 @@ const char *AudioDriverAndroid::get_name() const { Error AudioDriverAndroid::init() { - mutex = Mutex::create(); /* // TODO: pass in/return a (Java) device ID, also whether we're opening for input or output this->spec.samples = Android_JNI_OpenAudioDevice(this->spec.freq, this->spec.format == AUDIO_U8 ? 0 : 1, this->spec.channels, this->spec.samples); @@ -133,7 +132,7 @@ void AudioDriverAndroid::thread_func(JNIEnv *env) { int16_t *ptr = (int16_t *)audioBufferPinned; int fc = audioBufferFrames; - if (!s_ad->active || mutex->try_lock() != OK) { + if (!s_ad->active || mutex.try_lock() != OK) { for (int i = 0; i < fc; i++) { ptr[i] = 0; @@ -143,7 +142,7 @@ void AudioDriverAndroid::thread_func(JNIEnv *env) { s_ad->audio_server_process(fc / 2, audioBuffer32); - mutex->unlock(); + mutex.unlock(); for (int i = 0; i < fc; i++) { @@ -167,14 +166,12 @@ AudioDriver::SpeakerMode AudioDriverAndroid::get_speaker_mode() const { void AudioDriverAndroid::lock() { - if (mutex) - mutex->lock(); + mutex.lock(); } void AudioDriverAndroid::unlock() { - if (mutex) - mutex->unlock(); + mutex.unlock(); } void AudioDriverAndroid::finish() { diff --git a/platform/android/audio_driver_jandroid.h b/platform/android/audio_driver_jandroid.h index d3d1641c20..b1cc3f9aa0 100644 --- a/platform/android/audio_driver_jandroid.h +++ b/platform/android/audio_driver_jandroid.h @@ -37,7 +37,7 @@ class AudioDriverAndroid : public AudioDriver { - static Mutex *mutex; + static Mutex mutex; static AudioDriverAndroid *s_ad; static jobject io; static jmethodID _init_audio; diff --git a/platform/android/audio_driver_opensl.cpp b/platform/android/audio_driver_opensl.cpp index 6e9864c803..307bc3a169 100644 --- a/platform/android/audio_driver_opensl.cpp +++ b/platform/android/audio_driver_opensl.cpp @@ -44,8 +44,8 @@ void AudioDriverOpenSL::_buffer_callback( if (pause) { mix = false; - } else if (mutex) { - mix = mutex->try_lock() == OK; + } else { + mix = mutex.try_lock() == OK; } if (mix) { @@ -58,8 +58,8 @@ void AudioDriverOpenSL::_buffer_callback( } } - if (mutex && mix) - mutex->unlock(); + if (mix) + mutex.unlock(); const int32_t *src_buff = mixdown_buffer; @@ -107,7 +107,6 @@ Error AudioDriverOpenSL::init() { void AudioDriverOpenSL::start() { - mutex = Mutex::create(); active = false; SLresult res; @@ -330,13 +329,13 @@ AudioDriver::SpeakerMode AudioDriverOpenSL::get_speaker_mode() const { void AudioDriverOpenSL::lock() { if (active && mutex) - mutex->lock(); + mutex.lock(); } void AudioDriverOpenSL::unlock() { if (active && mutex) - mutex->unlock(); + mutex.unlock(); } void AudioDriverOpenSL::finish() { @@ -359,7 +358,6 @@ void AudioDriverOpenSL::set_pause(bool p_pause) { AudioDriverOpenSL::AudioDriverOpenSL() { s_ad = this; - mutex = Mutex::create(); //NULL; pause = false; active = false; } diff --git a/platform/android/audio_driver_opensl.h b/platform/android/audio_driver_opensl.h index 57d9b30af6..569e2aa54b 100644 --- a/platform/android/audio_driver_opensl.h +++ b/platform/android/audio_driver_opensl.h @@ -40,7 +40,7 @@ class AudioDriverOpenSL : public AudioDriver { bool active; - Mutex *mutex; + Mutex mutex; enum { diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index 50bf671a84..c618177475 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -257,7 +257,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { Vector<Device> devices; volatile bool devices_changed; - Mutex *device_lock; + Mutex device_lock; Thread *device_thread; volatile bool quit_request; @@ -288,7 +288,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { ldevices.push_back(d); } - ea->device_lock->lock(); + MutexLock lock(ea->device_lock); bool different = false; @@ -381,8 +381,6 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { ea->devices = ndevices; ea->devices_changed = true; } - - ea->device_lock->unlock(); } uint64_t sleep = 200; @@ -1432,11 +1430,8 @@ public: virtual int get_options_count() const { - device_lock->lock(); - int dc = devices.size(); - device_lock->unlock(); - - return dc; + MutexLock lock(device_lock); + return devices.size(); } virtual String get_options_tooltip() const { @@ -1447,16 +1442,14 @@ public: virtual String get_option_label(int p_index) const { ERR_FAIL_INDEX_V(p_index, devices.size(), ""); - device_lock->lock(); - String s = devices[p_index].name; - device_lock->unlock(); - return s; + MutexLock lock(device_lock); + return devices[p_index].name; } virtual String get_option_tooltip(int p_index) const { ERR_FAIL_INDEX_V(p_index, devices.size(), ""); - device_lock->lock(); + MutexLock lock(device_lock); String s = devices[p_index].description; if (devices.size() == 1) { // Tooltip will be: @@ -1464,7 +1457,6 @@ public: // Description s = devices[p_index].name + "\n\n" + s; } - device_lock->unlock(); return s; } @@ -1479,7 +1471,7 @@ public: return ERR_UNCONFIGURED; } - device_lock->lock(); + MutexLock lock(device_lock); EditorProgress ep("run", "Running on " + devices[p_device].name, 3); @@ -1487,7 +1479,6 @@ public: // Export_temp APK. if (ep.step("Exporting APK...", 0)) { - device_lock->unlock(); return ERR_SKIP; } @@ -1502,7 +1493,6 @@ public: #define CLEANUP_AND_RETURN(m_err) \ { \ DirAccess::remove_file_or_error(tmp_export_path); \ - device_lock->unlock(); \ return m_err; \ } @@ -2570,7 +2560,6 @@ public: run_icon.instance(); run_icon->create_from_image(img); - device_lock = Mutex::create(); devices_changed = true; quit_request = false; device_thread = Thread::create(_device_poll_thread, this); @@ -2579,7 +2568,6 @@ public: ~EditorExportPlatformAndroid() { quit_request = true; Thread::wait_to_finish(device_thread); - memdelete(device_lock); memdelete(device_thread); } }; diff --git a/platform/haiku/audio_driver_media_kit.cpp b/platform/haiku/audio_driver_media_kit.cpp index b7f6b57244..0a5df14743 100644 --- a/platform/haiku/audio_driver_media_kit.cpp +++ b/platform/haiku/audio_driver_media_kit.cpp @@ -67,7 +67,6 @@ Error AudioDriverMediaKit::init() { ERR_FAIL_COND_V(player == NULL, ERR_CANT_OPEN); } - mutex = Mutex::create(); player->Start(); return OK; @@ -108,14 +107,14 @@ void AudioDriverMediaKit::lock() { if (!mutex) return; - mutex->lock(); + mutex.lock(); } void AudioDriverMediaKit::unlock() { if (!mutex) return; - mutex->unlock(); + mutex.unlock(); } void AudioDriverMediaKit::finish() { @@ -124,15 +123,9 @@ void AudioDriverMediaKit::finish() { if (samples_in) { memdelete_arr(samples_in); }; - - if (mutex) { - memdelete(mutex); - mutex = NULL; - } } AudioDriverMediaKit::AudioDriverMediaKit() { - mutex = NULL; player = NULL; } diff --git a/platform/haiku/audio_driver_media_kit.h b/platform/haiku/audio_driver_media_kit.h index 06a362a89e..8272780fa7 100644 --- a/platform/haiku/audio_driver_media_kit.h +++ b/platform/haiku/audio_driver_media_kit.h @@ -40,7 +40,7 @@ #include <SoundPlayer.h> class AudioDriverMediaKit : public AudioDriver { - Mutex *mutex; + Mutex mutex; BSoundPlayer *player; static int32_t *samples_in; diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp index c44a0270ab..f0326d5027 100644 --- a/platform/javascript/export/export.cpp +++ b/platform/javascript/export/export.cpp @@ -200,7 +200,7 @@ class EditorExportPlatformJavaScript : public EditorExportPlatform { private: Ref<EditorHTTPServer> server; bool server_quit; - Mutex *server_lock; + Mutex server_lock; Thread *server_thread; static void _server_thread_poll(void *data); @@ -531,9 +531,8 @@ bool EditorExportPlatformJavaScript::poll_export() { menu_options = preset.is_valid(); if (server->is_listening()) { if (menu_options == 0) { - server_lock->lock(); + MutexLock lock(server_lock); server->stop(); - server_lock->unlock(); } else { menu_options += 1; } @@ -553,9 +552,8 @@ int EditorExportPlatformJavaScript::get_options_count() const { Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_preset, int p_option, int p_debug_flags) { if (p_option == 1) { - server_lock->lock(); + MutexLock lock(server_lock); server->stop(); - server_lock->unlock(); return OK; } @@ -584,10 +582,12 @@ Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_prese ERR_FAIL_COND_V_MSG(!bind_ip.is_valid(), ERR_INVALID_PARAMETER, "Invalid editor setting 'export/web/http_host': '" + bind_host + "'. Try using '127.0.0.1'."); // Restart server. - server_lock->lock(); - server->stop(); - err = server->listen(bind_port, bind_ip); - server_lock->unlock(); + { + MutexLock lock(server_lock); + + server->stop(); + err = server->listen(bind_port, bind_ip); + } ERR_FAIL_COND_V_MSG(err != OK, err, "Unable to start HTTP server."); OS::get_singleton()->shell_open(String("http://" + bind_host + ":" + itos(bind_port) + "/tmp_js_export.html")); @@ -605,9 +605,10 @@ void EditorExportPlatformJavaScript::_server_thread_poll(void *data) { EditorExportPlatformJavaScript *ej = (EditorExportPlatformJavaScript *)data; while (!ej->server_quit) { OS::get_singleton()->delay_usec(1000); - ej->server_lock->lock(); - ej->server->poll(); - ej->server_lock->unlock(); + { + MutexLock lock(ej->server_lock); + ej->server->poll(); + } } } @@ -615,7 +616,6 @@ EditorExportPlatformJavaScript::EditorExportPlatformJavaScript() { server.instance(); server_quit = false; - server_lock = Mutex::create(); server_thread = Thread::create(_server_thread_poll, this); Ref<Image> img = memnew(Image(_javascript_logo)); @@ -639,7 +639,6 @@ EditorExportPlatformJavaScript::~EditorExportPlatformJavaScript() { server->stop(); server_quit = true; Thread::wait_to_finish(server_thread); - memdelete(server_lock); memdelete(server_thread); } diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp index 3cd7a02a94..1e63d50263 100644 --- a/platform/uwp/os_uwp.cpp +++ b/platform/uwp/os_uwp.cpp @@ -141,7 +141,6 @@ void OS_UWP::initialize_core() { ThreadUWP::make_default(); SemaphoreWindows::make_default(); - MutexWindows::make_default(); RWLockWindows::make_default(); FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_RESOURCES); diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 716a637993..2b414dd5bf 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -47,7 +47,6 @@ #include "drivers/windows/dir_access_windows.h" #include "drivers/windows/file_access_windows.h" -#include "drivers/windows/mutex_windows.h" #include "drivers/windows/rw_lock_windows.h" #include "drivers/windows/semaphore_windows.h" #include "drivers/windows/thread_windows.h" @@ -230,7 +229,6 @@ void OS_Windows::initialize_core() { ThreadWindows::make_default(); SemaphoreWindows::make_default(); - MutexWindows::make_default(); RWLockWindows::make_default(); FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_RESOURCES); diff --git a/platform/x11/joypad_linux.cpp b/platform/x11/joypad_linux.cpp index a64a25aeee..a9fe7275c2 100644 --- a/platform/x11/joypad_linux.cpp +++ b/platform/x11/joypad_linux.cpp @@ -83,7 +83,6 @@ void JoypadLinux::Joypad::reset() { JoypadLinux::JoypadLinux(InputDefault *in) { exit_udev = false; input = in; - joy_mutex = Mutex::create(); joy_thread = Thread::create(joy_thread_func, this); } @@ -91,7 +90,6 @@ JoypadLinux::~JoypadLinux() { exit_udev = true; Thread::wait_to_finish(joy_thread); memdelete(joy_thread); - memdelete(joy_mutex); close_joypad(); } @@ -137,9 +135,8 @@ void JoypadLinux::enumerate_joypads(udev *p_udev) { String devnode_str = devnode; if (devnode_str.find(ignore_str) == -1) { - joy_mutex->lock(); + MutexLock lock(joy_mutex); open_joypad(devnode); - joy_mutex->unlock(); } } udev_device_unref(dev); @@ -176,7 +173,7 @@ void JoypadLinux::monitor_joypads(udev *p_udev) { if (dev && udev_device_get_devnode(dev) != 0) { - joy_mutex->lock(); + MutexLock lock(joy_mutex); String action = udev_device_get_action(dev); const char *devnode = udev_device_get_devnode(dev); if (devnode) { @@ -192,7 +189,6 @@ void JoypadLinux::monitor_joypads(udev *p_udev) { } udev_device_unref(dev); - joy_mutex->unlock(); } } usleep(50000); @@ -204,15 +200,17 @@ void JoypadLinux::monitor_joypads(udev *p_udev) { void JoypadLinux::monitor_joypads() { while (!exit_udev) { - joy_mutex->lock(); - for (int i = 0; i < 32; i++) { - char fname[64]; - sprintf(fname, "/dev/input/event%d", i); - if (attached_devices.find(fname) == -1) { - open_joypad(fname); + { + MutexLock lock(joy_mutex); + + for (int i = 0; i < 32; i++) { + char fname[64]; + sprintf(fname, "/dev/input/event%d", i); + if (attached_devices.find(fname) == -1) { + open_joypad(fname); + } } } - joy_mutex->unlock(); usleep(1000000); // 1s } } @@ -457,7 +455,7 @@ InputDefault::JoyAxis JoypadLinux::axis_correct(const input_absinfo *p_abs, int void JoypadLinux::process_joypads() { - if (joy_mutex->try_lock() != OK) { + if (joy_mutex.try_lock() != OK) { return; } for (int i = 0; i < JOYPADS_MAX; i++) { @@ -548,6 +546,6 @@ void JoypadLinux::process_joypads() { } } } - joy_mutex->unlock(); + joy_mutex.unlock(); } #endif diff --git a/platform/x11/joypad_linux.h b/platform/x11/joypad_linux.h index e5638899bf..d5719b6dbe 100644 --- a/platform/x11/joypad_linux.h +++ b/platform/x11/joypad_linux.h @@ -72,7 +72,7 @@ private: }; bool exit_udev; - Mutex *joy_mutex; + Mutex joy_mutex; Thread *joy_thread; InputDefault *input; Joypad joypads[JOYPADS_MAX]; diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index 942b63898d..ef7aa9ba01 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -41,17 +41,13 @@ #include "servers/visual/visual_server_raster.h" #include "servers/visual_server.h" -Mutex *CanvasItemMaterial::material_mutex = NULL; +Mutex CanvasItemMaterial::material_mutex; SelfList<CanvasItemMaterial>::List *CanvasItemMaterial::dirty_materials = NULL; Map<CanvasItemMaterial::MaterialKey, CanvasItemMaterial::ShaderData> CanvasItemMaterial::shader_map; CanvasItemMaterial::ShaderNames *CanvasItemMaterial::shader_names = NULL; void CanvasItemMaterial::init_shaders() { -#ifndef NO_THREADS - material_mutex = Mutex::create(); -#endif - dirty_materials = memnew(SelfList<CanvasItemMaterial>::List); shader_names = memnew(ShaderNames); @@ -66,10 +62,6 @@ void CanvasItemMaterial::finish_shaders() { memdelete(dirty_materials); memdelete(shader_names); dirty_materials = NULL; - -#ifndef NO_THREADS - memdelete(material_mutex); -#endif } void CanvasItemMaterial::_update_shader() { @@ -156,44 +148,28 @@ void CanvasItemMaterial::_update_shader() { void CanvasItemMaterial::flush_changes() { - if (material_mutex) - material_mutex->lock(); + MutexLock lock(material_mutex); while (dirty_materials->first()) { dirty_materials->first()->self()->_update_shader(); } - - if (material_mutex) - material_mutex->unlock(); } void CanvasItemMaterial::_queue_shader_change() { - if (material_mutex) - material_mutex->lock(); + MutexLock lock(material_mutex); if (!element.in_list()) { dirty_materials->add(&element); } - - if (material_mutex) - material_mutex->unlock(); } bool CanvasItemMaterial::_is_shader_dirty() const { - bool dirty = false; - - if (material_mutex) - material_mutex->lock(); - - dirty = element.in_list(); + MutexLock lock(material_mutex); - if (material_mutex) - material_mutex->unlock(); - - return dirty; + return element.in_list(); } void CanvasItemMaterial::set_blend_mode(BlendMode p_blend_mode) { @@ -332,8 +308,7 @@ CanvasItemMaterial::CanvasItemMaterial() : CanvasItemMaterial::~CanvasItemMaterial() { - if (material_mutex) - material_mutex->lock(); + MutexLock lock(material_mutex); if (shader_map.has(current_key)) { shader_map[current_key].users--; @@ -345,9 +320,6 @@ CanvasItemMaterial::~CanvasItemMaterial() { VS::get_singleton()->material_set_shader(_get_material(), RID()); } - - if (material_mutex) - material_mutex->unlock(); } /////////////////////////////////////////////////////////////////// diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h index 3cd8e6ef74..c7f9500ea1 100644 --- a/scene/2d/canvas_item.h +++ b/scene/2d/canvas_item.h @@ -108,7 +108,7 @@ private: return mk; } - static Mutex *material_mutex; + static Mutex material_mutex; static SelfList<CanvasItemMaterial>::List *dirty_materials; SelfList<CanvasItemMaterial> element; diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp index 35df6c8945..f781f06b0f 100644 --- a/scene/2d/cpu_particles_2d.cpp +++ b/scene/2d/cpu_particles_2d.cpp @@ -970,118 +970,103 @@ void CPUParticles2D::_particles_process(float p_delta) { } void CPUParticles2D::_update_particle_data_buffer() { -#ifndef NO_THREADS - update_mutex->lock(); -#endif + MutexLock lock(update_mutex); - { - - int pc = particles.size(); + int pc = particles.size(); - int *ow; - int *order = NULL; + int *ow; + int *order = NULL; - float *w = particle_data.ptrw(); - const Particle *r = particles.ptr(); - float *ptr = w; + float *w = particle_data.ptrw(); + const Particle *r = particles.ptr(); + float *ptr = w; - if (draw_order != DRAW_ORDER_INDEX) { - ow = particle_order.ptrw(); - order = ow; + if (draw_order != DRAW_ORDER_INDEX) { + ow = particle_order.ptrw(); + order = ow; - for (int i = 0; i < pc; i++) { - order[i] = i; - } - if (draw_order == DRAW_ORDER_LIFETIME) { - SortArray<int, SortLifetime> sorter; - sorter.compare.particles = r; - sorter.sort(order, pc); - } + for (int i = 0; i < pc; i++) { + order[i] = i; + } + if (draw_order == DRAW_ORDER_LIFETIME) { + SortArray<int, SortLifetime> sorter; + sorter.compare.particles = r; + sorter.sort(order, pc); } + } - for (int i = 0; i < pc; i++) { + for (int i = 0; i < pc; i++) { - int idx = order ? order[i] : i; + int idx = order ? order[i] : i; - Transform2D t = r[idx].transform; + Transform2D t = r[idx].transform; - if (!local_coords) { - t = inv_emission_transform * t; - } + if (!local_coords) { + t = inv_emission_transform * t; + } - if (r[idx].active) { + if (r[idx].active) { - ptr[0] = t.elements[0][0]; - ptr[1] = t.elements[1][0]; - ptr[2] = 0; - ptr[3] = t.elements[2][0]; - ptr[4] = t.elements[0][1]; - ptr[5] = t.elements[1][1]; - ptr[6] = 0; - ptr[7] = t.elements[2][1]; + ptr[0] = t.elements[0][0]; + ptr[1] = t.elements[1][0]; + ptr[2] = 0; + ptr[3] = t.elements[2][0]; + ptr[4] = t.elements[0][1]; + ptr[5] = t.elements[1][1]; + ptr[6] = 0; + ptr[7] = t.elements[2][1]; - } else { - zeromem(ptr, sizeof(float) * 8); - } + } else { + zeromem(ptr, sizeof(float) * 8); + } - Color c = r[idx].color; + Color c = r[idx].color; - ptr[8] = c.r; - ptr[9] = c.g; - ptr[10] = c.b; - ptr[11] = c.a; + ptr[8] = c.r; + ptr[9] = c.g; + ptr[10] = c.b; + ptr[11] = c.a; - ptr[12] = r[idx].custom[0]; - ptr[13] = r[idx].custom[1]; - ptr[14] = r[idx].custom[2]; - ptr[15] = r[idx].custom[3]; + ptr[12] = r[idx].custom[0]; + ptr[13] = r[idx].custom[1]; + ptr[14] = r[idx].custom[2]; + ptr[15] = r[idx].custom[3]; - ptr += 16; - } + ptr += 16; } - -#ifndef NO_THREADS - update_mutex->unlock(); -#endif } void CPUParticles2D::_set_redraw(bool p_redraw) { if (redraw == p_redraw) return; redraw = p_redraw; -#ifndef NO_THREADS - update_mutex->lock(); -#endif - if (redraw) { - VS::get_singleton()->connect_compat("frame_pre_draw", this, "_update_render_thread"); - VS::get_singleton()->canvas_item_set_update_when_visible(get_canvas_item(), true); - - VS::get_singleton()->multimesh_set_visible_instances(multimesh, -1); - } else { - if (VS::get_singleton()->is_connected_compat("frame_pre_draw", this, "_update_render_thread")) { - VS::get_singleton()->disconnect_compat("frame_pre_draw", this, "_update_render_thread"); - } - VS::get_singleton()->canvas_item_set_update_when_visible(get_canvas_item(), false); - VS::get_singleton()->multimesh_set_visible_instances(multimesh, 0); + { + MutexLock lock(update_mutex); + + if (redraw) { + VS::get_singleton()->connect_compat("frame_pre_draw", this, "_update_render_thread"); + VS::get_singleton()->canvas_item_set_update_when_visible(get_canvas_item(), true); + + VS::get_singleton()->multimesh_set_visible_instances(multimesh, -1); + } else { + if (VS::get_singleton()->is_connected_compat("frame_pre_draw", this, "_update_render_thread")) { + VS::get_singleton()->disconnect_compat("frame_pre_draw", this, "_update_render_thread"); + } + VS::get_singleton()->canvas_item_set_update_when_visible(get_canvas_item(), false); + + VS::get_singleton()->multimesh_set_visible_instances(multimesh, 0); + } } -#ifndef NO_THREADS - update_mutex->unlock(); -#endif + update(); // redraw to update render list } void CPUParticles2D::_update_render_thread() { -#ifndef NO_THREADS - update_mutex->lock(); -#endif + MutexLock lock(update_mutex); VS::get_singleton()->multimesh_set_buffer(multimesh, particle_data); - -#ifndef NO_THREADS - update_mutex->unlock(); -#endif } void CPUParticles2D::_notification(int p_what) { @@ -1494,18 +1479,10 @@ CPUParticles2D::CPUParticles2D() { set_color(Color(1, 1, 1, 1)); -#ifndef NO_THREADS - update_mutex = Mutex::create(); -#endif - _update_mesh_texture(); } CPUParticles2D::~CPUParticles2D() { VS::get_singleton()->free(multimesh); VS::get_singleton()->free(mesh); - -#ifndef NO_THREADS - memdelete(update_mutex); -#endif } diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h index 6f85631fe1..18d0caceed 100644 --- a/scene/2d/cpu_particles_2d.h +++ b/scene/2d/cpu_particles_2d.h @@ -178,7 +178,7 @@ private: void _particles_process(float p_delta); void _update_particle_data_buffer(); - Mutex *update_mutex; + Mutex update_mutex; void _update_render_thread(); diff --git a/scene/2d/navigation_polygon.cpp b/scene/2d/navigation_polygon.cpp index 6754c1c9a6..8fb9a8427e 100644 --- a/scene/2d/navigation_polygon.cpp +++ b/scene/2d/navigation_polygon.cpp @@ -82,9 +82,10 @@ bool NavigationPolygon::_edit_is_selected_on_click(const Point2 &p_point, double void NavigationPolygon::set_vertices(const Vector<Vector2> &p_vertices) { - navmesh_generation->lock(); - navmesh.unref(); - navmesh_generation->unlock(); + { + MutexLock lock(navmesh_generation); + navmesh.unref(); + } vertices = p_vertices; rect_cache_dirty = true; } @@ -96,9 +97,10 @@ Vector<Vector2> NavigationPolygon::get_vertices() const { void NavigationPolygon::_set_polygons(const Array &p_array) { - navmesh_generation->lock(); - navmesh.unref(); - navmesh_generation->unlock(); + { + MutexLock lock(navmesh_generation); + navmesh.unref(); + } polygons.resize(p_array.size()); for (int i = 0; i < p_array.size(); i++) { polygons.write[i].indices = p_array[i]; @@ -141,9 +143,10 @@ void NavigationPolygon::add_polygon(const Vector<int> &p_polygon) { Polygon polygon; polygon.indices = p_polygon; polygons.push_back(polygon); - navmesh_generation->lock(); - navmesh.unref(); - navmesh_generation->unlock(); + { + MutexLock lock(navmesh_generation); + navmesh.unref(); + } } void NavigationPolygon::add_outline_at_index(const Vector<Vector2> &p_outline, int p_index) { @@ -164,13 +167,15 @@ Vector<int> NavigationPolygon::get_polygon(int p_idx) { void NavigationPolygon::clear_polygons() { polygons.clear(); - navmesh_generation->lock(); - navmesh.unref(); - navmesh_generation->unlock(); + { + MutexLock lock(navmesh_generation); + navmesh.unref(); + } } Ref<NavigationMesh> NavigationPolygon::get_mesh() { - navmesh_generation->lock(); + MutexLock lock(navmesh_generation); + if (navmesh.is_null()) { navmesh.instance(); Vector<Vector3> verts; @@ -190,7 +195,7 @@ Ref<NavigationMesh> NavigationPolygon::get_mesh() { navmesh->add_polygon(get_polygon(i)); } } - navmesh_generation->unlock(); + return navmesh; } @@ -230,9 +235,10 @@ void NavigationPolygon::clear_outlines() { } void NavigationPolygon::make_polygons_from_outlines() { - navmesh_generation->lock(); - navmesh.unref(); - navmesh_generation->unlock(); + { + MutexLock lock(navmesh_generation); + navmesh.unref(); + } List<TriangulatorPoly> in_poly, out_poly; Vector2 outside_point(-1e10, -1e10); @@ -362,15 +368,13 @@ void NavigationPolygon::_bind_methods() { } NavigationPolygon::NavigationPolygon() : - rect_cache_dirty(true), - navmesh_generation(Mutex::create()) { + rect_cache_dirty(true) { } NavigationPolygon::~NavigationPolygon() { - memdelete(navmesh_generation); } -void NavigationPolygonInstance::set_enabled(bool p_enabled) { +void NavigationRegion2D::set_enabled(bool p_enabled) { if (enabled == p_enabled) return; @@ -394,25 +398,25 @@ void NavigationPolygonInstance::set_enabled(bool p_enabled) { update(); } -bool NavigationPolygonInstance::is_enabled() const { +bool NavigationRegion2D::is_enabled() const { return enabled; } ///////////////////////////// #ifdef TOOLS_ENABLED -Rect2 NavigationPolygonInstance::_edit_get_rect() const { +Rect2 NavigationRegion2D::_edit_get_rect() const { return navpoly.is_valid() ? navpoly->_edit_get_rect() : Rect2(); } -bool NavigationPolygonInstance::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { +bool NavigationRegion2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { return navpoly.is_valid() ? navpoly->_edit_is_selected_on_click(p_point, p_tolerance) : false; } #endif -void NavigationPolygonInstance::_notification(int p_what) { +void NavigationRegion2D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { @@ -496,7 +500,7 @@ void NavigationPolygonInstance::_notification(int p_what) { } } -void NavigationPolygonInstance::set_navigation_polygon(const Ref<NavigationPolygon> &p_navpoly) { +void NavigationRegion2D::set_navigation_polygon(const Ref<NavigationPolygon> &p_navpoly) { if (p_navpoly == navpoly) { return; @@ -518,18 +522,18 @@ void NavigationPolygonInstance::set_navigation_polygon(const Ref<NavigationPolyg update_configuration_warning(); } -Ref<NavigationPolygon> NavigationPolygonInstance::get_navigation_polygon() const { +Ref<NavigationPolygon> NavigationRegion2D::get_navigation_polygon() const { return navpoly; } -void NavigationPolygonInstance::_navpoly_changed() { +void NavigationRegion2D::_navpoly_changed() { if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint())) update(); } -String NavigationPolygonInstance::get_configuration_warning() const { +String NavigationRegion2D::get_configuration_warning() const { if (!is_visible_in_tree() || !is_inside_tree()) return String(); @@ -547,24 +551,24 @@ String NavigationPolygonInstance::get_configuration_warning() const { c = Object::cast_to<Node2D>(c->get_parent()); } - return TTR("NavigationPolygonInstance must be a child or grandchild to a Navigation2D node. It only provides navigation data."); + return TTR("NavigationRegion2D must be a child or grandchild to a Navigation2D node. It only provides navigation data."); } -void NavigationPolygonInstance::_bind_methods() { +void NavigationRegion2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_navigation_polygon", "navpoly"), &NavigationPolygonInstance::set_navigation_polygon); - ClassDB::bind_method(D_METHOD("get_navigation_polygon"), &NavigationPolygonInstance::get_navigation_polygon); + ClassDB::bind_method(D_METHOD("set_navigation_polygon", "navpoly"), &NavigationRegion2D::set_navigation_polygon); + ClassDB::bind_method(D_METHOD("get_navigation_polygon"), &NavigationRegion2D::get_navigation_polygon); - ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &NavigationPolygonInstance::set_enabled); - ClassDB::bind_method(D_METHOD("is_enabled"), &NavigationPolygonInstance::is_enabled); + ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &NavigationRegion2D::set_enabled); + ClassDB::bind_method(D_METHOD("is_enabled"), &NavigationRegion2D::is_enabled); - ClassDB::bind_method(D_METHOD("_navpoly_changed"), &NavigationPolygonInstance::_navpoly_changed); + ClassDB::bind_method(D_METHOD("_navpoly_changed"), &NavigationRegion2D::_navpoly_changed); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "navpoly", PROPERTY_HINT_RESOURCE_TYPE, "NavigationPolygon"), "set_navigation_polygon", "get_navigation_polygon"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled"); } -NavigationPolygonInstance::NavigationPolygonInstance() { +NavigationRegion2D::NavigationRegion2D() { enabled = true; set_notify_transform(true); @@ -573,6 +577,6 @@ NavigationPolygonInstance::NavigationPolygonInstance() { navigation = NULL; } -NavigationPolygonInstance::~NavigationPolygonInstance() { +NavigationRegion2D::~NavigationRegion2D() { Navigation2DServer::get_singleton()->free(region); } diff --git a/scene/2d/navigation_polygon.h b/scene/2d/navigation_polygon.h index 557ce4b3e7..579d6b0e0e 100644 --- a/scene/2d/navigation_polygon.h +++ b/scene/2d/navigation_polygon.h @@ -34,8 +34,6 @@ #include "scene/2d/node_2d.h" #include "scene/resources/navigation_mesh.h" -class Mutex; - class NavigationPolygon : public Resource { GDCLASS(NavigationPolygon, Resource); @@ -50,7 +48,7 @@ class NavigationPolygon : public Resource { mutable Rect2 item_rect; mutable bool rect_cache_dirty; - Mutex *navmesh_generation; + Mutex navmesh_generation; // Navigation mesh Ref<NavigationMesh> navmesh; @@ -96,9 +94,9 @@ public: class Navigation2D; -class NavigationPolygonInstance : public Node2D { +class NavigationRegion2D : public Node2D { - GDCLASS(NavigationPolygonInstance, Node2D); + GDCLASS(NavigationRegion2D, Node2D); bool enabled; RID region; @@ -125,8 +123,8 @@ public: String get_configuration_warning() const; - NavigationPolygonInstance(); - ~NavigationPolygonInstance(); + NavigationRegion2D(); + ~NavigationRegion2D(); }; #endif // NAVIGATIONPOLYGON_H diff --git a/scene/3d/collision_shape.cpp b/scene/3d/collision_shape.cpp index d0d775d557..c7a92b66e1 100644 --- a/scene/3d/collision_shape.cpp +++ b/scene/3d/collision_shape.cpp @@ -33,9 +33,9 @@ #include "scene/resources/capsule_shape.h" #include "scene/resources/concave_polygon_shape.h" #include "scene/resources/convex_polygon_shape.h" -#include "scene/resources/plane_shape.h" #include "scene/resources/ray_shape.h" #include "scene/resources/sphere_shape.h" +#include "scene/resources/world_margin_shape.h" #include "servers/visual_server.h" //TODO: Implement CylinderShape and HeightMapShape? #include "core/math/quick_hull.h" @@ -123,10 +123,6 @@ String CollisionShape::get_configuration_warning() const { return TTR("A shape must be provided for CollisionShape to function. Please create a shape resource for it."); } - if (shape->is_class("PlaneShape")) { - return TTR("Plane shapes don't work well and will be removed in future versions. Please don't use them."); - } - return String(); } diff --git a/scene/3d/cpu_particles.cpp b/scene/3d/cpu_particles.cpp index cddbe4bbbb..eefda96caa 100644 --- a/scene/3d/cpu_particles.cpp +++ b/scene/3d/cpu_particles.cpp @@ -1017,140 +1017,125 @@ void CPUParticles::_particles_process(float p_delta) { } void CPUParticles::_update_particle_data_buffer() { -#ifndef NO_THREADS - update_mutex->lock(); -#endif + MutexLock lock(update_mutex); - { + int pc = particles.size(); - int pc = particles.size(); + int *ow; + int *order = NULL; - int *ow; - int *order = NULL; + float *w = particle_data.ptrw(); + const Particle *r = particles.ptr(); + float *ptr = w; - float *w = particle_data.ptrw(); - const Particle *r = particles.ptr(); - float *ptr = w; + if (draw_order != DRAW_ORDER_INDEX) { + ow = particle_order.ptrw(); + order = ow; - if (draw_order != DRAW_ORDER_INDEX) { - ow = particle_order.ptrw(); - order = ow; + for (int i = 0; i < pc; i++) { + order[i] = i; + } + if (draw_order == DRAW_ORDER_LIFETIME) { + SortArray<int, SortLifetime> sorter; + sorter.compare.particles = r; + sorter.sort(order, pc); + } else if (draw_order == DRAW_ORDER_VIEW_DEPTH) { + Camera *c = get_viewport()->get_camera(); + if (c) { + Vector3 dir = c->get_global_transform().basis.get_axis(2); //far away to close + + if (local_coords) { + + // will look different from Particles in editor as this is based on the camera in the scenetree + // and not the editor camera + dir = inv_emission_transform.xform(dir).normalized(); + } else { + dir = dir.normalized(); + } - for (int i = 0; i < pc; i++) { - order[i] = i; - } - if (draw_order == DRAW_ORDER_LIFETIME) { - SortArray<int, SortLifetime> sorter; + SortArray<int, SortAxis> sorter; sorter.compare.particles = r; + sorter.compare.axis = dir; sorter.sort(order, pc); - } else if (draw_order == DRAW_ORDER_VIEW_DEPTH) { - Camera *c = get_viewport()->get_camera(); - if (c) { - Vector3 dir = c->get_global_transform().basis.get_axis(2); //far away to close - - if (local_coords) { - - // will look different from Particles in editor as this is based on the camera in the scenetree - // and not the editor camera - dir = inv_emission_transform.xform(dir).normalized(); - } else { - dir = dir.normalized(); - } - - SortArray<int, SortAxis> sorter; - sorter.compare.particles = r; - sorter.compare.axis = dir; - sorter.sort(order, pc); - } } } + } - for (int i = 0; i < pc; i++) { - - int idx = order ? order[i] : i; + for (int i = 0; i < pc; i++) { - Transform t = r[idx].transform; + int idx = order ? order[i] : i; - if (!local_coords) { - t = inv_emission_transform * t; - } + Transform t = r[idx].transform; - if (r[idx].active) { - ptr[0] = t.basis.elements[0][0]; - ptr[1] = t.basis.elements[0][1]; - ptr[2] = t.basis.elements[0][2]; - ptr[3] = t.origin.x; - ptr[4] = t.basis.elements[1][0]; - ptr[5] = t.basis.elements[1][1]; - ptr[6] = t.basis.elements[1][2]; - ptr[7] = t.origin.y; - ptr[8] = t.basis.elements[2][0]; - ptr[9] = t.basis.elements[2][1]; - ptr[10] = t.basis.elements[2][2]; - ptr[11] = t.origin.z; - } else { - zeromem(ptr, sizeof(float) * 12); - } + if (!local_coords) { + t = inv_emission_transform * t; + } - Color c = r[idx].color; + if (r[idx].active) { + ptr[0] = t.basis.elements[0][0]; + ptr[1] = t.basis.elements[0][1]; + ptr[2] = t.basis.elements[0][2]; + ptr[3] = t.origin.x; + ptr[4] = t.basis.elements[1][0]; + ptr[5] = t.basis.elements[1][1]; + ptr[6] = t.basis.elements[1][2]; + ptr[7] = t.origin.y; + ptr[8] = t.basis.elements[2][0]; + ptr[9] = t.basis.elements[2][1]; + ptr[10] = t.basis.elements[2][2]; + ptr[11] = t.origin.z; + } else { + zeromem(ptr, sizeof(float) * 12); + } - ptr[12] = c.r; - ptr[13] = c.g; - ptr[14] = c.b; - ptr[15] = c.a; + Color c = r[idx].color; - ptr[16] = r[idx].custom[0]; - ptr[17] = r[idx].custom[1]; - ptr[18] = r[idx].custom[2]; - ptr[19] = r[idx].custom[3]; + ptr[12] = c.r; + ptr[13] = c.g; + ptr[14] = c.b; + ptr[15] = c.a; - ptr += 20; - } + ptr[16] = r[idx].custom[0]; + ptr[17] = r[idx].custom[1]; + ptr[18] = r[idx].custom[2]; + ptr[19] = r[idx].custom[3]; - can_update = true; + ptr += 20; } -#ifndef NO_THREADS - update_mutex->unlock(); -#endif + can_update = true; } void CPUParticles::_set_redraw(bool p_redraw) { if (redraw == p_redraw) return; redraw = p_redraw; -#ifndef NO_THREADS - update_mutex->lock(); -#endif - if (redraw) { - VS::get_singleton()->connect_compat("frame_pre_draw", this, "_update_render_thread"); - VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, true); - VS::get_singleton()->multimesh_set_visible_instances(multimesh, -1); - } else { - if (VS::get_singleton()->is_connected_compat("frame_pre_draw", this, "_update_render_thread")) { - VS::get_singleton()->disconnect_compat("frame_pre_draw", this, "_update_render_thread"); + + { + MutexLock lock(update_mutex); + + if (redraw) { + VS::get_singleton()->connect_compat("frame_pre_draw", this, "_update_render_thread"); + VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, true); + VS::get_singleton()->multimesh_set_visible_instances(multimesh, -1); + } else { + if (VS::get_singleton()->is_connected_compat("frame_pre_draw", this, "_update_render_thread")) { + VS::get_singleton()->disconnect_compat("frame_pre_draw", this, "_update_render_thread"); + } + VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, false); + VS::get_singleton()->multimesh_set_visible_instances(multimesh, 0); } - VS::get_singleton()->instance_geometry_set_flag(get_instance(), VS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, false); - VS::get_singleton()->multimesh_set_visible_instances(multimesh, 0); } -#ifndef NO_THREADS - update_mutex->unlock(); -#endif } void CPUParticles::_update_render_thread() { -#ifndef NO_THREADS - update_mutex->lock(); -#endif + MutexLock lock(update_mutex); + if (can_update) { VS::get_singleton()->multimesh_set_buffer(multimesh, particle_data); can_update = false; //wait for next time } - -#ifndef NO_THREADS - update_mutex->unlock(); -#endif } void CPUParticles::_notification(int p_what) { @@ -1556,16 +1541,8 @@ CPUParticles::CPUParticles() { can_update = false; set_color(Color(1, 1, 1, 1)); - -#ifndef NO_THREADS - update_mutex = Mutex::create(); -#endif } CPUParticles::~CPUParticles() { VS::get_singleton()->free(multimesh); - -#ifndef NO_THREADS - memdelete(update_mutex); -#endif } diff --git a/scene/3d/cpu_particles.h b/scene/3d/cpu_particles.h index 1a5537e4f2..231e1f1ad9 100644 --- a/scene/3d/cpu_particles.h +++ b/scene/3d/cpu_particles.h @@ -178,7 +178,7 @@ private: void _particles_process(float p_delta); void _update_particle_data_buffer(); - Mutex *update_mutex; + Mutex update_mutex; void _update_render_thread(); diff --git a/scene/3d/navigation.h b/scene/3d/navigation.h index 85887651ff..08f306611f 100644 --- a/scene/3d/navigation.h +++ b/scene/3d/navigation.h @@ -31,7 +31,7 @@ #ifndef NAVIGATION_H #define NAVIGATION_H -#include "scene/3d/navigation_mesh_instance.h" +#include "scene/3d/navigation_region.h" #include "scene/3d/spatial.h" class Navigation : public Spatial { diff --git a/scene/3d/navigation_mesh_instance.cpp b/scene/3d/navigation_region.cpp index 8f8574ba2d..d96d095797 100644 --- a/scene/3d/navigation_mesh_instance.cpp +++ b/scene/3d/navigation_region.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* navigation_mesh_instance.cpp */ +/* navigation_region.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,13 +28,13 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "navigation_mesh_instance.h" +#include "navigation_region.h" #include "core/os/thread.h" #include "mesh_instance.h" #include "navigation.h" #include "servers/navigation_server.h" -void NavigationMeshInstance::set_enabled(bool p_enabled) { +void NavigationRegion::set_enabled(bool p_enabled) { if (enabled == p_enabled) return; @@ -66,14 +66,14 @@ void NavigationMeshInstance::set_enabled(bool p_enabled) { update_gizmo(); } -bool NavigationMeshInstance::is_enabled() const { +bool NavigationRegion::is_enabled() const { return enabled; } ///////////////////////////// -void NavigationMeshInstance::_notification(int p_what) { +void NavigationRegion::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { @@ -129,7 +129,7 @@ void NavigationMeshInstance::_notification(int p_what) { } } -void NavigationMeshInstance::set_navigation_mesh(const Ref<NavigationMesh> &p_navmesh) { +void NavigationRegion::set_navigation_mesh(const Ref<NavigationMesh> &p_navmesh) { if (p_navmesh == navmesh) return; @@ -156,13 +156,13 @@ void NavigationMeshInstance::set_navigation_mesh(const Ref<NavigationMesh> &p_na update_configuration_warning(); } -Ref<NavigationMesh> NavigationMeshInstance::get_navigation_mesh() const { +Ref<NavigationMesh> NavigationRegion::get_navigation_mesh() const { return navmesh; } struct BakeThreadsArgs { - NavigationMeshInstance *nav_mesh_instance; + NavigationRegion *nav_mesh_instance; }; void _bake_navigation_mesh(void *p_user_data) { @@ -182,7 +182,7 @@ void _bake_navigation_mesh(void *p_user_data) { } } -void NavigationMeshInstance::bake_navigation_mesh() { +void NavigationRegion::bake_navigation_mesh() { ERR_FAIL_COND(bake_thread != NULL); BakeThreadsArgs *args = memnew(BakeThreadsArgs); @@ -192,12 +192,12 @@ void NavigationMeshInstance::bake_navigation_mesh() { ERR_FAIL_COND(bake_thread == NULL); } -void NavigationMeshInstance::_bake_finished(Ref<NavigationMesh> p_nav_mesh) { +void NavigationRegion::_bake_finished(Ref<NavigationMesh> p_nav_mesh) { set_navigation_mesh(p_nav_mesh); bake_thread = NULL; } -String NavigationMeshInstance::get_configuration_warning() const { +String NavigationRegion::get_configuration_warning() const { if (!is_visible_in_tree() || !is_inside_tree()) return String(); @@ -214,19 +214,19 @@ String NavigationMeshInstance::get_configuration_warning() const { c = Object::cast_to<Spatial>(c->get_parent()); } - return TTR("NavigationMeshInstance must be a child or grandchild to a Navigation node. It only provides navigation data."); + return TTR("NavigationRegion must be a child or grandchild to a Navigation node. It only provides navigation data."); } -void NavigationMeshInstance::_bind_methods() { +void NavigationRegion::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_navigation_mesh", "navmesh"), &NavigationMeshInstance::set_navigation_mesh); - ClassDB::bind_method(D_METHOD("get_navigation_mesh"), &NavigationMeshInstance::get_navigation_mesh); + ClassDB::bind_method(D_METHOD("set_navigation_mesh", "navmesh"), &NavigationRegion::set_navigation_mesh); + ClassDB::bind_method(D_METHOD("get_navigation_mesh"), &NavigationRegion::get_navigation_mesh); - ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &NavigationMeshInstance::set_enabled); - ClassDB::bind_method(D_METHOD("is_enabled"), &NavigationMeshInstance::is_enabled); + ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &NavigationRegion::set_enabled); + ClassDB::bind_method(D_METHOD("is_enabled"), &NavigationRegion::is_enabled); - ClassDB::bind_method(D_METHOD("bake_navigation_mesh"), &NavigationMeshInstance::bake_navigation_mesh); - ClassDB::bind_method(D_METHOD("_bake_finished", "nav_mesh"), &NavigationMeshInstance::_bake_finished); + ClassDB::bind_method(D_METHOD("bake_navigation_mesh"), &NavigationRegion::bake_navigation_mesh); + ClassDB::bind_method(D_METHOD("_bake_finished", "nav_mesh"), &NavigationRegion::_bake_finished); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "navmesh", PROPERTY_HINT_RESOURCE_TYPE, "NavigationMesh"), "set_navigation_mesh", "get_navigation_mesh"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled"); @@ -235,12 +235,12 @@ void NavigationMeshInstance::_bind_methods() { ADD_SIGNAL(MethodInfo("bake_finished")); } -void NavigationMeshInstance::_changed_callback(Object *p_changed, const char *p_prop) { +void NavigationRegion::_changed_callback(Object *p_changed, const char *p_prop) { update_gizmo(); update_configuration_warning(); } -NavigationMeshInstance::NavigationMeshInstance() { +NavigationRegion::NavigationRegion() { enabled = true; set_notify_transform(true); @@ -251,7 +251,7 @@ NavigationMeshInstance::NavigationMeshInstance() { bake_thread = NULL; } -NavigationMeshInstance::~NavigationMeshInstance() { +NavigationRegion::~NavigationRegion() { if (navmesh.is_valid()) navmesh->remove_change_receptor(this); NavigationServer::get_singleton()->free(region); diff --git a/scene/3d/navigation_mesh_instance.h b/scene/3d/navigation_region.h index 1135bf47d2..f215e92c97 100644 --- a/scene/3d/navigation_mesh_instance.h +++ b/scene/3d/navigation_region.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* navigation_mesh_instance.h */ +/* navigation_region.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef NAVIGATION_MESH_INSTANCE_H -#define NAVIGATION_MESH_INSTANCE_H +#ifndef NAVIGATION_REGION_H +#define NAVIGATION_REGION_H #include "scene/3d/spatial.h" #include "scene/resources/mesh.h" @@ -37,9 +37,9 @@ class Navigation; -class NavigationMeshInstance : public Spatial { +class NavigationRegion : public Spatial { - GDCLASS(NavigationMeshInstance, Spatial); + GDCLASS(NavigationRegion, Spatial); bool enabled; RID region; @@ -68,8 +68,8 @@ public: String get_configuration_warning() const; - NavigationMeshInstance(); - ~NavigationMeshInstance(); + NavigationRegion(); + ~NavigationRegion(); }; -#endif // NAVIGATION_MESH_INSTANCE_H +#endif // NAVIGATION_REGION_H diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 6288598ce2..dd00565929 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -151,7 +151,6 @@ #include "scene/resources/packed_scene.h" #include "scene/resources/particles_material.h" #include "scene/resources/physics_material.h" -#include "scene/resources/plane_shape.h" #include "scene/resources/polygon_path_finder.h" #include "scene/resources/primitive_meshes.h" #include "scene/resources/ray_shape.h" @@ -169,6 +168,7 @@ #include "scene/resources/visual_shader_nodes.h" #include "scene/resources/world.h" #include "scene/resources/world_2d.h" +#include "scene/resources/world_margin_shape.h" #include "scene/scene_string_names.h" #ifndef _3D_DISABLED @@ -190,8 +190,8 @@ #include "scene/3d/multimesh_instance.h" #include "scene/3d/navigation.h" #include "scene/3d/navigation_agent.h" -#include "scene/3d/navigation_mesh_instance.h" #include "scene/3d/navigation_obstacle.h" +#include "scene/3d/navigation_region.h" #include "scene/3d/particles.h" #include "scene/3d/path.h" #include "scene/3d/physics_body.h" @@ -470,7 +470,7 @@ void register_scene_types() { ClassDB::register_class<Generic6DOFJoint>(); ClassDB::register_class<Navigation>(); - ClassDB::register_class<NavigationMeshInstance>(); + ClassDB::register_class<NavigationRegion>(); ClassDB::register_class<NavigationAgent>(); ClassDB::register_class<NavigationObstacle>(); @@ -643,7 +643,7 @@ void register_scene_types() { ClassDB::register_class<CapsuleShape>(); ClassDB::register_class<CylinderShape>(); ClassDB::register_class<HeightMapShape>(); - ClassDB::register_class<PlaneShape>(); + ClassDB::register_class<WorldMarginShape>(); ClassDB::register_class<ConvexPolygonShape>(); ClassDB::register_class<ConcavePolygonShape>(); @@ -726,7 +726,7 @@ void register_scene_types() { ClassDB::register_class<Navigation2D>(); ClassDB::register_class<NavigationPolygon>(); - ClassDB::register_class<NavigationPolygonInstance>(); + ClassDB::register_class<NavigationRegion2D>(); ClassDB::register_class<NavigationAgent2D>(); ClassDB::register_class<NavigationObstacle2D>(); @@ -746,6 +746,9 @@ void register_scene_types() { ClassDB::add_compatibility_class("VisualShaderNodeScalarUniform", "VisualShaderNodeFloatUniform"); ClassDB::add_compatibility_class("VisualShaderNodeScalarOp", "VisualShaderNodeFloatOp"); ClassDB::add_compatibility_class("VisualShaderNodeScalarFunc", "VisualShaderNodeFloatFunc"); + ClassDB::add_compatibility_class("NavigationMeshInstance", "NavigationRegion"); + ClassDB::add_compatibility_class("NavigationPolygonInstance", "NavigationRegion2D"); + ClassDB::add_compatibility_class("PlaneShape", "WorldMarginShape"); #endif OS::get_singleton()->yield(); //may take time to init diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp index 79a1500129..fc53dfe376 100644 --- a/scene/resources/dynamic_font.cpp +++ b/scene/resources/dynamic_font.cpp @@ -990,7 +990,7 @@ void DynamicFont::_bind_methods() { BIND_ENUM_CONSTANT(SPACING_SPACE); } -Mutex *DynamicFont::dynamic_font_mutex = NULL; +Mutex DynamicFont::dynamic_font_mutex; SelfList<DynamicFont>::List *DynamicFont::dynamic_fonts = NULL; @@ -1004,29 +1004,21 @@ DynamicFont::DynamicFont() : spacing_char = 0; spacing_space = 0; outline_color = Color(1, 1, 1); - if (dynamic_font_mutex) { - dynamic_font_mutex->lock(); - dynamic_fonts->add(&font_list); - dynamic_font_mutex->unlock(); - } + + MutexLock lock(dynamic_font_mutex); + dynamic_fonts->add(&font_list); } DynamicFont::~DynamicFont() { - if (dynamic_font_mutex) { - dynamic_font_mutex->lock(); - dynamic_fonts->remove(&font_list); - dynamic_font_mutex->unlock(); - } + MutexLock lock(dynamic_font_mutex); + dynamic_fonts->remove(&font_list); } void DynamicFont::initialize_dynamic_fonts() { dynamic_fonts = memnew(SelfList<DynamicFont>::List()); - dynamic_font_mutex = Mutex::create(); } void DynamicFont::finish_dynamic_fonts() { - memdelete(dynamic_font_mutex); - dynamic_font_mutex = NULL; memdelete(dynamic_fonts); dynamic_fonts = NULL; } @@ -1034,39 +1026,36 @@ void DynamicFont::finish_dynamic_fonts() { void DynamicFont::update_oversampling() { Vector<Ref<DynamicFont> > changed; + { + MutexLock lock(dynamic_font_mutex); - if (dynamic_font_mutex) - dynamic_font_mutex->lock(); - - SelfList<DynamicFont> *E = dynamic_fonts->first(); - while (E) { + SelfList<DynamicFont> *E = dynamic_fonts->first(); + while (E) { - if (E->self()->data_at_size.is_valid()) { - E->self()->data_at_size->update_oversampling(); + if (E->self()->data_at_size.is_valid()) { + E->self()->data_at_size->update_oversampling(); - if (E->self()->outline_data_at_size.is_valid()) { - E->self()->outline_data_at_size->update_oversampling(); - } + if (E->self()->outline_data_at_size.is_valid()) { + E->self()->outline_data_at_size->update_oversampling(); + } - for (int i = 0; i < E->self()->fallback_data_at_size.size(); i++) { - if (E->self()->fallback_data_at_size[i].is_valid()) { - E->self()->fallback_data_at_size.write[i]->update_oversampling(); + for (int i = 0; i < E->self()->fallback_data_at_size.size(); i++) { + if (E->self()->fallback_data_at_size[i].is_valid()) { + E->self()->fallback_data_at_size.write[i]->update_oversampling(); - if (E->self()->has_outline() && E->self()->fallback_outline_data_at_size[i].is_valid()) { - E->self()->fallback_outline_data_at_size.write[i]->update_oversampling(); + if (E->self()->has_outline() && E->self()->fallback_outline_data_at_size[i].is_valid()) { + E->self()->fallback_outline_data_at_size.write[i]->update_oversampling(); + } } } + + changed.push_back(Ref<DynamicFont>(E->self())); } - changed.push_back(Ref<DynamicFont>(E->self())); + E = E->next(); } - - E = E->next(); } - if (dynamic_font_mutex) - dynamic_font_mutex->unlock(); - for (int i = 0; i < changed.size(); i++) { changed.write[i]->emit_changed(); } diff --git a/scene/resources/dynamic_font.h b/scene/resources/dynamic_font.h index fa6db370f8..6a0b51fb93 100644 --- a/scene/resources/dynamic_font.h +++ b/scene/resources/dynamic_font.h @@ -285,7 +285,7 @@ public: SelfList<DynamicFont> font_list; - static Mutex *dynamic_font_mutex; + static Mutex dynamic_font_mutex; static SelfList<DynamicFont>::List *dynamic_fonts; static void initialize_dynamic_fonts(); diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index ff51cab0a4..54e9067abb 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -290,17 +290,13 @@ ShaderMaterial::~ShaderMaterial() { ///////////////////////////////// -Mutex *BaseMaterial3D::material_mutex = NULL; +Mutex BaseMaterial3D::material_mutex; SelfList<BaseMaterial3D>::List *BaseMaterial3D::dirty_materials = NULL; Map<BaseMaterial3D::MaterialKey, BaseMaterial3D::ShaderData> BaseMaterial3D::shader_map; BaseMaterial3D::ShaderNames *BaseMaterial3D::shader_names = NULL; void BaseMaterial3D::init_shaders() { -#ifndef NO_THREADS - material_mutex = Mutex::create(); -#endif - dirty_materials = memnew(SelfList<BaseMaterial3D>::List); shader_names = memnew(ShaderNames); @@ -379,10 +375,6 @@ void BaseMaterial3D::finish_shaders() { materials_for_2d[i].unref(); } -#ifndef NO_THREADS - memdelete(material_mutex); -#endif - memdelete(dirty_materials); dirty_materials = NULL; @@ -1133,44 +1125,28 @@ void BaseMaterial3D::_update_shader() { void BaseMaterial3D::flush_changes() { - if (material_mutex) - material_mutex->lock(); + MutexLock lock(material_mutex); while (dirty_materials->first()) { dirty_materials->first()->self()->_update_shader(); } - - if (material_mutex) - material_mutex->unlock(); } void BaseMaterial3D::_queue_shader_change() { - if (material_mutex) - material_mutex->lock(); + MutexLock lock(material_mutex); if (!element.in_list()) { dirty_materials->add(&element); } - - if (material_mutex) - material_mutex->unlock(); } bool BaseMaterial3D::_is_shader_dirty() const { - bool dirty = false; - - if (material_mutex) - material_mutex->lock(); - - dirty = element.in_list(); + MutexLock lock(material_mutex); - if (material_mutex) - material_mutex->unlock(); - - return dirty; + return element.in_list(); } void BaseMaterial3D::set_albedo(const Color &p_albedo) { @@ -2580,8 +2556,7 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) : BaseMaterial3D::~BaseMaterial3D() { - if (material_mutex) - material_mutex->lock(); + MutexLock lock(material_mutex); if (shader_map.has(current_key)) { shader_map[current_key].users--; @@ -2593,9 +2568,6 @@ BaseMaterial3D::~BaseMaterial3D() { VS::get_singleton()->material_set_shader(_get_material(), RID()); } - - if (material_mutex) - material_mutex->unlock(); } ////////////////////// diff --git a/scene/resources/material.h b/scene/resources/material.h index 927334c74d..fc77226fb9 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -388,7 +388,7 @@ private: StringName texture_names[TEXTURE_MAX]; }; - static Mutex *material_mutex; + static Mutex material_mutex; static SelfList<BaseMaterial3D>::List *dirty_materials; static ShaderNames *shader_names; diff --git a/scene/resources/mesh_library.h b/scene/resources/mesh_library.h index 9155975f47..b256e86b96 100644 --- a/scene/resources/mesh_library.h +++ b/scene/resources/mesh_library.h @@ -34,7 +34,7 @@ #include "core/map.h" #include "core/resource.h" #include "mesh.h" -#include "scene/3d/navigation_mesh_instance.h" +#include "scene/3d/navigation_region.h" #include "shape.h" class MeshLibrary : public Resource { diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp index e820aec2ed..f18e8956f1 100644 --- a/scene/resources/particles_material.cpp +++ b/scene/resources/particles_material.cpp @@ -30,17 +30,13 @@ #include "particles_material.h" -Mutex *ParticlesMaterial::material_mutex = NULL; +Mutex ParticlesMaterial::material_mutex; SelfList<ParticlesMaterial>::List *ParticlesMaterial::dirty_materials = NULL; Map<ParticlesMaterial::MaterialKey, ParticlesMaterial::ShaderData> ParticlesMaterial::shader_map; ParticlesMaterial::ShaderNames *ParticlesMaterial::shader_names = NULL; void ParticlesMaterial::init_shaders() { -#ifndef NO_THREADS - material_mutex = Mutex::create(); -#endif - dirty_materials = memnew(SelfList<ParticlesMaterial>::List); shader_names = memnew(ShaderNames); @@ -107,10 +103,6 @@ void ParticlesMaterial::init_shaders() { void ParticlesMaterial::finish_shaders() { -#ifndef NO_THREADS - memdelete(material_mutex); -#endif - memdelete(dirty_materials); dirty_materials = NULL; @@ -612,44 +604,28 @@ void ParticlesMaterial::_update_shader() { void ParticlesMaterial::flush_changes() { - if (material_mutex) - material_mutex->lock(); + MutexLock lock(material_mutex); while (dirty_materials->first()) { dirty_materials->first()->self()->_update_shader(); } - - if (material_mutex) - material_mutex->unlock(); } void ParticlesMaterial::_queue_shader_change() { - if (material_mutex) - material_mutex->lock(); + MutexLock lock(material_mutex); if (!element.in_list()) { dirty_materials->add(&element); } - - if (material_mutex) - material_mutex->unlock(); } bool ParticlesMaterial::_is_shader_dirty() const { - bool dirty = false; + MutexLock lock(material_mutex); - if (material_mutex) - material_mutex->lock(); - - dirty = element.in_list(); - - if (material_mutex) - material_mutex->unlock(); - - return dirty; + return element.in_list(); } void ParticlesMaterial::set_direction(Vector3 p_direction) { @@ -1298,8 +1274,7 @@ ParticlesMaterial::ParticlesMaterial() : ParticlesMaterial::~ParticlesMaterial() { - if (material_mutex) - material_mutex->lock(); + MutexLock lock(material_mutex); if (shader_map.has(current_key)) { shader_map[current_key].users--; @@ -1311,7 +1286,4 @@ ParticlesMaterial::~ParticlesMaterial() { VS::get_singleton()->material_set_shader(_get_material(), RID()); } - - if (material_mutex) - material_mutex->unlock(); } diff --git a/scene/resources/particles_material.h b/scene/resources/particles_material.h index 246ce58a21..c6c8316995 100644 --- a/scene/resources/particles_material.h +++ b/scene/resources/particles_material.h @@ -126,7 +126,7 @@ private: return mk; } - static Mutex *material_mutex; + static Mutex material_mutex; static SelfList<ParticlesMaterial>::List *dirty_materials; struct ShaderNames { diff --git a/scene/resources/plane_shape.cpp b/scene/resources/world_margin_shape.cpp index ddc820233e..b5b701327c 100644 --- a/scene/resources/plane_shape.cpp +++ b/scene/resources/world_margin_shape.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* plane_shape.cpp */ +/* world_margin_shape.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,11 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "plane_shape.h" +#include "world_margin_shape.h" #include "servers/physics_server.h" -Vector<Vector3> PlaneShape::get_debug_mesh_lines() { +Vector<Vector3> WorldMarginShape::get_debug_mesh_lines() { Plane p = get_plane(); Vector<Vector3> points; @@ -61,13 +61,13 @@ Vector<Vector3> PlaneShape::get_debug_mesh_lines() { return points; } -void PlaneShape::_update_shape() { +void WorldMarginShape::_update_shape() { PhysicsServer::get_singleton()->shape_set_data(get_shape(), plane); Shape::_update_shape(); } -void PlaneShape::set_plane(Plane p_plane) { +void WorldMarginShape::set_plane(Plane p_plane) { plane = p_plane; _update_shape(); @@ -75,20 +75,20 @@ void PlaneShape::set_plane(Plane p_plane) { _change_notify("plane"); } -Plane PlaneShape::get_plane() const { +Plane WorldMarginShape::get_plane() const { return plane; } -void PlaneShape::_bind_methods() { +void WorldMarginShape::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_plane", "plane"), &PlaneShape::set_plane); - ClassDB::bind_method(D_METHOD("get_plane"), &PlaneShape::get_plane); + ClassDB::bind_method(D_METHOD("set_plane", "plane"), &WorldMarginShape::set_plane); + ClassDB::bind_method(D_METHOD("get_plane"), &WorldMarginShape::get_plane); ADD_PROPERTY(PropertyInfo(Variant::PLANE, "plane"), "set_plane", "get_plane"); } -PlaneShape::PlaneShape() : +WorldMarginShape::WorldMarginShape() : Shape(PhysicsServer::get_singleton()->shape_create(PhysicsServer::SHAPE_PLANE)) { set_plane(Plane(0, 1, 0, 0)); diff --git a/scene/resources/plane_shape.h b/scene/resources/world_margin_shape.h index 360f9dbbe9..78ea570212 100644 --- a/scene/resources/plane_shape.h +++ b/scene/resources/world_margin_shape.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* plane_shape.h */ +/* world_margin_shape.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,14 +28,14 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef PLANE_SHAPE_H -#define PLANE_SHAPE_H +#ifndef WORLD_MARGIN_SHAPE_H +#define WORLD_MARGIN_SHAPE_H #include "scene/resources/shape.h" -class PlaneShape : public Shape { +class WorldMarginShape : public Shape { - GDCLASS(PlaneShape, Shape); + GDCLASS(WorldMarginShape, Shape); Plane plane; protected: @@ -52,6 +52,6 @@ public: return 0; } - PlaneShape(); + WorldMarginShape(); }; -#endif // PLANE_SHAPE_H +#endif // WORLD_MARGIN_SHAPE_H diff --git a/servers/audio/audio_driver_dummy.cpp b/servers/audio/audio_driver_dummy.cpp index 5389c64099..69b098edfc 100644 --- a/servers/audio/audio_driver_dummy.cpp +++ b/servers/audio/audio_driver_dummy.cpp @@ -49,7 +49,6 @@ Error AudioDriverDummy::init() { samples_in = memnew_arr(int32_t, buffer_frames * channels); - mutex = Mutex::create(); thread = Thread::create(AudioDriverDummy::thread_func, this); return OK; @@ -95,16 +94,16 @@ AudioDriver::SpeakerMode AudioDriverDummy::get_speaker_mode() const { void AudioDriverDummy::lock() { - if (!thread || !mutex) + if (!thread) return; - mutex->lock(); + mutex.lock(); }; void AudioDriverDummy::unlock() { - if (!thread || !mutex) + if (!thread) return; - mutex->unlock(); + mutex.unlock(); }; void AudioDriverDummy::finish() { @@ -120,14 +119,11 @@ void AudioDriverDummy::finish() { }; memdelete(thread); - if (mutex) - memdelete(mutex); thread = NULL; }; AudioDriverDummy::AudioDriverDummy() { - mutex = NULL; thread = NULL; }; diff --git a/servers/audio/audio_driver_dummy.h b/servers/audio/audio_driver_dummy.h index ba99e5a239..a2cd9b2dc6 100644 --- a/servers/audio/audio_driver_dummy.h +++ b/servers/audio/audio_driver_dummy.h @@ -39,7 +39,7 @@ class AudioDriverDummy : public AudioDriver { Thread *thread; - Mutex *mutex; + Mutex mutex; int32_t *samples_in; diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp index abf351135a..caee5f5db5 100644 --- a/servers/audio_server.cpp +++ b/servers/audio_server.cpp @@ -1137,27 +1137,28 @@ void *AudioServer::audio_data_alloc(uint32_t p_data_len, const uint8_t *p_from_d copymem(ad, p_from_data, p_data_len); } - audio_data_lock->lock(); - audio_data[ad] = p_data_len; - audio_data_total_mem += p_data_len; - audio_data_max_mem = MAX(audio_data_total_mem, audio_data_max_mem); - audio_data_lock->unlock(); + { + MutexLock lock(audio_data_lock); + + audio_data[ad] = p_data_len; + audio_data_total_mem += p_data_len; + audio_data_max_mem = MAX(audio_data_total_mem, audio_data_max_mem); + } return ad; } void AudioServer::audio_data_free(void *p_data) { - audio_data_lock->lock(); + MutexLock lock(audio_data_lock); + if (!audio_data.has(p_data)) { - audio_data_lock->unlock(); ERR_FAIL(); } audio_data_total_mem -= audio_data[p_data]; audio_data.erase(p_data); memfree(p_data); - audio_data_lock->unlock(); } size_t AudioServer::audio_data_get_total_memory_usage() const { @@ -1399,7 +1400,6 @@ AudioServer::AudioServer() { singleton = this; audio_data_total_mem = 0; audio_data_max_mem = 0; - audio_data_lock = Mutex::create(); mix_frames = 0; channel_count = 0; to_mix = 0; @@ -1413,7 +1413,6 @@ AudioServer::AudioServer() { AudioServer::~AudioServer() { - memdelete(audio_data_lock); singleton = NULL; } diff --git a/servers/audio_server.h b/servers/audio_server.h index 1d9e5100fa..cc0c9d1112 100644 --- a/servers/audio_server.h +++ b/servers/audio_server.h @@ -238,7 +238,7 @@ private: size_t audio_data_total_mem; size_t audio_data_max_mem; - Mutex *audio_data_lock; + Mutex audio_data_lock; void init_channels_and_buffers(); diff --git a/servers/navigation_server.h b/servers/navigation_server.h index 2587e53ab2..7c9b6ba595 100644 --- a/servers/navigation_server.h +++ b/servers/navigation_server.h @@ -37,7 +37,7 @@ #include "core/object.h" #include "core/rid.h" -#include "scene/3d/navigation_mesh_instance.h" +#include "scene/3d/navigation_region.h" /// This server uses the concept of internal mutability. /// All the constant functions can be called in multithread because internally diff --git a/servers/physics_2d/physics_2d_server_wrap_mt.cpp b/servers/physics_2d/physics_2d_server_wrap_mt.cpp index 291693de39..7070902f77 100644 --- a/servers/physics_2d/physics_2d_server_wrap_mt.cpp +++ b/servers/physics_2d/physics_2d_server_wrap_mt.cpp @@ -160,7 +160,6 @@ Physics2DServerWrapMT::Physics2DServerWrapMT(Physics2DServer *p_contained, bool step_sem = NULL; step_pending = 0; step_thread_up = false; - alloc_mutex = Mutex::create(); pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc"); @@ -177,6 +176,5 @@ Physics2DServerWrapMT::Physics2DServerWrapMT(Physics2DServer *p_contained, bool Physics2DServerWrapMT::~Physics2DServerWrapMT() { memdelete(physics_2d_server); - memdelete(alloc_mutex); //finish(); } diff --git a/servers/physics_2d/physics_2d_server_wrap_mt.h b/servers/physics_2d/physics_2d_server_wrap_mt.h index 9a01344390..0648b8651f 100644 --- a/servers/physics_2d/physics_2d_server_wrap_mt.h +++ b/servers/physics_2d/physics_2d_server_wrap_mt.h @@ -67,7 +67,7 @@ class Physics2DServerWrapMT : public Physics2DServer { bool first_frame; - Mutex *alloc_mutex; + Mutex alloc_mutex; int pool_max_size; public: diff --git a/servers/server_wrap_mt_common.h b/servers/server_wrap_mt_common.h index f01e0b9578..4481b296c6 100644 --- a/servers/server_wrap_mt_common.h +++ b/servers/server_wrap_mt_common.h @@ -57,7 +57,7 @@ virtual RID m_type##_create() { \ if (Thread::get_caller_id() != server_thread) { \ RID rid; \ - alloc_mutex->lock(); \ + MutexLock lock(alloc_mutex); \ if (m_type##_id_pool.size() == 0) { \ int ret; \ command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, &ret); \ @@ -65,7 +65,6 @@ } \ rid = m_type##_id_pool.front()->get(); \ m_type##_id_pool.pop_front(); \ - alloc_mutex->unlock(); \ return rid; \ } else { \ return server_name->m_type##_create(); \ @@ -88,7 +87,7 @@ virtual RID m_type##_create(m_arg1 p1) { \ if (Thread::get_caller_id() != server_thread) { \ RID rid; \ - alloc_mutex->lock(); \ + MutexLock lock(alloc_mutex); \ if (m_type##_id_pool.size() == 0) { \ int ret; \ command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, p1, &ret); \ @@ -96,7 +95,6 @@ } \ rid = m_type##_id_pool.front()->get(); \ m_type##_id_pool.pop_front(); \ - alloc_mutex->unlock(); \ return rid; \ } else { \ return server_name->m_type##_create(p1); \ @@ -119,7 +117,7 @@ virtual RID m_type##_create(m_arg1 p1, m_arg2 p2) { \ if (Thread::get_caller_id() != server_thread) { \ RID rid; \ - alloc_mutex->lock(); \ + MutexLock lock(alloc_mutex); \ if (m_type##_id_pool.size() == 0) { \ int ret; \ command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, p1, p2, &ret); \ @@ -127,7 +125,6 @@ } \ rid = m_type##_id_pool.front()->get(); \ m_type##_id_pool.pop_front(); \ - alloc_mutex->unlock(); \ return rid; \ } else { \ return server_name->m_type##_create(p1, p2); \ @@ -150,7 +147,7 @@ virtual RID m_type##_create(m_arg1 p1, m_arg2 p2, m_arg3 p3) { \ if (Thread::get_caller_id() != server_thread) { \ RID rid; \ - alloc_mutex->lock(); \ + MutexLock lock(alloc_mutex); \ if (m_type##_id_pool.size() == 0) { \ int ret; \ command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, p1, p2, p3, &ret); \ @@ -158,7 +155,6 @@ } \ rid = m_type##_id_pool.front()->get(); \ m_type##_id_pool.pop_front(); \ - alloc_mutex->unlock(); \ return rid; \ } else { \ return server_name->m_type##_create(p1, p2, p3); \ @@ -181,7 +177,7 @@ virtual RID m_type##_create(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4) { \ if (Thread::get_caller_id() != server_thread) { \ RID rid; \ - alloc_mutex->lock(); \ + MutexLock lock(alloc_mutex); \ if (m_type##_id_pool.size() == 0) { \ int ret; \ command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, p1, p2, p3, p4, &ret); \ @@ -189,7 +185,6 @@ } \ rid = m_type##_id_pool.front()->get(); \ m_type##_id_pool.pop_front(); \ - alloc_mutex->unlock(); \ return rid; \ } else { \ return server_name->m_type##_create(p1, p2, p3, p4); \ @@ -213,7 +208,7 @@ virtual RID m_type##_create(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5) { \ if (Thread::get_caller_id() != server_thread) { \ RID rid; \ - alloc_mutex->lock(); \ + MutexLock lock(alloc_mutex); \ if (m_type##_id_pool.size() == 0) { \ int ret; \ command_queue.push_and_ret(this, &ServerNameWrapMT::m_type##allocn, p1, p2, p3, p4, p5, &ret); \ @@ -221,7 +216,6 @@ } \ rid = m_type##_id_pool.front()->get(); \ m_type##_id_pool.pop_front(); \ - alloc_mutex->unlock(); \ return rid; \ } else { \ return server_name->m_type##_create(p1, p2, p3, p4, p5); \ diff --git a/servers/visual/rasterizer_rd/cubemap_coeffs.h b/servers/visual/rasterizer_rd/cubemap_coeffs.h new file mode 100644 index 0000000000..9d4117191b --- /dev/null +++ b/servers/visual/rasterizer_rd/cubemap_coeffs.h @@ -0,0 +1,28 @@ +// Copyright 2016 Activision Publishing, Inc. +// +// 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 CUBEMAP_COEFFS_H +#define CUBEMAP_COEFFS_H + +const float low_quality_coeffs[7][5][6][4] = { { { { 0.0002037563, 0.0045063655, -0.0016408688, 0.00012037493 }, { -9.1834951e-05, -0.008947532, -8.1524405e-05, -3.9080094e-05 }, { -2.6038267e-05, -6.8409667e-05, 7.2175702e-05, 0.25492775 }, { -9.9426044e-05, 0.0025427756, -0.00074437925, 1.1773191e-05 }, { -3.2668211e-05, 0.0026930659, -4.824934e-05, -0.0006835048 }, { -0.0002864144, -0.0032220854, 0.0021558286, -0.00014573736 } }, { { 0.00030683201, 0.0026819548, -0.00060011756, -0.0067169226 }, { -0.0030993251, 0.0098575575, 0.0022416671, -8.9075401e-05 }, { 0.00052405626, 0.00057860515, 0.00011654518, -0.048018609 }, { 0.00010850967, -0.0088443512, -0.0018168095, 8.6633128e-05 }, { 0.003333989, -0.0050956447, -8.0414612e-05, 0.0049721239 }, { -4.0961436e-05, -8.5486984e-05, 0.0058683066, 2.2978359e-05 } }, { { 0.99999993, 0.99998625, 0.99999847, 0.99997743 }, { 0.99999519, 0.99991138, 0.99999748, 1 }, { 0.99999986, 0.99999983, 0.99999999, 0.96576708 }, { 0.99999999, 0.99995765, 0.99999807, 1 }, { 0.99999444, 0.99998339, 1, 0.99998741 }, { 0.99999996, 0.99999481, 0.99998046, 0.99999999 } }, { { -0.32267524, -0.65409377, -1.4666488, 0.87153305 }, { -1.264365, 0.89880861, -1.2245906, -0.88501403 }, { -0.31118682, -0.086150323, -0.58811532, 1.1317711 }, { -1.2193493, 1.250379, -1.0871569, -0.12694096 }, { -0.4012249, -0.47436307, -0.59661001, 2.7313005 }, { -1.3109856, 0.60929855, 0.55672643, -0.39880018 } }, { { 0.93273157, 0.59530745, 1.1994788, 0.19102276 }, { 1.2272239, 0.23245736, 1.2577607, 2.5491008 }, { 1.1210098, 0.83074953, 1.3049282, -0.001940633 }, { 1.5839111, 0.10520816, 1.150458, 2.3251789 }, { 0.688692, 0.59807498, 1.3374877, 0.095746692 }, { 1.3054173, 0.36604721, 0.065870226, 1.6496907 } } }, { { { 0.10348445, -4.6771514e-07, -0.011513131, 8.8921052e-05 }, { -0.042152043, 0.013143535, 0.00029120107, 0.036661611 }, { -0.04516036, 0.011438473, -0.0099289792, -0.011707897 }, { -0.034779497, 0.0090981166, -5.4202726e-05, 0.038592793 }, { -0.0071967376, -0.0056614418, -0.012278945, 0.0056867462 }, { -0.037678514, 0.011570177, 0.00029044557, 0.038583909 } }, { { 0.048320869, 1.4603673e-05, 0.0092672368, 0.00033289199 }, { 0.0071001761, -0.0090106091, -0.0027305905, -0.00221479 }, { -0.0027204116, 0.00017921587, 0.015296357, -0.00010306185 }, { 0.0079350203, -0.014772431, -1.2410913e-05, -0.0062296897 }, { 0.025087691, 0.00086046427, 0.015034685, -0.00078224706 }, { 0.00074587265, -0.014602074, 0.00027338224, -0.012848552 } }, { { 0.99345662, 1, 0.99989078, 0.99999994 }, { 0.99908598, 0.99987302, 0.99999623, 0.99932528 }, { 0.99897605, 0.99993456, 0.9998337, 0.99993145 }, { 0.99936351, 0.99984949, 1, 0.9992356 }, { 0.99965935, 0.9999836, 0.99981158, 0.99998352 }, { 0.99928963, 0.99982644, 0.99999992, 0.99917276 } }, { { 3.6882765, 0.15963861, 0.55983965, 0.4075649 }, { 2.1169304, 0.56463157, 0.52957047, 2.0117964 }, { 3.1080461, 0.09682931, 0.42125986, 0.089254784 }, { 1.4247315, 0.48411378, -0.17039102, 1.7431674 }, { 4.0339531, 0.14046159, 0.89848909, 0.011661811 }, { 1.9787852, 0.61750145, 0.63514194, 1.9359003 } }, { { 0.030848793, 1.4472743, 1.4356825, 1.4078009 }, { 0.37639678, 1.0793106, 1.1945413, 0.43983395 }, { 0.27451605, 1.5256415, 1.016769, 1.4850575 }, { 0.54580883, 1.1332879, 3.1331784, 0.60772955 }, { 0.11785158, 1.3928946, 0.94998805, 1.0377182 }, { 0.2842108, 1.0026911, 1.9064553, 0.27147854 } } }, { { { -0.096789259, 0.10326967, 0.0011799959, -0.03077328 }, { 0.08342021, 0.033260738, -0.00045864451, -0.021450568 }, { -0.093369441, -0.05807574, -0.033745214, 0.023817208 }, { 0.056747754, 0.031140512, 0.00019362509, -0.023727797 }, { -0.084538386, -0.040545412, -0.0076838784, 0.03424599 }, { 0.074312056, 0.027619787, 0.0015509082, -0.031043528 } }, { { -0.0085160473, -0.012179292, 0.0049910118, 0.020224799 }, { 0.022559343, -0.016273333, -0.0069382139, 0.00058083224 }, { -0.001115062, 0.035002846, -0.0038974773, -0.039378629 }, { 0.0014921617, -0.00058523872, -0.0011606685, 0.02807528 }, { -0.021454809, 0.052957852, -0.0022083677, -0.027956663 }, { -0.016486487, -0.0040233682, 0.00029949558, 0.021924605 } }, { { 0.99526846, 0.99457883, 0.99998685, 0.99932175 }, { 0.99625908, 0.99931422, 0.99997583, 0.99976974 }, { 0.99563091, 0.99769836, 0.99942287, 0.99894047 }, { 0.99838743, 0.99951485, 0.99999931, 0.99932416 }, { 0.99618922, 0.99777329, 0.99996804, 0.99902234 }, { 0.99709875, 0.9996104, 0.99999875, 0.99927754 } }, { { 3.0342011, 4.8022834, 1.3814123, 1.5280754 }, { 2.9043837, 1.7325954, 1.422223, 2.0569263 }, { 3.0358722, 5.3331504, 1.5680146, 1.6079289 }, { 3.2062833, 1.5368069, 1.0484709, 1.5399477 }, { 2.4471653, 4.0916696, 1.5060688, 1.5807009 }, { 2.6932695, 1.5161537, 1.3991175, 1.6301918 } }, { { 0.50787578, 0.17735471, 1.4006765, 1.0878482 }, { 0.69514518, 1.6765187, 1.2224869, 1.3461327 }, { 0.71381288, 0.17509216, 1.2712934, 0.94575821 }, { 1.1817337, 1.796984, 1.8671538, 1.5708691 }, { 0.55621228, 0.38291359, 1.4128781, 0.82625349 }, { 0.72441647, 1.005794, 1.5522327, 1.6032524 } } }, { { { -0.00041301094, -0.095882618, 0.26932618, -0.25137214 }, { 0.13737415, -0.12694293, -0.0090389663, 0.07227623 }, { -0.005236407, -0.0072961249, 0.27776083, -0.19536433 }, { 0.12781899, -0.042881667, -0.095979169, 0.088937396 }, { 0.037496084, -0.090547583, 0.22112334, -0.21930294 }, { 0.13353408, -0.084346121, -0.011365728, 0.043459312 } }, { { -0.05799135, -0.048612281, 0.02422989, 0.015536268 }, { -0.083144241, 0.039381032, 0.018705957, 0.029297922 }, { 0.026364989, -0.041927591, 0.036718516, 0.0050376168 }, { -0.11562256, 0.043521976, -0.014481644, 0.01529188 }, { -0.047859898, -0.057779647, -0.053171395, -0.0063193506 }, { -0.028781196, 0.041145059, -0.00018523142, 0.053524246 } }, { { 0.998317, 0.99420489, 0.96274416, 0.96776581 }, { 0.98702349, 0.99112796, 0.99978417, 0.99695425 }, { 0.99963867, 0.99909401, 0.95994827, 0.9807178 }, { 0.98503489, 0.99813175, 0.99527799, 0.99591983 }, { 0.99815003, 0.99421459, 0.97379529, 0.97563635 }, { 0.99062621, 0.99558667, 0.99993539, 0.99762039 } }, { { 2.3221943, 2.5383575, 4.3177232, 4.2016467 }, { 3.1936529, 3.0443024, 2.548962, 2.7636456 }, { 2.5923827, 2.3497949, 4.2471014, 4.1975975 }, { 3.3748785, 3.2836577, 2.9220414, 2.7175317 }, { 2.3290083, 2.5560991, 4.3572168, 4.4372585 }, { 3.1512055, 3.2863613, 2.4475378, 2.3620003 } }, { { 0.62833231, 0.52378061, 0.55845033, 0.64883444 }, { 0.76905594, 1.1017801, 1.8714048, 1.5664383 }, { 1.5283278, 1.2423369, 0.62247385, 1.0341956 }, { 0.77484548, 1.6866409, 1.0307399, 1.4224643 }, { 0.85627405, 0.72516079, 0.70094339, 0.7547877 }, { 1.202842, 1.7650605, 1.5938526, 0.97031337 } } }, { { { -0.078108035, -0.049518839, 0.26950139, -0.51522828 }, { 0.43015518, -0.045354216, 0.094550359, -0.2395012 }, { -0.079900522, -0.082582235, 0.24464909, -0.5234896 }, { 0.38422945, -0.023833644, 0.07334288, -0.22827313 }, { -0.075370379, -0.05156594, 0.19883182, -0.45064193 }, { 0.46285395, 0.021899343, 0.10155287, -0.25974773 } }, { { 0.068681419, -0.32175988, 0.15143274, -0.0066205388 }, { -0.17060226, 0.31051319, -0.080511981, -0.1593209 }, { 0.08167251, -0.32517768, 0.10937023, -0.06941926 }, { -0.14580685, 0.32474959, -0.081718057, -0.11068378 }, { 0.053961394, -0.29322836, 0.10408839, -0.02243046 }, { -0.030598471, 0.34332821, -0.091528353, -0.16299796 } }, { { 0.99457629, 0.9455255, 0.95101899, 0.85702741 }, { 0.88648824, 0.94948647, 0.99225906, 0.95773484 }, { 0.99345131, 0.94204015, 0.96342357, 0.84919939 }, { 0.9116513, 0.94549969, 0.99395321, 0.96728511 }, { 0.99569447, 0.95465076, 0.97449039, 0.89242295 }, { 0.88590629, 0.93896015, 0.99061071, 0.95182077 } }, { { 3.6380949, 4.1749529, 4.1351439, 4.8389883 }, { 5.256362, 4.2027959, 3.6096892, 3.9848645 }, { 3.5689427, 3.8620869, 4.0023981, 4.8268584 }, { 5.1128497, 4.468934, 3.5851596, 4.047485 }, { 3.7014988, 4.1310058, 4.2446872, 5.3049323 }, { 4.8659881, 4.3133002, 3.4582876, 3.8863853 } }, { { 1.6276316, 0.7747672, 1.0485958, 0.73900224 }, { 0.72010795, 0.65403093, 1.3179681, 0.65610074 }, { 1.5881174, 0.55108527, 1.0509725, 0.72153362 }, { 1.1389053, 1.0905142, 1.6661598, 0.9987548 }, { 1.977914, 0.83001686, 1.0571479, 0.80249183 }, { 0.94107069, 0.80840873, 0.95379751, 0.50386367 } } }, { { { 0.015525428, -0.48038019, -0.021799698, 0.43629156 }, { 0.045681247, -0.55039024, -0.54573329, 0.57817853 }, { -0.045869129, -0.42209953, -0.14040829, 0.37787106 }, { 0.66327604, -0.70070311, -0.55261635, 0.63446196 }, { 0.015397585, -0.43515767, -0.021927897, 0.4203714 }, { 0.85681772, -0.65394729, -0.67557236, 0.60104142 } }, { { -0.31503888, -0.26745648, 0.26817896, 0.26548747 }, { -0.93282124, -0.033621213, 0.68374802, -0.10858524 }, { -0.21723689, -0.17935495, 0.38521982, 0.2578335 }, { -0.39913153, 0.23555359, 0.59589456, -0.19075103 }, { -0.28851798, -0.24142459, 0.28279261, 0.24766617 }, { -0.29435977, -0.25850549, 0.57790878, -0.200546 } }, { { 0.94895177, 0.83528552, 0.96312243, 0.85974768 }, { 0.35743218, 0.8342303, 0.48442112, 0.80865248 }, { 0.97504059, 0.88863029, 0.9120807, 0.88923301 }, { 0.63305523, 0.67344611, 0.58268761, 0.74904744 }, { 0.95735066, 0.86738225, 0.9589304, 0.87289711 }, { 0.42333878, 0.71100482, 0.45784651, 0.77364753 } }, { { 5.3641275, 5.2550422, 5.3103777, 5.2851215 }, { 5.2657045, 6.2095784, 6.9549598, 4.9205516 }, { 5.163385, 5.3141038, 4.9907618, 5.3583852 }, { 6.1257061, 6.1102338, 6.9549598, 5.3129951 }, { 5.3138838, 5.3257842, 5.3133783, 5.2687156 }, { 5.8915091, 6.153324, 6.9549598, 4.9568971 } }, { { 3.1221918, 1.1882615, 2.6991784, 1.1185048 }, { -0.2322432, -0.16590163, 0.088416958, 0.057399579 }, { 3.4395383, 1.5836276, 2.6242352, 1.2873336 }, { -0.23767634, -0.79425452, 0.20477899, 0.40461516 }, { 2.2521751, 1.1933374, 2.3309484, 1.0185309 }, { -0.099258385, -0.2173726, 0.0736866, 0.15470436 } } }, { { { 0.066050217, -0.33053278, -0.13771479, 0.33278465 }, { 0.00084467977, -0.50077778, -0.30083482, 0.6494273 }, { 0.24880159, -0.30354993, -0.15417892, 0.38203296 }, { -0.073325098, -0.4778777, 0.10779844, 0.66683723 }, { 0.15703809, -0.36335455, -0.15657631, 0.35926503 }, { 0.26127617, -0.29524368, -0.14490804, 0.65461301 } }, { { -0.57970022, -0.33939622, 0.72169742, 0.320959 }, { -0.38698206, -0.12730306, 0.65810895, 0.026509232 }, { -0.6199708, -0.34745658, 0.68683659, 0.34547285 }, { -0.3613378, -0.14006845, 0.65917895, 0.038446867 }, { -0.57778101, -0.35057776, 0.57837882, 0.36488991 }, { -0.50051482, -0.019174387, 0.50816239, 0.02682636 } }, { { 0.8121484, 0.88065787, 0.67837119, 0.88670158 }, { 0.92208686, 0.85616327, 0.69021085, -0.75996148 }, { 0.74413303, 0.88720424, 0.71027063, 0.85714604 }, { 0.92954743, 0.86718726, 0.74421946, -0.74421095 }, { 0.80094204, 0.86317363, 0.8006009, 0.85894353 }, { 0.82536033, 0.95522956, 0.8489833, -0.75548802 } }, { { 5.7725061, 5.1565901, 5.6224483, 5.0847054 }, { 5.7717118, 6.4180057, 6.9797014, -0.03290957 }, { 5.7847117, 5.2015529, 5.614561, 5.2019388 }, { 6.2613999, 6.5807982, 6.9797014, -0.032764603 }, { 5.823775, 5.2332343, 5.826694, 5.197143 }, { 6.3463188, 5.8174311, 6.9797014, -0.032766769 } }, { { 2.96787, 1.3557735, 2.0749129, 1.3066609 }, { -0.92782801, 0.0079162579, -0.33479446, 2.699659e-05 }, { 2.1997063, 3.1083252, 2.6810949, 1.8276262 }, { -0.48654719, -0.10954189, -0.32175132, 5.490092e-05 }, { 3.1970446, 1.787085, 3.062849, 1.6274811 }, { -0.78882801, -0.34050184, -0.59962127, 3.6554198e-05 } } } }; + +const float high_quality_coeffs[7][5][3][24][4] = { { { { { -4.8355339e-06, -4.4902569e-05, -9.2632249e-05, -0.00053773136 }, { 0.0040143823, -0.00060900339, -0.0095301923, -0.0053956011 }, { -0.0005923892, -3.6901978e-05, -5.6694857e-06, -0.00017018564 }, { 0.0012441402, 0.02236187, 0.022751769, 0.0062788948 }, { 0.00013810055, -2.2709815e-05, 0.0054849671, -1.6599195e-05 }, { -0.020320408, -0.017066319, -0.017457746, 0.022910628 }, { 0.00024171724, 9.7419073e-05, -0.00047804272, -0.00010093683 }, { 7.6988167e-05, 1.8551597e-05, -5.7692813e-05, -3.332362e-05 }, { -0.00062766208, 2.713742e-05, 0.00026511682, 2.3841873e-05 }, { -0.00043656844, 0.0028645469, 0.0049817085, 0.0080221478 }, { -3.3210444e-05, -8.0852386e-05, -2.2111492e-06, -8.4430827e-05 }, { 0.010967284, 0.018811225, 0.017569463, -0.0046944996 }, { -0.00018391248, -0.00010462174, -0.00017726, -0.00018490133 }, { 0.00012591989, 0.015965386, 0.015964059, -0.0078018431 }, { -0.006125333, -8.2224165e-05, -0.00020500151, -0.00025207244 }, { -0.00016320041, -0.0001279242, 0.00014038799, 8.1359421e-05 }, { -0.00064341098, -0.0011265496, -0.0011634792, -0.00081607159 }, { 0.00089294825, 0.0061923653, 0.0052662392, -0.00058227469 }, { -2.4001308e-05, -1.3534224e-05, -1.4720478e-05, -2.5120827e-05 }, { 0.00029964918, -0.0045658543, -0.0045581938, 0.0017106208 }, { 7.5790173e-05, -1.8265415e-05, 1.5918205e-05, 5.8524021e-05 }, { 0.0011669872, -0.00017571882, -0.00017190275, -0.0023833977 }, { 0.0033487264, -0.0066535821, -0.0066413786, -0.0032332601 }, { -3.6468807e-05, -0.00068145131, -9.8190714e-05, -8.7169435e-05 } }, { { -0.0010440653, -8.9750644e-05, 4.971182e-05, 0.0044618878 }, { 0.0078333883, -0.00090884312, -0.00046920549, -0.002465051 }, { -0.0058778609, 0.0026554895, -0.00031880506, -0.00010649091 }, { -0.0015095448, 0.0094026506, 0.009492703, 0.0024572848 }, { 0.0047331786, 0.00070722401, 0.0028798817, -0.00039779892 }, { -0.0089878107, -0.0095474878, -0.0097187652, 0.008765907 }, { -4.0435321e-05, -0.00061813281, -0.0060490143, 0.0016259965 }, { -0.00014720558, -1.0601876e-05, 0.00014757138, 0.00016227641 }, { -0.010428289, -0.00031812813, -0.0016172213, -0.00012022134 }, { 0.0040517131, 0.0072972763, 0.0060433905, 0.0025041645 }, { 0.00014090924, 0.00027612853, 0.00015961665, 0.0002605418 }, { -0.00020653783, -0.00048482867, -0.00058472338, 0.00026413759 }, { 0.00056712638, 0.00026385353, 0.00035484947, 0.00033212447 }, { -0.00094663094, 0.0029891757, 0.0029887838, -0.0026583585 }, { -0.0017400246, 0.00042350567, 0.00086128207, 0.00039863587 }, { 0.00059604848, 0.00027495434, -0.00059956434, -4.4981673e-05 }, { -0.010211343, -0.0080580409, -0.0085333216, 0.0023258717 }, { 0.00042832593, 0.0056750222, 0.0048059635, -0.0092168281 }, { 3.0214612e-05, 4.540924e-06, 1.7239937e-05, 2.783598e-05 }, { 0.00029393335, -4.5128636e-05, -4.3089017e-05, 0.00030682556 }, { -4.7077735e-05, -1.3596835e-05, -0.0015338149, -7.4957991e-05 }, { -0.00097136844, 0.00018564298, 0.00021815754, 0.0015095577 }, { 0.00043929849, -0.0014691094, -0.0014671742, -0.00029365954 }, { 8.8554045e-05, 0.0062500772, 0.0001495049, 0.00021007601 } }, { { 0.0020307077, 0.0020947445, 0.0017438295, 0.0084822342 }, { -0.0069727503, -0.0010131005, 0.0055261321, -0.0020442588 }, { 0.00031035611, 0.00010839441, 3.7359209e-06, 4.3112837e-05 }, { 9.1207794e-05, 0.0050148169, 0.0051071455, 0.0033679057 }, { -0.00090101737, -0.00053793176, -0.0025829621, 0.0003241927 }, { -0.0019244714, -0.0033690472, -0.0035193497, 0.0027653636 }, { -0.00065476293, -0.00017787403, 0.00040383136, -0.00018123957 }, { -0.00030640434, -0.00018961553, -0.00011036218, -0.00015793049 }, { 0.001110592, -0.00021252645, 0.00015849587, -3.7758317e-05 }, { 0.00077967828, -0.0051765235, -0.0078505592, -0.010796339 }, { -1.2024951e-05, 6.48806e-05, -3.9409005e-05, 7.4639306e-05 }, { -0.00017352424, -0.00037802595, -0.00045639468, 0.00016843169 }, { -4.2866244e-05, -4.3730932e-06, 7.3574276e-05, 5.6076779e-05 }, { 0.00024802387, 0.0018053101, 0.0018042994, -0.0016700716 }, { 0.0082698262, -0.00014605077, 0.0004377682, 8.1585074e-05 }, { -4.494343e-06, 0.00019781519, -0.00058910268, -0.00027360572 }, { 0.0013016934, 0.0021020456, 0.0022718598, -0.0059377824 }, { 0.002185371, -0.0080788056, -0.0071952836, 0.0039688918 }, { 0.00013048617, 0.0001738124, 0.00012978924, 0.00013813358 }, { 0.00032386518, 0.00023046021, 0.00023064714, 0.00033762343 }, { 0.00023643771, 0.00019652953, 0.0013083597, 0.00024739959 }, { -0.0063957036, -0.0055319023, -0.0054742301, -0.0037204932 }, { -0.0005510683, -0.0007715413, -0.00077385934, -0.001009415 }, { 0.00017904616, -0.00096137522, 0.00030252599, -2.2478138e-05 } } }, { { { -0.00038948583, -0.00040817153, -0.00041280315, -0.0010985631 }, { 0.0025695337, 0.00042904308, 0.0054649973, -0.0055079106 }, { 0.00052050672, 2.2618679e-05, 0.00024058975, -0.00012632201 }, { -0.013468886, 0.0079396715, 0.0079402246, 0.026283756 }, { -7.922122e-05, -3.4761763e-06, -0.0041716347, 0.0001478739 }, { 0.023716381, -0.016415262, -0.015296927, -0.021050827 }, { 3.7654391e-05, 0.00012765816, -0.0001337099, 0.00051483398 }, { 0.00015671907, 0.00010686796, 2.1421097e-05, -2.2281569e-05 }, { 3.1779413e-06, 0.00010449913, -0.00018303614, 7.5382489e-05 }, { -0.00020526765, -0.0011333575, -0.0050720108, 0.0051482782 }, { 4.0450357e-05, 1.0808158e-05, -2.3316095e-05, 9.7767333e-06 }, { -0.019107229, 0.010907324, 0.0048969594, 0.017851514 }, { 7.4048796e-05, -7.041835e-06, 8.0226174e-05, 5.1714105e-05 }, { -0.016564627, 0.0023486944, 0.0023601429, 0.016005248 }, { -0.004528284, 3.6291049e-05, 2.4229636e-05, 0.0024853948 }, { 5.6882054e-05, 6.8805135e-05, 0.00013119897, 0.00010339801 }, { 0.00021183341, 0.0008203137, -7.204401e-05, 0.00062599728 }, { -0.00099314707, 0.0030198762, -0.0038989955, 0.00055571214 }, { -7.4247984e-05, -8.3993373e-05, -5.9133252e-05, -7.7411989e-05 }, { 0.0054296732, -0.00057858871, -0.00058417754, -0.005072911 }, { -0.00019259782, -0.00018772532, -4.2959783e-05, -0.0001827295 }, { -0.00029351865, 0.00013736372, 0.00016666048, 0.00020873447 }, { 0.0069341659, 0.0027612928, 0.0027538377, -0.0061770317 }, { 4.2584714e-05, -0.00037063589, -9.0693123e-06, 0.00011845784 } }, { { 0.0028834168, 0.0031807308, 0.0031352582, 0.01064051 }, { 0.0049297987, -4.2149356e-05, -0.0014926841, -0.0002300371 }, { 0.0020396303, -0.00066042794, -6.4359283e-05, 0.00017835163 }, { -0.0025767816, 0.0025148152, 0.0025224779, 0.0043006543 }, { -0.00042084416, -0.00013534305, 0.002453623, -4.0707749e-05 }, { -0.0001803055, -0.0010450606, -0.00084380806, 0.00014843677 }, { -0.0064067107, 0.00011012652, -0.0022552747, -0.00080508294 }, { -0.00017778763, -4.296789e-05, 0.00015343883, 0.00025036711 }, { 0.002825978, -0.00031945362, -0.00031987612, -0.00021117763 }, { 0.00032791249, -0.00049524542, 0.0049368722, -0.0017186408 }, { -0.0001685943, -0.00016766033, -0.0001755097, -0.00017067307 }, { 0.00023939157, -0.00011793706, -6.0620575e-05, -0.0002706595 }, { -2.9718673e-05, 3.5950879e-05, 1.839844e-05, -2.8718148e-05 }, { -0.0017260981, 0.00012145435, 0.0001236679, 0.0018292155 }, { 0.0036086706, 0.0001026898, -2.5518889e-05, -0.00019830236 }, { -0.00031546808, -0.00042107458, -0.00059963868, -0.00061472497 }, { -0.0074719522, 0.0015719596, -0.0033624165, -0.0092664101 }, { -0.0011285776, 0.0018601435, 0.00052060704, -1.5554679e-05 }, { 4.9853171e-05, 7.3650922e-05, 3.4080107e-05, 5.4255445e-05 }, { 0.00015102779, -2.58105e-05, -2.5851018e-05, -4.5185316e-05 }, { 0.0002057452, 0.00019037765, 0.0040052198, 0.00020046579 }, { 0.0027727314, 0.0040749211, 0.0036050794, 0.0034635222 }, { 0.00042503689, 0.00056027382, 0.00056052971, -8.2485044e-05 }, { -5.6309634e-05, 0.0019722025, 6.4267434e-05, -0.00020376412 } }, { { 0.0051607661, 0.0047835358, 0.0047658352, 0.0054281814 }, { -0.0040939561, 0.0012119183, -0.0023408179, -0.00055891234 }, { -0.0031939804, -0.0015954053, -0.00018570689, 0.00028849431 }, { -0.0075625096, 0.0033878734, 0.0033797415, 0.010242674 }, { -0.002293562, 0.00024245282, 0.0019455622, 0.0039550747 }, { 0.0090386754, -0.0086947671, -0.0082684939, -0.0075613346 }, { -0.00085735117, 3.4822634e-05, -0.0024653972, -0.00090964985 }, { -0.00013750587, -0.00010089501, 6.3555498e-05, 0.0002758494 }, { 0.0060496328, -0.00032664426, 0.0005979723, -0.00018819024 }, { 0.00072724184, 0.00082242885, 0.0045668772, -0.0054557456 }, { -9.6167811e-05, 7.9856612e-05, 0.00015672473, 8.0901183e-05 }, { 0.00038859448, -0.00025360755, -0.00017624981, -0.00049125519 }, { -8.8277361e-05, 2.4159527e-05, -0.00016014627, -2.7854246e-05 }, { -0.0037308647, 0.00041434141, 0.0004167221, 0.0037190244 }, { 0.00050696744, -4.6752715e-05, 0.00033183668, -0.0025882828 }, { -0.00015915702, -0.0002325901, -0.00036157415, -0.00016391937 }, { 0.00012320153, 0.0026711886, 0.0018414591, -0.0058215223 }, { -0.0029409983, -0.00015460743, 0.0031951665, 0.0074654329 }, { 9.9084813e-05, 9.1785865e-05, 5.9300007e-05, 0.00010463304 }, { 0.00024773341, -2.5723276e-05, -2.5709769e-05, -0.00015357475 }, { 0.000416633, 0.00028749584, -0.0038632071, 0.00039869488 }, { 0.00018344152, 3.0811778e-05, -0.00010240082, 0.00059301197 }, { 0.0019217461, 0.00034404024, 0.00034318823, -0.0015867375 }, { -0.00011928879, 0.001178769, -5.8655983e-05, -0.00028461439 } } }, { { { 0.99999992, 0.99999992, 0.99999991, 0.99999925 }, { 0.99998864, 0.99999972, 0.99993965, 0.99997027 }, { 0.99999969, 1, 0.99999997, 0.99999998 }, { 0.99990852, 0.99971841, 0.99970961, 0.9996348 }, { 0.99999999, 1, 0.99997626, 0.99999999 }, { 0.99951219, 0.9997196, 0.99973058, 0.99951587 }, { 0.99999997, 0.99999999, 0.99999988, 0.99999986 }, { 0.99999998, 0.99999999, 1, 1 }, { 0.9999998, 0.99999999, 0.99999995, 1 }, { 0.99999988, 0.99999525, 0.99997473, 0.99995457 }, { 1, 1, 1, 1 }, { 0.99975729, 0.99976356, 0.99983365, 0.99982963 }, { 0.99999998, 0.99999999, 0.99999998, 0.99999998 }, { 0.99986279, 0.99986979, 0.99986978, 0.99984147 }, { 0.99997099, 1, 0.99999998, 0.99999688 }, { 0.99999999, 0.99999999, 0.99999998, 0.99999999 }, { 0.99999977, 0.99999903, 0.99999932, 0.99999947 }, { 0.99999911, 0.99997627, 0.99997853, 0.99999968 }, { 1, 1, 1, 1 }, { 0.99998521, 0.99998941, 0.99998944, 0.99998567 }, { 0.99999998, 0.99999998, 1, 0.99999998 }, { 0.99999928, 0.99999998, 0.99999997, 0.99999714 }, { 0.99997035, 0.99997405, 0.99997415, 0.99997569 }, { 1, 0.9999997, 1, 0.99999999 } }, { { 0.00015966941, 0.00014262676, 0.00020165066, 0.00021618914 }, { 2.8140907e-06, -0.00020325872, 0.00017736728, 6.0386679e-05 }, { -0.0003187876, 5.8862288e-05, 6.2281085e-05, 1.7339908e-05 }, { -2.6587911e-05, -0.00011609007, -0.00011725093, -7.6114852e-05 }, { 0.00013665042, 5.2703844e-06, -0.00031293536, 3.8693931e-05 }, { -9.8143069e-05, -0.00012816332, -0.00012926252, -0.00010623032 }, { 0.00032342312, -1.9200091e-06, -0.00010691485, 6.3541059e-05 }, { -8.0643542e-06, 9.7622933e-06, 2.9924822e-05, -1.988333e-05 }, { 0.00025318464, 1.2588649e-05, 1.4665927e-05, 9.3294806e-06 }, { 2.6875391e-06, -2.4928123e-05, 2.251878e-05, 0.00011026808 }, { 1.767638e-05, 1.0309044e-05, 2.4765648e-05, 1.4397941e-05 }, { 6.9000935e-06, 1.0637078e-05, 1.087637e-05, 6.3065784e-06 }, { 5.532953e-05, 1.6231463e-05, 4.9564371e-05, 3.6623041e-05 }, { -1.6958729e-05, -3.1627491e-05, -3.1524511e-05, -2.9954116e-05 }, { 8.9045086e-05, 2.1005026e-05, 1.3016463e-05, 8.7863053e-05 }, { -2.75035e-05, -3.0440427e-05, -3.5356286e-05, 5.9609261e-06 }, { 0.0001586274, 4.0711165e-05, 3.1563135e-05, 0.0001385483 }, { 8.5548316e-06, 7.4531928e-05, -3.7017413e-05, 2.6874037e-05 }, { -1.3750655e-05, -8.2756032e-06, -2.7214983e-07, -1.4830115e-05 }, { -7.0798362e-07, -3.3187173e-07, -3.3266762e-07, -5.7113855e-07 }, { 4.3615512e-05, -4.4076433e-06, 8.9239586e-06, 3.7278531e-05 }, { -7.7366773e-06, 4.610399e-06, 4.3762687e-06, -5.64067e-06 }, { -3.2666125e-06, -1.0773146e-05, -1.0861965e-05, -1.3327232e-06 }, { -9.1178305e-06, 0.00030171207, -1.5395234e-05, -2.0695425e-07 } }, { { 0.00017159464, 0.00014699558, 0.00018752678, 0.0002227926 }, { -4.6524822e-05, -0.00010460271, 0.00034735325, 0.00010082238 }, { -6.8269006e-05, 1.4343751e-05, 7.7283393e-06, 2.5347136e-05 }, { -6.6149546e-05, -7.1168993e-05, -7.0621016e-05, -0.00015246746 }, { 7.12022e-05, 3.8790461e-05, -0.00023994449, 6.6792921e-05 }, { -0.00014735813, -0.00012658353, -0.00012162488, -0.00012106777 }, { 0.00015161388, -1.4439153e-05, -3.7629923e-06, 8.3140788e-06 }, { 4.0175416e-05, 2.5380268e-05, -2.2894421e-06, 4.6374378e-06 }, { 0.00028906023, 1.7695243e-05, 5.3790587e-06, 1.631859e-05 }, { 1.8890685e-05, -1.6898275e-05, 2.1007663e-05, 6.5179363e-05 }, { -3.9142595e-06, 2.5745488e-05, 1.0803197e-05, 2.7099749e-05 }, { 9.4245546e-06, 1.0010075e-05, 9.058324e-06, 9.8703427e-06 }, { -2.3441863e-06, 2.5490323e-05, -1.0097654e-05, 4.0554798e-05 }, { -4.1443921e-05, -1.996316e-05, -2.0000841e-05, -4.7495655e-05 }, { 0.00012591695, 5.6179903e-05, -1.8415869e-05, -3.8697972e-05 }, { 2.6719505e-05, 2.4195362e-06, 2.4287424e-05, 3.4703059e-05 }, { 7.3804931e-05, 4.9784871e-05, 3.1159931e-06, 0.00015857197 }, { -0.00010634331, -1.6427658e-05, -7.4874306e-05, -6.2620255e-05 }, { -4.2561214e-06, -1.6123179e-05, -1.5507273e-05, -1.2909924e-05 }, { -1.2210463e-06, 1.1546399e-06, 1.1413892e-06, -1.3465856e-06 }, { 3.4909884e-05, -1.2677793e-05, 0.00011543701, 2.413091e-05 }, { -2.1953323e-05, -4.6244252e-06, -3.5624435e-06, 4.2293671e-06 }, { -1.1392936e-05, -4.3970369e-06, -4.4264864e-06, -1.208518e-05 }, { -4.4002617e-05, 0.00020912348, -3.9617824e-05, -4.1725112e-05 } } }, { { { -0.32504349, -0.32502096, -0.32501094, -0.32423576 }, { -0.65602876, -0.65622598, -0.65567173, -0.65525128 }, { -1.4666488, -1.4666488, -1.4666488, -1.4666488 }, { 0.87168363, 0.87181364, 0.87181792, 0.8718169 }, { -1.264365, -1.264365, -1.264365, -1.264365 }, { 0.89917968, 0.89916889, 0.89916525, 0.89927374 }, { -1.2245906, -1.2245906, -1.2245906, -1.2245906 }, { -0.8885678, -0.88856217, -0.88856327, -0.88855044 }, { -0.31799095, -0.31916566, -0.31907669, -0.31918911 }, { -0.08987958, -0.090342401, -0.090004674, -0.090222398 }, { -0.59425693, -0.59433999, -0.59429118, -0.59433553 }, { 1.1317575, 1.1317475, 1.1317412, 1.1317494 }, { -1.2193493, -1.2193493, -1.2193493, -1.2193493 }, { 1.2506981, 1.250675, 1.250675, 1.2506569 }, { -1.08782, -1.0877793, -1.0878022, -1.0878025 }, { -0.13925598, -0.13932948, -0.13919658, -0.13913403 }, { -0.40394684, -0.4042314, -0.40436178, -0.40402218 }, { -0.47762966, -0.47745572, -0.47767784, -0.47713093 }, { -0.60177181, -0.60176862, -0.60177347, -0.60177079 }, { 2.7311956, 2.7311911, 2.7311911, 2.731191 }, { -1.3109856, -1.3109856, -1.3109856, -1.3109856 }, { 0.60942644, 0.60941369, 0.6094123, 0.60944198 }, { 0.55675448, 0.55672275, 0.55672303, 0.5567542 }, { -0.40637059, -0.4057945, -0.40635768, -0.40636681 } }, { { -0.0016154222, -0.0015930079, -0.0015828998, -0.00087447165 }, { -0.0011262472, -0.001324462, -0.00094895016, -0.00062188189 }, { 0, 0, 0, 0 }, { 9.7616744e-05, 0.00010718899, 0.00010718606, 0.00012665246 }, { 0, 0, 0, 0 }, { 0.00013476236, 6.982272e-05, 6.8208505e-05, 0.00014604742 }, { 0, 0, 0, 0 }, { -0.0031089951, -0.0031071196, -0.0031207245, -0.0031097054 }, { -0.0027808116, -0.0035049857, -0.0034100135, -0.0035192661 }, { -0.0018291474, -0.0019603285, -0.0018919656, -0.0019656229 }, { -0.0034301741, -0.0034912573, -0.0034474395, -0.0034893985 }, { -6.156701e-06, -9.8568527e-06, -1.2383692e-05, -9.9984205e-06 }, { 0, 0, 0, 0 }, { 0.00011838153, 0.00011008679, 0.00011008878, 0.00010536608 }, { -0.0006246638, -0.00058479459, -0.00061327452, -0.00061085433 }, { -0.0059197749, -0.0059778169, -0.0059586015, -0.0058798299 }, { -0.0013246996, -0.0016061786, -0.0016081246, -0.0014374546 }, { -0.001593227, -0.0014706843, -0.0015974008, -0.001341579 }, { -0.0027930604, -0.0027920013, -0.0027939865, -0.0027928528 }, { -1.8908723e-06, -4.266382e-06, -4.2210172e-06, -5.0155215e-06 }, { 0, 0, 0, 0 }, { 0.00018508026, 0.00019774537, 0.00019744661, 0.00019538593 }, { 2.3243747e-05, 1.7291398e-05, 1.7309712e-05, 2.9261396e-05 }, { -0.0041402471, -0.0037085946, -0.0041294876, -0.0041316136 } }, { { -0.0018899732, -0.0018719182, -0.0018661076, -0.0012234594 }, { -0.0012968123, -0.0012971446, -0.00093522854, -0.00066475268 }, { 0, 0, 0, 0 }, { 9.1054464e-05, 0.00014124217, 0.00014156806, 0.00012014953 }, { 0, 0, 0, 0 }, { 0.00017026995, 0.00010528413, 0.00010537941, 0.00015698848 }, { 0, 0, 0, 0 }, { -0.0025812972, -0.0025835894, -0.0025789321, -0.002554949 }, { -0.0035568863, -0.0042988014, -0.0042155548, -0.004312546 }, { -0.0024184575, -0.0025111277, -0.0024654994, -0.0023980076 }, { -0.0036993386, -0.0037113013, -0.0036987284, -0.0037094875 }, { -5.074861e-06, -1.1367399e-05, -1.4819989e-05, -9.2705899e-06 }, { 0, 0, 0, 0 }, { 0.00012570403, 0.00012150272, 0.00012149179, 0.00010579599 }, { -0.00062162762, -0.00058131015, -0.00060837583, -0.00060795256 }, { -0.00775735, -0.0077198081, -0.0078365948, -0.0077749317 }, { -0.0015325554, -0.0017125784, -0.001703195, -0.0015662859 }, { -0.0018130784, -0.00177106, -0.001858095, -0.0015845058 }, { -0.003668417, -0.0036659688, -0.0036693421, -0.0036680526 }, { -9.5804016e-06, -9.6276607e-06, -9.630607e-06, -1.2159056e-05 }, { 0, 0, 0, 0 }, { 0.00017930618, 0.00020084683, 0.00020150104, 0.00020810787 }, { 2.3869269e-05, 1.1024793e-05, 1.1041937e-05, 1.6467357e-05 }, { -0.004690782, -0.0044656761, -0.0046782065, -0.0046921455 } } }, { { { 0.23047932, 0.23043226, 0.23041471, 0.22922185 }, { 0.14990977, 0.15703656, 0.15110771, 0.15149153 }, { 0.30629171, 0.30426701, 0.30400037, 0.30403889 }, { 0.03476576, 0.036188528, 0.036216719, 0.037322097 }, { 0.31066251, 0.31090363, 0.31041565, 0.31057779 }, { 0.04875259, 0.046468595, 0.046486323, 0.046584523 }, { 0.31745458, 0.31874472, 0.32086369, 0.31880207 }, { 0.64054942, 0.64062862, 0.64051973, 0.64059059 }, { 0.27309038, 0.27480819, 0.27477284, 0.27486762 }, { 0.196647, 0.19687982, 0.19607604, 0.1957915 }, { 0.32867362, 0.32858008, 0.32856702, 0.328555 }, { -0.0026873031, -0.0042393446, -0.0057894907, -0.0041858859 }, { 0.40254624, 0.4024247, 0.4025598, 0.40243731 }, { 0.019362807, 0.018146218, 0.018146051, 0.019656613 }, { 0.29328089, 0.29403937, 0.29435036, 0.29403094 }, { 0.57111506, 0.57118505, 0.57099608, 0.57099266 }, { 0.16966612, 0.16993739, 0.17069399, 0.16991136 }, { 0.14989055, 0.1489484, 0.14995985, 0.15015916 }, { 0.33606014, 0.33606294, 0.33606393, 0.33605429 }, { 0.015421206, 0.015180692, 0.01518037, 0.015431139 }, { 0.33165237, 0.33185282, 0.33162592, 0.33166981 }, { 0.078137018, 0.078153855, 0.078165152, 0.078332343 }, { 0.002896946, 0.0026038621, 0.0026029604, 0.0022081151 }, { 0.41064398, 0.40987685, 0.41065341, 0.41059166 } }, { { -0.0024316111, -0.0024732789, -0.0024922144, -0.0035874346 }, { 0.0013306961, 0.004171802, 0.0027660627, 0.0023671465 }, { 0.0034411091, 0.0020878413, 0.0020874456, 0.0022028237 }, { -0.0032873976, -0.0021351911, -0.0021071363, -0.0028424534 }, { 0.0017995208, 0.0022319618, 0.0039270256, 0.0021249365 }, { -0.0019590835, -0.0012526895, -0.0012347747, -0.0021069943 }, { 0.0012319531, 0.002255621, 0.0030193583, 0.0020970822 }, { 0.0015144077, 0.0015110104, 0.0014803089, 0.0015340007 }, { -0.0036679996, -0.0028160114, -0.0028586497, -0.0027953731 }, { -0.005445786, -0.0052624873, -0.0054843188, -0.0053271749 }, { 0.00067154572, 0.0007530775, 0.00067974516, 0.00074462315 }, { -0.0035626119, -0.0034186877, -0.0038720517, -0.0040088745 }, { 0.003455851, 0.0035040061, 0.0034671486, 0.0035069881 }, { -0.0047789747, -0.0047994804, -0.0047996451, -0.0044008337 }, { 0.0032403482, 0.0033627856, 0.003429619, 0.0031153117 }, { -0.005027022, -0.0049812, -0.0049604573, -0.0050556194 }, { -0.0020728991, -0.0014784158, -0.001216894, -0.0019213729 }, { -0.00013808007, -0.00067270623, -0.00024001574, -0.00030691077 }, { 0.0004367104, 0.00043390709, 0.00043548166, 0.00043425516 }, { -0.00082746467, -0.00088151411, -0.00088152334, -0.0008043643 }, { 0.0030277712, 0.003133577, 0.0028529862, 0.0030362271 }, { -0.0058721937, -0.0059816331, -0.0059799345, -0.0058882832 }, { -0.0057032562, -0.0057401855, -0.0057416619, -0.0062417688 }, { -0.0014357888, -0.0020782049, -0.0014346823, -0.0014513767 } }, { { -0.0027051235, -0.0027087245, -0.0027052303, -0.0033594951 }, { 0.0028036195, 0.0030416572, 0.0014306948, 0.0017897371 }, { 0.0031113166, 0.0026432303, 0.0025937824, 0.0025394463 }, { -0.0036032904, -0.003447065, -0.0034344406, -0.0024163572 }, { 0.0023912799, 0.0025281229, 0.0038665087, 0.0024214034 }, { -0.0023543827, -0.0024294943, -0.0024539784, -0.0027742617 }, { 0.0020903896, 0.0026617586, 0.003395249, 0.0026261065 }, { 0.0019031008, 0.0019405475, 0.0019426085, 0.0019404325 }, { -0.0040413326, -0.0030964835, -0.0031020735, -0.0030826754 }, { -0.0064568993, -0.0062342438, -0.0064704698, -0.0065636744 }, { 0.0010788406, 0.0010092051, 0.0010264121, 0.00099891228 }, { -0.0040759201, -0.0059224283, -0.0066809927, -0.0049099348 }, { 0.0042962009, 0.0041909175, 0.0043195236, 0.0041900138 }, { -0.0062728983, -0.0070256154, -0.007025641, -0.0061758746 }, { 0.0036210401, 0.0039723998, 0.0042232048, 0.0042757707 }, { -0.0058693852, -0.0058583303, -0.0058544016, -0.005887725 }, { -0.0023099876, -0.0021136245, -0.0017298078, -0.0022483337 }, { -0.00017851962, -0.00014956209, 8.5676316e-05, -0.00024971669 }, { 0.0003734781, 0.00037078986, 0.00037364181, 0.00037070594 }, { -0.00030648905, -0.00038230535, -0.00038223043, -0.00028623253 }, { 0.0032871423, 0.0034163052, 0.0028276655, 0.0032991918 }, { -0.0061331695, -0.0063319797, -0.0063340119, -0.0064390374 }, { -0.0062172888, -0.0059787106, -0.0059793294, -0.0060406701 }, { -0.0018276142, -0.0022170788, -0.0018293949, -0.0018222824 } } } }, { { { { 0.13218089, -0.11654637, -0.11622196, -0.044208736 }, { 0.0074579257, 0.0038503609, 0.0013201096, 4.0415784e-05 }, { -0.025474487, -0.01209255, -0.016535858, 0.012704547 }, { -0.0016894103, -0.0081312144, -0.0033264609, 0.0011923269 }, { -0.068044876, 0.018276873, -0.074833897, 0.01308348 }, { 0.02665691, 0.013515118, 0.026440814, -0.0077037816 }, { 0.0023286096, -0.0025782652, 0.0021644694, -0.0042955294 }, { 0.051356261, -0.031058382, -0.085382962, -0.033103269 }, { -0.081609229, 0.0035270199, -0.015722417, 0.048773789 }, { 0.0023928418, -0.001243811, 0.011910492, -0.011621478 }, { -0.028953904, -0.029335777, -0.0057891432, 0.013874136 }, { -0.012473582, 0.001772629, -0.013983442, 0.014846792 }, { -0.016111661, 0.0018902323, 0.025910586, 0.042848276 }, { 0.026200626, 0.024007879, 0.0017667146, -0.016394032 }, { -0.0067006429, -0.0017968936, 0.009028659, 0.0044060413 }, { 0.019280611, 0.0449581, -0.042852227, -0.066012332 }, { -0.014451123, -0.047772741, -0.047475406, 0.098434178 }, { -0.0028954635, 0.010521833, -0.015741597, -0.00091666191 }, { 0.0020291956, -0.057966746, -0.04525094, 0.032711614 }, { 0.020563445, -0.0078684621, -0.015282237, -0.0019830466 }, { -0.019504171, 0.071338511, 0.0033729474, -0.0095772339 }, { 0.013056103, 0.018719519, 0.0096002937, -0.028774366 }, { -0.00038728577, -0.0010662982, -0.0014333502, 0.00059135695 }, { 0.073844752, -0.05666013, -0.1007151, -0.030440738 } }, { { 0.00017766639, -9.2398532e-05, -3.9442682e-05, -3.9559848e-05 }, { -0.0043956477, 0.00044042277, -0.00047491077, 9.4171117e-05 }, { -0.0042095545, -0.00910753, -0.0014295282, 0.0042595844 }, { 0.00070989004, -0.0009623012, 0.00084162653, -0.00015925965 }, { -0.0017587638, 0.0033199811, -0.00025544613, 0.00083644978 }, { 0.0051797987, 0.0015691893, -0.002324397, 0.0050776381 }, { 0.003911779, 0.00072639703, 2.102924e-05, -0.0029529332 }, { 0.0050240476, -0.00041452319, 3.1730448e-06, -0.0072697591 }, { -1.5023048e-05, 0.00032491246, -9.2151952e-05, 0.0035851726 }, { 0.0030984373, 0.0016428856, 0.0032974124, -0.0036034289 }, { -0.00044578206, -0.0035916409, 0.0028146658, 0.0068013321 }, { 0.00025716711, -0.0024772152, 0.0029660992, -0.0008783244 }, { -0.005543602, -0.00046453249, 0.006815884, 0.0069207512 }, { -0.0033541738, -0.0015140333, -0.004071746, -0.0020908789 }, { 0.0027932918, -0.0012517158, -0.0033509184, -0.001271572 }, { 0.0043481525, -0.00088858735, -0.0081538059, 0.00027985077 }, { 7.4017523e-05, -7.0080388e-05, -7.1766386e-05, 0.00020468758 }, { 0.00044507396, 0.010179106, -0.0048087449, 0.0013487105 }, { 0.00082148695, -0.00042640153, -0.0024255173, 0.0044486011 }, { -0.00026383509, -0.0031871528, -0.008203704, -0.00053957093 }, { -0.0002996462, 0.00070789605, 7.9300612e-05, -0.00024002209 }, { 0.0013722116, 0.0049176054, 0.0029283062, -0.000849108 }, { 0.00026545039, 0.0011783443, 0.00072103548, -0.0007355776 }, { 0.002192273, -0.00294318, 1.5452606e-05, -0.0020953993 } }, { { 2.4074136e-05, -2.4931598e-05, -1.0893587e-05, 1.080951e-05 }, { -0.0061635883, -0.0042963493, -0.00177783, -0.00080292808 }, { 0.0047868795, -0.0050472436, 0.0082439123, -0.0090979713 }, { 0.0017221077, 0.0067285193, 0.0031011872, -0.0019932567 }, { 0.0010926271, -0.0012170693, 0.00012875612, 0.00016441623 }, { -0.0048786273, -0.0041225634, -0.005591426, 0.0043469593 }, { -0.0070664098, -0.0012625813, -0.00022220241, -0.0026120468 }, { -0.0026689917, 0.00030860545, 1.9297947e-05, 0.001274799 }, { 0.0026769559, 0.00016106032, 0.00013829246, -0.0017239107 }, { -0.0042495789, 0.0010270326, -0.00078224804, -0.0019210019 }, { 0.0072385804, 0.0086418476, 0.0061428272, -0.0027142827 }, { 0.0019768127, -0.00057957046, 0.0047464783, -0.004599565 }, { 0.0093618867, -0.0010476542, -0.0038681572, -0.0065219521 }, { -0.0076406673, -0.0036729355, -0.0068804827, 0.0077571478 }, { 0.0012706397, -0.00042567505, -0.002521821, 6.0288127e-05 }, { -0.002041411, 0.000430125, 0.0073620925, 0.0021579456 }, { 0.00012145466, 4.1276616e-05, 4.2449608e-05, 9.8351262e-05 }, { 0.0014376278, -0.007439719, 0.0039006971, 0.00051135138 }, { -7.1665367e-05, 0.00023856335, 0.00015274881, -0.0096946274 }, { -0.00076804256, 0.0040182915, 0.012603411, -0.00059669891 }, { -0.00010641981, -0.00052355992, 0.00057481361, 0.00016456343 }, { -0.0027623375, -0.0036761364, -0.010480297, 0.0066006902 }, { 0.00049081404, 0.00077264749, 0.0021355718, -0.00029188425 }, { 0.00028566818, 0.00097678458, 0.00089022281, -0.00013760767 } } }, { { { -0.0098123577, 0.11017117, 0.11245143, -0.01173447 }, { 0.0036188505, -0.0025878518, -0.00043343726, -0.0038813197 }, { 0.013109746, -0.016775181, -0.0011093308, 0.00083465721 }, { -0.0042515898, -0.0028159364, 0.00027829209, -0.002907578 }, { -0.0081027554, -0.0019330574, 0.061872524, -0.037539524 }, { -0.012923735, 0.021011524, 0.002680406, 0.0034369108 }, { 0.0027819214, 0.0028657905, -0.0034177203, -0.0037322329 }, { -0.0036178174, 0.065792163, 0.13263475, 0.0055427994 }, { 0.027832309, -0.083372016, -0.058757582, 0.016164879 }, { -0.0082343898, 0.011782416, 0.011496052, -0.0027847616 }, { 0.0012516658, -0.014686832, -0.025073035, -0.020700577 }, { 0.0055718234, -0.011543219, -0.012867689, -0.0049474286 }, { 0.028869265, -0.035431559, 0.024976635, -0.01063055 }, { -0.0010657662, 0.014977146, 0.027109, 0.01612865 }, { -0.0021697493, 0.0044220507, 0.0055654161, -0.0032373397 }, { -0.018500666, -0.01979267, -0.0068480612, 0.03908391 }, { 0.063306878, 0.01934691, 0.019254616, -0.099824471 }, { 7.0580666e-05, -0.0015082457, -0.0056893693, 0.00022726294 }, { 0.0077067654, -0.014018834, -0.021406454, -0.0076589993 }, { -0.0013072394, 2.6765854e-05, 0.0028400803, 0.0037431063 }, { -0.025369581, -0.064039908, -0.020594137, -0.086807367 }, { -0.033639351, 0.010434758, 0.00082983507, 0.013145885 }, { 0.00029373395, 7.8193614e-05, 0.00048496415, 0.00062972215 }, { -0.0041597628, 0.024283117, -0.030148407, 0.011456515 } }, { { -1.3484857e-05, -3.7204145e-05, -1.5660577e-05, -2.4497955e-05 }, { -0.0068070249, 0.0041035892, 0.0034647689, 0.0035918321 }, { -0.0053613309, 0.0080593503, 0.0028507084, -0.0023104987 }, { 0.0048581064, 0.0039720065, -0.0019058129, 0.0047295789 }, { -0.00030675956, -0.0007787587, -0.00025201217, 0.00020777843 }, { -0.00026433336, -0.0093672701, -0.0053201627, -0.0059632173 }, { -0.0063062815, 0.0011995204, 0.0001870407, 0.0028197877 }, { -0.00053247524, -0.00066138217, -1.4959372e-05, -0.00036023628 }, { 0.00027591427, 0.00011309835, 2.2453632e-05, -0.00075736359 }, { 0.0015654886, 0.0018114616, -0.0004503446, -8.5866048e-05 }, { 0.003501393, 0.0037179893, 0.008328543, 0.013411108 }, { -0.0035136609, -0.0015054003, 0.0011903964, 0.0022551358 }, { -0.0083723767, 0.0061303554, -0.008056962, 0.0035035183 }, { -0.0023715655, -0.0070468331, -0.010219655, -0.0057856465 }, { -0.0011406634, -0.00021204595, -0.001693195, 0.0011051597 }, { 0.0011643412, 0.00037557194, 0.0048567739, -0.00063996433 }, { -3.1728174e-05, -2.9073903e-06, -3.0243209e-06, 2.579239e-05 }, { 0.00053152589, 0.0029635352, 0.0040743289, -0.00051381046 }, { -0.0017253584, 0.00012081524, 0.00012243664, -0.00063598215 }, { 0.0026711847, -0.0020733972, -0.0027860744, 0.0017065643 }, { 5.7762902e-05, 0.00092043577, -0.0035278882, 0.0007846087 }, { 0.0056127705, -0.0051893669, -0.0027072408, -0.0025630045 }, { -0.00059289151, -0.0004168408, -8.8118696e-05, -0.00073538101 }, { 0.0003388606, -0.00094234652, 3.013109e-05, -0.0010532484 } }, { { -2.9013996e-05, 6.1983083e-05, 2.8401438e-05, -3.4901557e-05 }, { 0.0045230474, -0.0021369843, -0.00422706, -0.0018918027 }, { 0.00017586142, 0.005389053, 0.0071352982, -0.0018278685 }, { -0.0012135723, -0.0035970727, 0.00078957165, -0.0017065397 }, { -0.00067051937, -1.9501585e-05, 4.1968766e-05, -0.0010958091 }, { -0.0015277626, -0.0039952533, -0.00049631478, 0.0018042745 }, { 0.0039376754, -0.00097834328, 6.5894634e-06, -0.0044189106 }, { -0.00067623039, 0.0004690807, 1.4532105e-07, 0.0032984829 }, { 0.0020787449, -0.0016586579, -0.00062367064, 0.0021545362 }, { 0.0016427801, 2.6710288e-05, 0.0016011535, -0.00077649869 }, { 0.0039999622, -0.0014968097, -0.0025647576, 0.0022783424 }, { 0.001558454, -0.00083803058, 0.0018955692, 0.0010432376 }, { 0.010555722, -0.010395022, 0.0050354965, -0.0016177699 }, { 0.00011370745, -0.009328355, -0.0063009522, 0.0024377458 }, { -0.00024433189, 0.00052920244, -0.0013213352, -0.0013503982 }, { -0.0057620093, 0.00095391746, -0.0034768563, 0.00093990705 }, { 0.00012108024, 4.1007202e-05, 4.2193381e-05, -0.00011043617 }, { 0.0038593696, -0.00074282979, -0.0093457897, 0.00027311164 }, { 0.0021514797, -7.8742315e-05, -0.0018813077, -0.0017625098 }, { 0.0038491118, 0.00022570776, -0.0061331041, 0.00014956617 }, { -0.00014676603, -0.00025053931, 0.003376287, -0.00014730695 }, { 0.0016439646, 0.0060569792, 0.00063058918, -0.0034810156 }, { 0.00011722835, 0.00032237223, -0.0012556553, -0.0006887808 }, { 0.00060814722, 0.0003708376, -0.00056515636, -0.00016801817 } } }, { { { 0.99117704, 0.98705585, 0.98683693, 0.9989534 }, { 0.99996564, 0.99998924, 0.99999903, 0.99999247 }, { 0.99958951, 0.99978616, 0.99986266, 0.99991895 }, { 0.99998953, 0.99996298, 0.99999443, 0.99999506 }, { 0.99764936, 0.9998311, 0.99527468, 0.99920949 }, { 0.9995611, 0.99968788, 0.99964679, 0.99996442 }, { 0.99999342, 0.99999257, 0.99999182, 0.99998381 }, { 0.99867384, 0.99734987, 0.98748052, 0.99943657 }, { 0.99627571, 0.99651225, 0.99814846, 0.99867903 }, { 0.99996323, 0.99992981, 0.99986298, 0.99992859 }, { 0.99957996, 0.99946171, 0.99966886, 0.99968945 }, { 0.99990668, 0.9999318, 0.99981943, 0.99987754 }, { 0.99945334, 0.99937032, 0.99935219, 0.99902503 }, { 0.99965614, 0.99959957, 0.99963092, 0.99973552 }, { 0.9999752, 0.99998861, 0.99994375, 0.99998505 }, { 0.99964293, 0.99879278, 0.99905795, 0.99705307 }, { 0.99788947, 0.99867085, 0.99868681, 0.99012413 }, { 0.99999581, 0.99994351, 0.99985991, 0.99999955 }, { 0.99996824, 0.99822008, 0.99874627, 0.99943549 }, { 0.9997877, 0.99996904, 0.99987919, 0.99999103 }, { 0.99948785, 0.99539425, 0.99978223, 0.99617908 }, { 0.99934875, 0.99977032, 0.99995357, 0.99949949 }, { 0.99999988, 0.99999943, 0.99999886, 0.99999963 }, { 0.99726107, 0.99809817, 0.99445842, 0.99947091 } }, { { -2.3481737e-05, -6.7307406e-06, -2.8605869e-06, -2.0372001e-06 }, { 6.6885689e-05, 4.5630281e-06, 3.5788218e-05, 1.0842484e-05 }, { -4.9278613e-05, -2.4660601e-05, 3.1625301e-06, 0.00019708279 }, { 1.2439158e-05, 3.0347865e-05, 8.6153947e-06, 1.0887256e-05 }, { -0.00012454598, -6.513709e-05, -3.5853483e-06, -3.4708286e-06 }, { -0.00013746339, 0.00013516333, 8.4535039e-05, 5.693766e-05 }, { -2.3674091e-05, -3.4690053e-06, 5.3812265e-07, -1.7613197e-05 }, { -0.00025790043, 3.0475251e-05, 2.1174795e-06, -0.00023630753 }, { -8.8624748e-06, 7.9175589e-06, -2.4258477e-07, -0.00017288313 }, { 4.0061469e-05, 0.00069846663, -0.00060299476, -0.00015396968 }, { 5.0667108e-06, 2.306363e-05, 0.00028636884, 3.6246633e-05 }, { 0.00032740524, -0.00037985037, -0.00014841039, -0.00012676016 }, { 8.7000758e-05, 0.00018530207, 1.7669124e-05, -0.00023199594 }, { 9.2332094e-05, 0.00013487652, 0.00034587506, -3.8853378e-05 }, { 6.9809868e-05, -0.00015411544, 0.0013505166, 1.4531796e-06 }, { -6.3782301e-05, 4.8545135e-05, -0.00027083794, 4.5129465e-05 }, { 3.0912438e-06, -3.2982361e-06, -3.3551612e-06, -1.7781589e-05 }, { 9.872609e-06, -2.9944213e-05, -4.5592652e-05, 1.5950681e-05 }, { 1.4767773e-05, -2.2486726e-05, -0.00010613341, -0.00015794394 }, { 2.4386215e-05, -1.1610334e-05, -4.4456294e-05, -5.0215596e-06 }, { -4.2741558e-06, 8.7714242e-06, -6.6343322e-05, 6.7010735e-05 }, { 0.00016489767, -3.3636771e-05, 5.1610504e-05, 5.2803593e-06 }, { 1.1649256e-05, 2.1169993e-05, 1.9755999e-05, 1.3389438e-05 }, { -0.00015815197, -0.00014316145, 2.6536218e-06, -4.6846396e-05 } }, { { -3.5109783e-06, -9.8530632e-06, -4.5020804e-06, 6.9233235e-08 }, { 9.9938991e-06, -2.0914089e-06, 3.5717699e-05, 3.2813664e-06 }, { 0.00012938219, 1.111062e-05, 8.0858608e-05, 0.00018147439 }, { 4.8657525e-06, 8.6580257e-06, 3.6742927e-06, 3.5828406e-06 }, { 6.9905696e-05, 2.0985073e-05, 6.8866215e-06, -4.2552499e-05 }, { 0.00012100208, 9.7821801e-05, 0.00013576456, 6.3686234e-05 }, { 1.954525e-06, -1.0727343e-06, 5.2332444e-07, -5.4034988e-06 }, { 0.00013699813, -2.226833e-05, 1.4994043e-06, 1.7110377e-05 }, { 0.0001678261, -0.00013844113, -3.4281745e-05, 5.3854072e-05 }, { -1.3018868e-05, 0.00022176303, 0.00016983401, 0.00038109805 }, { 0.00019016068, 0.00023448876, 2.643329e-05, 4.6842203e-05 }, { -1.2492528e-05, -0.00059486605, 0.00012427061, 8.1876965e-05 }, { 8.400564e-05, -0.00029859163, -4.884214e-05, 0.0002631806 }, { 0.00019907281, 0.00014046808, 0.00015482448, 4.0461099e-05 }, { -0.00024349239, 0.00081298441, 0.00084294728, 7.9617963e-05 }, { -6.0040835e-05, 3.2352918e-07, 0.00024295599, 0.00011067283 }, { -6.0027092e-06, 1.1975092e-06, 1.2248893e-06, -2.1293392e-05 }, { 1.4478736e-05, 6.8326918e-05, -7.8693614e-06, 9.2888155e-06 }, { -1.6982828e-05, 1.2094341e-05, -3.1693808e-05, 0.00028574477 }, { 3.4480942e-05, 2.6556008e-05, 0.00016193956, -1.8966503e-06 }, { -5.7726961e-06, 2.1091148e-05, 5.8963955e-05, -1.0834372e-05 }, { 0.0001214393, 1.4174882e-05, 0.0001371836, 0.00021757165 }, { 1.0140226e-05, 6.1641031e-06, 1.0590727e-05, 1.0893212e-05 }, { -1.7442656e-05, 4.2353331e-05, 7.4324714e-05, -1.9484775e-06 } } }, { { { 3.7217719, 3.6900797, 3.6899881, 3.6670816 }, { 0.067826319, 0.16468028, 0.083129199, 0.1336756 }, { 0.66338737, 0.23883566, 0.093361469, 0.10095622 }, { 0.27185537, 0.20781392, 0.32216624, 0.29876595 }, { 2.0776462, 2.0006156, 2.0243138, 2.080345 }, { 0.57695783, 0.18015147, -0.11440889, 0.14229144 }, { 0.63833683, 0.41431062, 0.44752994, 0.47594414 }, { 1.7890608, 1.962584, 1.9322155, 1.6588331 }, { 3.0538128, 3.108267, 3.1001573, 2.9593433 }, { -0.28383051, -0.27708376, -0.042513902, -0.085181891 }, { 0.3873435, 0.41697884, 0.39625427, 0.33250735 }, { -0.33498881, -0.40206929, -0.028905862, -0.48179632 }, { 1.1875033, 1.3535177, 1.2526197, 1.3337495 }, { 0.42579488, 0.24951727, 0.18976118, 0.20605317 }, { -0.53212666, -0.3861028, -0.75685995, -0.23411882 }, { 1.6910165, 1.686815, 1.5906473, 1.6528217 }, { 4.0570657, 4.0349492, 4.0350332, 4.0498099 }, { -0.017225465, -0.032503897, 0.46003211, 0.21602109 }, { 1.1196901, 1.00885, 0.91675568, 0.99635794 }, { -0.093891275, 0.0809352, -0.13783332, 0.27130678 }, { 1.9925136, 1.9829394, 1.8820721, 1.9542026 }, { 0.84563763, 0.48476746, 0.37907152, 0.70267878 }, { 0.37054708, 0.4228574, 0.6329822, 0.26197064 }, { 1.9618393, 1.8405969, 1.9440918, 1.901629 } }, { { -5.6047186e-06, 6.0454847e-06, 2.8365975e-06, 6.0894367e-06 }, { -0.00069876506, -0.00029642785, -0.00059516082, -0.00025400441 }, { -0.00020850504, -0.00012959593, -0.00032902532, -0.00058117893 }, { -0.00037901964, -0.00038062016, -0.00023777964, -0.00033714679 }, { -5.9894351e-05, -9.820791e-05, -5.9867157e-06, -6.258549e-06 }, { -0.00035424038, -8.7146215e-05, 3.0398362e-05, -0.00061406521 }, { 0.00014971442, 4.5936211e-05, -5.6259869e-06, 0.00013567035 }, { -0.00016180211, 3.1840487e-06, 3.8979157e-07, -0.00017131994 }, { -1.9877193e-05, 2.5768261e-05, 9.0577543e-06, -0.00013927462 }, { -0.0012323564, -0.00042892846, 7.2082106e-05, 0.00010999853 }, { -0.00034618449, -0.00017058897, -0.00016535057, -0.00096982024 }, { -0.00028039653, -7.155747e-05, -0.00075796707, 0.00062756458 }, { 6.6596276e-05, -7.9730809e-05, -8.0686754e-05, -2.9532397e-05 }, { -0.00084106867, -0.00036762453, 0.00012523548, -0.00052789663 }, { 7.6718268e-05, -0.0010042005, -0.00042802983, -0.0011951304 }, { -3.6972258e-05, 2.1447505e-06, -0.00035448623, -1.0620008e-05 }, { 2.8326169e-05, 2.2049468e-05, 2.2640575e-05, 1.7574827e-05 }, { -0.00014318496, -0.0004811524, -0.00049293303, -0.00067646484 }, { -2.7469144e-05, -5.9653763e-06, -1.3998899e-05, -0.00018475323 }, { -0.00017314302, -0.00010954727, -0.00040004932, 3.31106e-05 }, { -3.6093435e-06, -1.6125243e-05, -4.9195648e-05, 1.5586886e-05 }, { 0.0002059631, -0.0004024722, -0.00047984678, -9.8485329e-05 }, { -0.00094100913, -0.00073046048, -0.00052500163, -0.00068196784 }, { -2.2820197e-05, -5.9454557e-05, -6.2505468e-06, -2.6569804e-05 } }, { { 2.6015883e-05, 8.5398335e-06, 3.8473185e-06, 9.1409625e-06 }, { -0.00041459247, -0.0001855224, -0.00030529542, -0.00016322166 }, { -8.8427847e-05, -0.0002302048, -0.00038072959, -0.00076801295 }, { -0.00027717792, -0.00028594346, -0.00017910208, -0.00027291164 }, { 2.8409311e-05, -3.8005817e-05, -4.2266878e-06, -1.4520383e-05 }, { -0.0001088827, -0.00021924377, 3.9307406e-05, -0.00032488556 }, { 0.00027997916, 3.5103699e-05, -5.7448764e-06, 0.00010259251 }, { -4.7807894e-06, -2.9470863e-05, 2.6656233e-07, -0.00014346393 }, { 0.00015527098, -6.8528726e-05, -1.1206714e-05, 2.3422595e-05 }, { -0.0012763247, -0.00051503472, 0.00058055106, -0.00068688488 }, { -6.1232076e-06, -1.7073841e-05, -0.00033533389, -0.00078769935 }, { -0.00044113485, -0.00027577451, -0.0012008622, 0.00013071136 }, { 1.834948e-05, -0.00015615102, -0.00016449385, 3.6685217e-05 }, { -0.00063618257, -0.00032641968, -5.0281118e-05, -0.00041378992 }, { -0.0010181884, -0.0003871932, -0.00050061147, -0.0018967455 }, { -5.7650067e-05, -5.1145774e-06, -0.00017409773, 1.9512036e-05 }, { 1.5838743e-05, 2.503655e-05, 2.5679098e-05, 2.0053218e-05 }, { -0.00018055811, -0.00044345237, -7.9049557e-05, -0.00095669161 }, { -4.98611e-05, -1.1320605e-06, 3.7756645e-06, -8.7299215e-05 }, { -0.00011794063, -0.00015778552, -0.00036514881, 4.7288704e-05 }, { -5.1753817e-06, -1.5040527e-06, -2.836739e-05, -9.4945229e-06 }, { 0.00016873335, -0.00031983601, -0.00052281245, 0.00019034815 }, { -0.0011988594, -0.0010684975, -0.00057577023, -0.0009143845 }, { 5.0336006e-05, -1.356148e-05, 1.5582694e-05, -2.0666272e-05 } } }, { { { 0.012207721, 0.0044164612, 0.0022704542, 0.0042008503 }, { 0.29516302, 0.139976, 0.35038027, 0.13748343 }, { 0.1462123, 0.12114907, 0.28473665, 0.45762717 }, { 0.17976664, 0.19141553, 0.1209483, 0.16393769 }, { 0.044254492, 0.11383095, 0.0062726904, 0.023550537 }, { 0.14785458, 0.10151341, 0.045717467, 0.42243971 }, { -0.24205201, -0.033590842, 0.0032064617, -0.093924041 }, { 0.10866955, 0.016299431, 0.00081631108, 0.15856447 }, { 0.10108337, 0.057931152, 0.024463589, 0.21514346 }, { 0.47967783, 0.75472932, 0.5653649, 0.64752457 }, { 0.30082544, 0.15124922, 0.23567284, 0.47161499 }, { 0.54286166, 0.61049777, 0.61641378, 0.51181399 }, { 0.39328762, 0.25557559, 0.25875912, 0.22436901 }, { 0.45699569, 0.16989563, 0.2429263, 0.3924359 }, { 0.92996797, 1.1024806, 0.78045387, 1.2298879 }, { 0.19029829, -0.022675055, 0.28113642, 0.034941166 }, { 0.013203939, 0.013034069, 0.013414649, 0.011688038 }, { 0.076026927, 0.13838472, 0.29961655, 0.31531564 }, { 0.089182386, 0.010401684, 0.029374547, 0.22995838 }, { 0.052198894, 0.039866726, 0.11570972, -0.013818992 }, { 0.0062380932, 0.01788119, -0.20765047, 0.013339281 }, { 0.12436441, 0.17318651, 0.21554136, 0.18600144 }, { 0.38005287, 0.32135548, 0.28632777, 0.29211902 }, { 0.03798742, 0.0450845, 0.010912505, 0.039060104 } }, { { 0.00077914246, 0.00011130803, 8.1110229e-05, -0.00035312557 }, { 0.00051711901, 0.00029701387, 0.00040733345, 0.00034149723 }, { 0.00063893978, -0.00013702086, 0.00030866699, -0.00020070677 }, { 7.5899443e-05, 9.7456273e-05, -4.5352178e-05, 7.6172703e-06 }, { 0.00066250814, -0.00073033349, 0.00015225542, -0.0010197351 }, { 0.00040931533, -0.00043022747, 0.00093333285, 0.0002579685 }, { -0.00067488578, -0.0003706974, -0.00044487256, -0.00056555959 }, { 0.00075838366, -0.0021903789, -0.0026744174, -0.00047135202 }, { -0.00081050821, -0.0010297809, -0.00099480849, -0.00074914246 }, { 0.00063637392, 5.248783e-05, 0.00044645091, 0.00018028446 }, { 0.00067430392, 0.0004762628, -0.00032736685, 0.00041933609 }, { 6.2324555e-05, -1.6709531e-06, 0.00057418116, -0.0010360999 }, { -0.00038256183, -0.0010104012, -0.00045533693, -1.3888404e-05 }, { 0.00068274628, 0.00068411875, -0.00091273333, 0.00016211145 }, { -0.00039440715, 0.00027665323, -0.00035895503, 0.00013423207 }, { -0.00061939017, 0.00012140102, 0.00024178233, 0.00064755788 }, { -0.00052441128, -0.00050994483, -0.00051126044, 0.00066320373 }, { 0.00085915332, 0.0013567332, -0.00014328466, 0.00056098523 }, { -0.0012682676, 0.0029139719, 0.0019812291, -0.00053863027 }, { 0.0021895869, 0.00062956835, 0.0018161156, 0.00011699452 }, { -0.0010337306, 0.00016880497, -0.0014942346, -0.0034402453 }, { -0.0025336946, -0.00019468865, -0.00018045349, -5.4312149e-05 }, { 0.00021491979, 4.7651714e-05, -0.00044921151, 0.00046742044 }, { 0.0019408125, 0.00044842687, 0.0026003265, -0.00090116109 } }, { { -0.0006591255, 0.00022873584, 0.00026313866, -0.00060151354 }, { 0.00027198127, 0.00034252944, 0.00033246896, 0.00035232159 }, { -0.00034460639, -5.9085725e-05, 7.836454e-05, -0.00018946388 }, { 0.00018790551, 0.0001918358, 9.7031467e-05, 0.00015259869 }, { -0.0023033429, -0.0012945186, -0.00080964072, -0.00030432514 }, { -0.001359781, 0.00055828912, -0.00041912301, 0.00019263336 }, { -0.00042789448, -0.00018313775, -0.00030217124, -0.00028437496 }, { -0.0018340159, 0.00030654336, -0.00010781402, -0.0011985455 }, { -0.002103478, 0.00029492518, -0.00042283946, -0.001472689 }, { 0.00064558079, 0.00049703204, -0.00018932594, -0.00038268301 }, { -0.00097813334, -0.00057838807, 0.00079268109, 0.00039650774 }, { -0.00017335252, 0.00074363734, 0.0008194423, -0.00065923207 }, { -0.00075344545, -0.00026114262, -0.00054658657, -0.0013814943 }, { -0.00028279346, 0.00055730283, 0.00048990213, -0.00022186466 }, { 0.00013438509, -0.0001962818, -0.00036195953, 0.00042669461 }, { -0.00089003585, -0.0011600794, -0.0012554286, -0.0012892408 }, { -0.00067007058, -0.0010597247, -0.0010590421, 0.00044132516 }, { 0.0011626727, 0.001261033, -0.00072912018, 0.00076332442 }, { -0.001204702, -0.00011230019, 0.00036178615, -0.0017559004 }, { 0.00096282849, 0.001025959, 0.0011696947, 0.00046633555 }, { -0.00082328571, -0.00075771669, -0.0011629302, 0.00073458863 }, { -0.0016869269, -0.00035239862, -0.0004024204, -0.0016276971 }, { 0.00029053123, 0.00013409355, -0.00049087974, 0.00061969429 }, { -0.0013198997, -0.0018615784, -0.0025724061, -0.0015563017 } } } }, { { { { -0.072246889, -0.043157285, 0.043289306, 0.095998047 }, { 0.12597079, 0.24289541, -0.10930005, -0.24150539 }, { 0.031889347, -0.036238337, -0.014521983, -0.018963885 }, { -0.044155351, -0.0077170425, -0.043781059, 0.047982339 }, { 0.093995001, -0.0079510758, -0.04688882, -0.11125523 }, { 0.01700754, -0.0034361033, 0.055252382, -0.053119426 }, { -0.0014957087, -0.00063057103, 0.037930463, 0.017656646 }, { -0.017388477, -0.084085888, -0.067726647, 0.061397079 }, { -0.070625168, -0.061293011, -0.077366932, 0.11518646 }, { -0.14771316, -0.12543895, 0.052150789, 0.10530462 }, { -0.03609139, 0.001131616, -0.039549928, 0.03805765 }, { 0.064364205, 0.066758929, 0.045537002, -0.05510954 }, { 0.049051369, 0.098312455, -0.01079726, -0.11202623 }, { 0.033012208, -0.0013996988, -0.0049458824, -0.028981527 }, { 0.008617177, -0.00017670863, -0.0052380282, -0.0023438457 }, { -0.05901498, -0.050754807, -0.00011829844, 0.037297411 }, { -0.056264446, -0.03645315, -0.066412698, 0.019549244 }, { -0.11401603, -0.11856524, 0.12275022, 0.11635143 }, { -0.0011999881, -0.0016334327, -0.0056868938, 0.013393766 }, { 0.054526972, 0.033632235, 0.062591094, -0.0025531074 }, { 0.073041316, 0.073735243, -0.06935254, -0.11214186 }, { 0.034872822, -0.015473423, 0.037359975, -0.026829465 }, { -0.015137592, -0.0064462553, 0.011771178, 0.0025042048 }, { -0.038708904, -0.033968131, -0.044070885, 0.024422773 } }, { { -0.047895007, -0.016535938, 0.04855533, 0.018341613 }, { 0.004310087, 0.01519838, -0.0033290683, -0.013597406 }, { 0.0015859181, 0.016869623, -0.019279963, -0.01426933 }, { -0.0061048976, 0.031131561, 0.018085381, -0.017927117 }, { 0.052590378, 0.0066156852, -0.0025756141, -0.037241705 }, { 0.0083512619, 0.0046235666, 0.024122126, -0.013443654 }, { 0.0010672274, 0.00053123301, -0.0016276029, -0.04221993 }, { -0.0048754166, -0.021474788, -0.0039993317, 0.011831691 }, { -0.054685347, -0.050242732, -0.007606251, 0.043061893 }, { -7.5644942e-05, 0.00086632318, 0.0001960729, 0.0013264286 }, { 0.0042413724, -0.0057181522, 0.0065940983, -0.0078263328 }, { 0.0031260881, -0.0013520907, 0.025073658, -0.010841673 }, { 0.038353769, 0.06620308, -0.0072105562, -0.079188681 }, { 0.003099559, -0.0022927921, 0.021982683, -0.018991144 }, { 0.012285675, 0.0091834074, -0.0041874571, -0.032253924 }, { -0.014563556, 0.009843969, -0.010490279, 0.012979866 }, { -0.005492286, 0.064109426, -0.034795617, -0.020395732 }, { -0.023364141, -0.059336321, 0.080710391, 0.038948527 }, { 0.0028384819, 0.001822471, 0.0012903958, 0.012781079 }, { -0.004510518, -0.0020008272, 0.0017752876, 0.0077607089 }, { 0.032279653, 0.0041906079, -0.034682371, 0.0061335907 }, { -0.0082992317, -0.025250117, -0.017026845, -0.028345042 }, { -0.013132125, -0.026688493, -0.0014827793, -0.003236826 }, { 0.01650781, 0.002313574, -0.012897922, 0.026077933 } }, { { 0.062668058, 0.0081578851, 0.018952049, -0.012267283 }, { 0.0008567722, 0.0033246009, -0.0037620102, -0.0096317368 }, { -0.0083012273, 0.01184624, -0.01209373, 0.020208536 }, { 0.013862003, 0.019166381, 0.013235471, -0.026788736 }, { -0.021904217, -0.051018749, 0.0020330268, 0.006626371 }, { -0.015856131, 0.0028024655, -0.032825412, -0.018920906 }, { 0.0020870233, 0.0011616727, -0.0032704368, -0.027327141 }, { 0.01934969, 0.002427195, 0.049925128, -0.0061414889 }, { 0.013158375, 0.022248445, 0.040266734, -0.017583455 }, { 1.9024812e-05, 0.00071602053, 0.0012622199, 0.0018791611 }, { -0.0011857767, 0.0023417924, 0.026237548, -0.014687892 }, { -0.041419782, 0.024942194, -0.029143101, 0.036590943 }, { -0.015470651, -0.035208671, -0.038530514, 0.037434376 }, { -0.0029356279, 0.0023358079, 0.017641055, 0.0038203652 }, { -0.0030449623, -0.010187444, 0.0066142145, 0.0037433206 }, { 0.0080034603, 0.011463159, -0.0058129532, 0.011831147 }, { -0.0091743137, 0.045949289, 0.022412137, -0.0067531419 }, { 0.00069946656, -0.0068974782, 0.0091806954, 0.0022160793 }, { -0.0027530077, 0.00089797627, 0.0066153093, -0.010355635 }, { -0.019399018, -0.0085762573, 0.0208003, -0.027739023 }, { -0.014354809, -0.011971089, -0.0031124986, 0.044710091 }, { -0.011411144, 0.0073253411, -0.0087561348, -0.014838738 }, { 0.018837992, 0.00231775, -0.013982978, -0.0020044658 }, { 0.0012069362, 0.0012202952, 0.029106153, 0.00062793994 } } }, { { { 0.054154158, -0.11603661, -0.025631275, 0.054671866 }, { -0.2359715, 0.093194255, 0.21874866, -0.08378526 }, { 0.0089903397, 0.0087113885, -0.015445726, 0.011142042 }, { -0.0055372249, -0.0041494086, -0.033355186, -0.010136823 }, { -0.015010227, -0.0077144008, 0.13058394, -0.016779666 }, { -0.015855009, 0.014090685, 0.026549575, 0.025677527 }, { -0.00065423811, -0.0011506403, 0.028628751, 0.0086359197 }, { -0.010571292, 0.035861454, -0.025871285, -0.024827688 }, { 0.00010603924, 0.011433504, -0.052819957, -0.020208661 }, { 0.12243361, -0.14574398, -0.10091072, 0.054524772 }, { -0.014659734, -0.02291001, 0.010102434, -0.0099333349 }, { -0.0079939087, 0.023468399, 0.044548395, 0.04568814 }, { -0.048188816, 0.016469102, 0.084818672, -0.040634065 }, { 0.015089138, 0.025396216, 0.017000121, 0.010820807 }, { -0.0098155552, -0.00080001495, 0.0020122754, -0.00046896909 }, { -0.0018906417, -0.03909342, -0.020339049, -0.024007559 }, { -0.0012744487, -0.027829333, -0.05202457, -0.024366779 }, { 0.10406956, -0.092281421, -0.050420166, 0.10716663 }, { -0.0049603976, -0.0055370076, -0.0016910106, 0.012172389 }, { -0.0026486448, 0.038673757, -0.0016176887, 0.052692494 }, { -0.03722357, 0.055455783, 0.067738953, -0.0087990582 }, { -0.0026491637, 0.017275247, 0.010687117, 0.020312052 }, { -0.0016032469, 0.0090272843, -0.0079027514, -0.0050039898 }, { -0.0073653412, -0.033150577, 0.0082912493, -0.021457881 } }, { { -0.0059001999, 0.033600833, 0.066374213, -0.018058548 }, { -0.0037864945, -0.0064946131, 0.0018627774, 0.0044899139 }, { 0.0048961861, -0.0034770968, -0.0002311598, -0.0053935761 }, { 0.0090090757, 0.012149811, 0.0029969663, 0.0049403543 }, { -0.042874682, -0.0083455851, -0.0064437344, 0.0010579362 }, { 0.011866873, -0.017157526, -0.014724976, 0.0054373752 }, { -0.0006329516, -0.00024834697, 0.0015416168, -0.014246989 }, { 0.031530357, -0.052715858, -0.0063186617, -0.0070200141 }, { -0.0082273844, 0.053856605, 0.0096812384, 0.01684635 }, { -0.00017150577, 0.00097354737, 0.0013944706, 0.00085166684 }, { -0.013604545, 0.0089329355, -0.013809086, 0.0025044469 }, { -0.020284731, 0.0004724419, -0.045697697, -0.01844702 }, { 0.017874081, -0.0040537465, -0.023316716, -0.026344708 }, { 0.0092557469, -0.014456327, -0.0092919835, 0.0091758924 }, { 0.016058873, 0.0019220807, 0.0031692823, 0.0024577167 }, { -0.021184352, 0.021287579, -0.0048442696, 0.0095799112 }, { 0.035229915, -0.054291919, -0.013871324, 0.035585241 }, { 0.001275203, 0.011513119, 0.020184769, -0.0061701639 }, { 0.011353237, 0.0052697685, 0.0047637419, -0.020278005 }, { 0.0068266296, -0.01173749, 0.037482577, -0.0083236299 }, { 0.025699221, -0.03651135, -0.032342446, -0.0059784486 }, { 0.0029540635, -0.0021598269, 0.0028168477, 0.0044577193 }, { 0.0038274002, -0.0050806333, 0.007628551, 0.0027461742 }, { 0.0056567464, 0.006846664, -0.031161558, -0.0040832656 } }, { { 0.025668431, 0.0093723617, 7.4324163e-05, -0.023051436 }, { -0.010148124, 0.0018159908, 0.0072269566, 0.00082671261 }, { 0.0069741056, 0.023493533, 0.028507618, -0.026874125 }, { 0.0083316277, -0.024891629, 0.013623217, 0.0038373532 }, { -0.020992516, 0.070912136, -0.0014634877, -0.015680371 }, { 0.02178962, -0.003772636, -0.024578501, -0.047467019 }, { 0.0028586275, 0.0033445767, 0.0049576063, -0.017365739 }, { 0.0075721122, 0.010652219, -0.024031886, -0.0001146548 }, { 0.016381176, -0.044765924, -0.038036229, -0.014041395 }, { -0.00082564842, 0.00033107944, 0.00073792054, 0.0005712734 }, { 0.0080934887, 0.014534447, -0.0071347609, 0.0085413493 }, { -0.018211778, 0.0064443848, 0.017393403, 0.011490985 }, { -0.071531366, 0.030059694, 0.049103287, 0.0074609412 }, { 0.00770209, -0.017999995, -0.040048679, -0.0029073853 }, { 0.020442166, 0.0019454488, -0.019644905, 0.021793285 }, { 0.035171271, 0.0080192155, -0.023151504, 0.014168348 }, { -0.048901887, -0.0039613606, 0.0021703807, 0.030275152 }, { 0.044666116, -0.029756153, -0.015570779, 0.034470632 }, { -0.0078700362, 0.0037551741, 0.0003070052, -0.0031237403 }, { 0.015288427, -0.01284757, -0.0075319169, 0.026981487 }, { -0.0093872483, 0.013517073, -0.030221944, 0.058356065 }, { 0.0042326205, -0.016381154, 0.021475001, 0.01008732 }, { 0.0034929117, 0.020531314, -0.0085114063, 0.004821913 }, { 0.014314413, 0.01127037, -0.017197896, 0.0046932185 } } }, { { { 0.99591552, 0.99230689, 0.99873374, 0.99387895 }, { 0.96356049, 0.96556546, 0.96964041, 0.96677566 }, { 0.99945097, 0.99930521, 0.99977525, 0.99975808 }, { 0.99900933, 0.99996161, 0.99848418, 0.99879675 }, { 0.99545951, 0.99993863, 0.99032786, 0.9936502 }, { 0.99972964, 0.99989482, 0.99811938, 0.99825798 }, { 0.99999867, 0.99999914, 0.9988702, 0.99980681 }, { 0.99979292, 0.99581299, 0.99736843, 0.99780458 }, { 0.99750292, 0.99805433, 0.99560254, 0.9931383 }, { 0.98142286, 0.98133774, 0.99352772, 0.9929441 }, { 0.99924096, 0.99973689, 0.99916652, 0.99922617 }, { 0.99789446, 0.9974931, 0.99796885, 0.99743448 }, { 0.9976331, 0.99501931, 0.9963379, 0.99287411 }, { 0.99934104, 0.99967648, 0.99984325, 0.99952138 }, { 0.9999147, 0.99999966, 0.99998426, 0.99999714 }, { 0.99825531, 0.99794572, 0.99979313, 0.99901579 }, { 0.99841509, 0.99894779, 0.99643504, 0.99951192 }, { 0.98801309, 0.98864879, 0.99115599, 0.98740957 }, { 0.99998698, 0.99998334, 0.9999824, 0.99983621 }, { 0.99850879, 0.99868574, 0.99803794, 0.99860752 }, { 0.99663402, 0.99573479, 0.99528974, 0.99365325 }, { 0.99938825, 0.99973103, 0.99924472, 0.99943364 }, { 0.99988413, 0.99993848, 0.99989949, 0.99998434 }, { 0.99922338, 0.99887297, 0.998994, 0.9994714 } }, { { -0.0050599833, 0.003362263, 0.0035202243, -0.00056864904 }, { -0.0014675187, -0.0029154981, -0.00077796172, -0.0027392627 }, { -0.0010916411, 0.00078232803, 0.0014339533, -0.0020166729 }, { 0.011183745, 0.008298699, 0.011631254, 0.00030693508 }, { -0.0012964861, -0.00028098882, 0.00098513135, -0.0052243577 }, { 0.0091119501, 0.002780703, 0.011045274, 0.00334383 }, { 4.1103001e-05, 5.5767744e-05, 0.0030605577, 0.0022152241 }, { 0.00085375099, 0.0026952672, 0.0071937971, 0.0056504112 }, { -0.003773118, 0.0047936307, -4.5743022e-05, -0.0038357994 }, { 2.3815581e-05, 0.0002468657, 0.00013492048, -0.00018410816 }, { 0.0070959632, -0.00205589, 0.0056417297, 0.0030702073 }, { 0.010671769, 0.0074346008, 0.0012867659, 0.0075437523 }, { -0.0013037272, -0.0058374269, 0.0025899757, -0.0071565118 }, { 0.0030041304, 0.0018011397, 0.0093160386, 0.0082062863 }, { 0.0053156934, 0.0036543193, 0.0048724246, 0.0035118324 }, { -0.0053866158, 0.0024053442, 0.00052459148, 0.0090970513 }, { 0.011239324, -0.0010327051, -0.00097551594, 0.0044180668 }, { -0.0024379533, -0.0088232426, -0.012355568, -0.0031875953 }, { 0.0026244123, 0.0011858999, 0.0028110843, -0.001005442 }, { 0.0059514328, 0.0018892606, 0.0050231625, 0.0046700575 }, { 0.00050741664, 0.0096547476, -0.00079618251, 0.0024532112 }, { 0.0058717468, -0.0017457656, 0.0080261577, -0.00048009588 }, { 0.0025457914, 0.0016788968, 0.0013982313, 0.00073909928 }, { 0.0075035778, 0.011234409, 0.0079271096, 0.006672353 } }, { { 0.0095152396, 0.0011785006, -0.00081996856, 0.0018904938 }, { -0.0025430397, -0.0010236291, -0.0020168276, -0.0021827861 }, { 0.0036295778, 0.005406882, 0.0040788276, -0.0057729163 }, { -0.00029952998, 0.0024548208, 0.0088548836, 0.0019084209 }, { 0.0034184324, -0.0088925589, 0.00023040452, 0.00017437939 }, { 0.0037804595, 0.012156355, 0.0041276361, 0.012721488 }, { 7.4846461e-05, 0.00010580108, 0.013483417, 0.0024239851 }, { 0.00026411032, -0.00059353627, 0.0093564271, 0.0061507538 }, { 0.0016065383, -0.0027764641, 0.0013620195, 0.0010062065 }, { 9.7127925e-05, 0.00017275393, 1.0814607e-05, -0.00022627793 }, { 0.0048710612, -0.00014794569, 0.0082832436, -0.00072595412 }, { -0.0027392579, 0.0066783951, 0.00087397132, 0.001567366 }, { -0.003378151, 0.0025916338, -0.0025553201, 0.0030152022 }, { 0.0096818399, 0.0012695523, 0.0072489949, 0.016881099 }, { 0.0022796191, 0.0051693266, 0.0023373397, -0.0041448561 }, { -0.0002074582, 0.0035962454, -0.0007460719, 0.0025086317 }, { 0.0035784996, 0.003162753, 0.0022592918, 0.00024595998 }, { -0.0051294944, -0.0041428868, -0.0027597, -0.0039539398 }, { 0.0022410392, 0.00031263884, 0.0016376751, -0.0022787113 }, { 0.0025647038, 0.0074733037, 0.0051722028, 0.0024463612 }, { 0.0011787227, 0.0071159753, 0.0017217143, 0.0062717989 }, { 0.0046836737, 0.0038976423, 0.00062832002, 0.0027638154 }, { 0.0014142926, 0.0024903802, 0.0015757227, 0.0011628587 }, { 0.0016928585, 0.0043828548, 0.001653268, 0.011450696 } } }, { { { 2.8886078, 2.8900127, 2.7925705, 2.7895874 }, { 4.5455217, 4.5284714, 4.7042338, 4.6915273 }, { 0.96672505, 0.99303664, 0.98927606, 1.0351588 }, { 1.2743756, 1.2525364, 0.99649566, 0.94572778 }, { 2.6910679, 2.6922168, 2.8503404, 2.8246076 }, { 1.256075, 1.2325025, 1.5911826, 1.6091223 }, { 1.3601759, 1.3606869, 1.2793533, 1.240925 }, { 2.0291828, 2.0506809, 1.7341658, 1.6555689 }, { 2.6663531, 2.6921882, 3.1290975, 3.11849 }, { 5.3676887, 5.3663279, 5.3848664, 5.3852162 }, { 1.0586431, 1.0865889, 0.8196623, 0.8076665 }, { 1.6967251, 1.7305944, 1.5450413, 1.6347879 }, { 3.0908857, 3.0706775, 3.2974343, 3.3053965 }, { 1.2172073, 1.3839086, 1.5086796, 1.4295506 }, { 0.97676668, 1.0856738, 0.98747912, 1.0385491 }, { 1.5662275, 1.4603538, 1.784278, 1.6575438 }, { 2.1085757, 2.2092885, 2.1410448, 2.1518347 }, { 4.0214776, 4.006424, 3.7686967, 3.7771354 }, { 1.2089239, 1.2116036, 1.1244311, 1.0901017 }, { 1.1827246, 1.1472796, 1.7516784, 1.7833976 }, { 2.2113439, 2.197512, 2.2692963, 2.2787751 }, { 0.98819531, 1.057833, 1.3587301, 1.3890421 }, { 1.208957, 1.2247867, 1.2301205, 1.2325178 }, { 1.0499613, 1.1319197, 1.4067885, 1.3209087 } }, { { -0.002860931, -0.0033581281, -0.0047612075, -0.0030481839 }, { -0.0017370907, -0.0065700936, -0.0011051926, -0.0046915938 }, { -0.0006126207, 0.0010791181, -0.022876686, -0.015937275 }, { -0.010040922, -0.016433531, -0.0044976975, -0.029838315 }, { 0.00056888968, -0.0093450028, -0.00041549218, -0.0069079656 }, { -0.029781683, -0.019722587, 0.019472312, 0.0016798037 }, { -0.0015128736, -0.0012250172, -0.0091568262, -0.0091368119 }, { 0.0010846814, 0.0017189068, 0.012975603, -0.0051530971 }, { -0.026042808, -0.0090684857, -0.0021498742, -0.0032938309 }, { -0.0012792901, -0.0010431731, -0.0021366737, -0.0025526365 }, { -0.03218779, -0.013848893, -0.021872476, -0.029443623 }, { 0.008300061, 0.011951182, -0.011139414, 0.0098292843 }, { -0.0065854884, -0.020955083, -9.3843515e-05, -0.0078425688 }, { -0.054726229, -0.0073673428, -0.019267231, -0.03383648 }, { -0.049769726, 0.0065482059, -0.010189395, -0.0050480393 }, { 0.022565943, -0.020311569, 0.0091512717, -0.015600752 }, { -0.014418429, 0.0060070592, -0.0055296743, -0.003361885 }, { 8.8146509e-05, -0.0082609252, 0.0036746024, 0.0040108321 }, { 0.0010230427, 4.8153189e-06, 0.0052893378, -0.0096303521 }, { 0.0032909351, -0.010982824, 0.003880027, 0.0097699095 }, { -0.006528317, -0.012608887, -0.0057088008, -0.003867806 }, { -0.046599771, -0.024701737, -0.001078321, -0.0041018649 }, { -0.021680777, -0.021120711, 0.0055144734, -0.0031337995 }, { -0.030559213, 0.0089872726, -0.011166202, -0.0077587071 } }, { { -0.0059548858, -0.0040070313, -0.0062572119, -0.0047711065 }, { -0.0031938803, -0.005431389, -0.0026376521, -0.0046119366 }, { 0.0064917253, 0.013030824, -0.027850471, -0.011824849 }, { -0.032644485, -0.025045016, -0.0034396539, -0.039827623 }, { -0.007691681, -0.014095643, -0.0008171964, -0.0051336386 }, { -0.035626586, -0.021424668, 0.00035790929, 0.0099705685 }, { -0.0019006762, -0.0014887089, -0.0050782898, -0.0096835564 }, { -0.00087496879, 0.0052586834, 0.017041675, -0.00046753956 }, { -0.022489507, -0.0084834888, 0.0017184219, -0.0023910992 }, { -0.0010618265, -0.00085888729, -0.0020035777, -0.0024245283 }, { -0.029245834, -0.038977066, -0.013385246, -0.030312138 }, { -0.0028497869, 0.014205986, -0.0125692, 0.0037959624 }, { -0.0086377959, -0.019175965, -0.007684309, -0.005037677 }, { -0.063945685, -0.0060751259, -0.0057457302, -0.019079575 }, { -0.043745147, 0.013651906, -0.034067394, 0.0012111497 }, { 0.0086647574, -0.019171418, 0.020745219, -0.0055629951 }, { -0.024541273, 0.0072112135, -0.0078821942, -0.0085072621 }, { -0.0018227939, -0.0021153099, 0.008577002, 0.0043865151 }, { -0.013984752, -0.012209334, 0.00023638151, -0.0085025952 }, { -0.0099800075, -0.0095390578, 0.0081328135, 0.012673433 }, { -0.0099975551, -0.0028467616, -0.010712056, -0.0045012212 }, { -0.011329139, -0.0084709831, -0.0070232966, 0.0015504012 }, { -0.015334801, -0.0075637633, -0.01107439, -0.0094188163 }, { -0.017505269, -0.00013701888, -0.033955823, -0.034192649 } } }, { { { 0.16413327, 0.084074422, 0.10646123, 0.18806073 }, { 0.039511019, 0.058967072, 0.035166958, 0.052296507 }, { 0.26970995, 0.21576211, 0.2954278, 0.29870678 }, { 0.40442043, 0.38744132, 0.14502571, 0.24076804 }, { 0.22655046, 0.20912486, 0.015295019, 0.16442957 }, { 0.69235319, 0.6080183, 0.36756076, 0.23314717 }, { 0.085565328, 0.075535626, 0.22162979, 0.33140596 }, { 0.16109547, 0.11961895, 0.26619212, 0.25941009 }, { 0.27077686, 0.23481238, 0.063446408, 0.11614487 }, { 0.026116057, 0.027491327, 0.030421883, 0.039965345 }, { 0.33922592, 0.38039792, 0.27167385, 0.31510976 }, { 0.32744968, 0.22567102, 0.23116584, 0.18867836 }, { 0.29783431, 0.28054079, 0.26752139, 0.23889932 }, { 0.61721263, 0.60602797, 0.51283622, 0.47601102 }, { 0.51383952, 0.53111455, 0.44519064, 0.42875877 }, { 0.3485879, 0.35374178, 0.53292055, 0.53995494 }, { 0.4366997, 0.35554257, 0.14878367, 0.22083288 }, { 0.12855375, 0.16718264, 0.17583661, 0.11125895 }, { 0.35898096, 0.37222307, 0.35439108, 0.35956111 }, { 0.16773044, 0.25668894, 0.23246756, 0.1506316 }, { 0.36172813, 0.26938211, 0.20069185, 0.1714591 }, { 0.3998571, 0.23607244, 0.34121623, 0.29126696 }, { 0.31471307, 0.29500525, 0.39451396, 0.40013999 }, { 0.29554399, 0.28083636, 0.47190649, 0.47892938 } }, { { 0.01419653, -0.061214452, -0.032506906, 0.0078227125 }, { -0.015799432, 0.0136148, -0.0090824684, 0.013638505 }, { 0.023848919, 0.022034707, 0.022812846, 0.022790329 }, { -0.0026324255, -0.0053566952, 0.00027470228, 0.050203583 }, { 0.0035659857, -0.02015272, -0.039043616, 0.054511651 }, { 0.0052075445, 0.0051043119, -0.011801097, -0.0074336577 }, { 0.020735195, 0.01811747, 0.00808952, 0.01140964 }, { -0.0073139049, 0.011075347, 0.0057685988, 0.010251582 }, { 0.024813488, -0.01629986, -0.012536791, -0.01110061 }, { -0.014508648, -0.021444084, -0.023836972, -0.014258253 }, { 0.0079687141, -0.00092011446, 0.060249601, 0.033199468 }, { -0.020822483, -0.013924875, -0.005068391, -0.016928794 }, { -0.030059, -0.013887475, -0.045329289, -0.04449219 }, { 0.007264541, 0.0015213919, -0.0066322618, -0.0036449174 }, { 0.0057175046, 0.0012159867, -0.00054271896, 0.0020625484 }, { 0.0027083179, -0.0012554897, -0.0044854592, -0.0045242423 }, { -0.017906563, -0.028301884, -0.010139427, 0.0035851304 }, { -0.020245794, 0.01149232, 0.011320484, -0.013561794 }, { 0.0068048997, 0.011957759, 0.0046962412, -0.0015476541 }, { -0.0022514613, 0.019996868, 0.0051520398, -0.023405604 }, { 0.0055213198, 0.0070384134, 0.024405643, -0.02050399 }, { 0.039987541, 0.021127504, -0.012323503, -0.0041538161 }, { 0.0072321478, 0.0053097351, 0.0039966161, 0.013617175 }, { 0.030470642, 0.0044694115, -0.0024591651, -0.0027274707 } }, { { -0.040500402, -0.039657034, -0.017497359, -0.017857145 }, { -0.0015646885, -0.020957371, -0.0057356498, -0.0060587007 }, { 0.0070388709, -0.013205178, -0.00033412934, 0.02192306 }, { -0.0042317723, 0.020620857, -0.012309167, 0.065948811 }, { -0.016686589, 0.013616667, 0.030139062, -0.019023551 }, { 0.015181564, 0.008673659, -0.0014559576, -0.025916054 }, { 0.031630671, 0.027030197, -0.026982415, 0.025214731 }, { -0.003845127, -0.00062884599, -0.029488655, -0.0051457939 }, { -0.0032476351, 0.0021153707, -0.033110808, -0.033629213 }, { -0.0064637077, -0.010805748, -0.014982403, -0.0084641529 }, { 0.0087766042, 0.017780238, 0.026838871, 0.032580257 }, { 0.0010700985, -0.037414784, -0.0053773565, 0.0040969752 }, { -0.02637392, -0.050236074, -0.048422986, -0.069357813 }, { -0.0089483588, 0.0026259727, 0.0040142797, -0.010752754 }, { -0.0025658872, 0.0071106029, 0.015467367, 0.0012536589 }, { -0.0037247444, -0.0036991733, -0.015429566, -0.016148852 }, { -0.024788221, -0.045938054, -0.028679471, 0.011593494 }, { -0.032699114, -0.036800967, -0.033870575, -0.031842203 }, { 0.018156047, 0.02457546, 0.0209432, 0.015057433 }, { 0.0043152638, 0.025831372, -0.019608349, -0.026614397 }, { -0.0057047815, -0.013831909, 0.027613211, -0.043616864 }, { 0.014124478, -0.010786326, 0.010775415, -0.023241344 }, { 0.018337827, 0.0048735321, 0.018371717, 0.022106807 }, { 0.013619207, 0.022051384, 0.0082720974, -0.0030262071 } } } }, { { { { 0.083322661, 0.079807165, 0.03660117, -0.051657142 }, { -0.099216074, -0.0080141573, 0.10637241, 0.0367403 }, { 0.20813681, -0.0001361621, -0.20762563, -0.085913357 }, { -0.22091149, 0.10003156, -0.16122219, 0.31542901 }, { 0.16226908, 0.02665194, -0.012123307, -0.16559939 }, { -0.14025496, 0.025804505, 0.076174345, 0.20548591 }, { 0.0035713609, -0.0092551928, -0.099937652, 0.0038879391 }, { 0.12405732, -0.0053373497, -0.030865175, -0.060934551 }, { -0.0060175826, -0.026583926, -0.075326797, -0.0063155886 }, { 0.036389362, 0.054175433, 0.06490927, -0.038784258 }, { 0.30604876, -0.030813476, 0.011402956, -0.21074796 }, { -0.31769497, 0.046793931, -0.038212559, 0.21137297 }, { 0.12952945, 0.20720126, 0.08525845, -0.14568109 }, { -0.09735197, -0.17799099, -0.12256082, 0.038889119 }, { 0.002114572, 0.026037779, -0.0036772795, 0.13478173 }, { 0.094577863, 0.0057382415, -0.087017736, -0.059444148 }, { 0.054953104, 0.071323301, 0.097417831, 8.3254475e-05 }, { -0.11005534, 0.027214076, 0.0059378205, 0.02443999 }, { 0.27096654, 0.1864966, 0.034810947, -0.25886676 }, { -0.35626794, 0.037256657, -0.17795321, 0.52988269 }, { 0.14913899, -0.0086988732, -0.028760192, -0.21779266 }, { -0.16010301, -0.17699785, 0.017269826, 0.17878541 }, { -0.0049504093, -0.02387924, -0.04034852, -0.060461173 }, { 0.10405347, 0.0072745723, -0.10244372, -0.072981984 } }, { { 0.019363393, 5.327311e-05, 0.0075925373, 0.0019542034 }, { -0.051707557, 0.06554253, 0.0050626046, -0.0061857803 }, { 0.022891698, 0.014872273, -0.020436928, 0.0069081531 }, { -0.044566611, 0.019854557, 0.023600607, -0.0055387351 }, { 0.02283957, -0.067086756, 0.088865856, -0.033915007 }, { 0.0020254431, -0.16422426, 0.032495902, 0.012460808 }, { -0.017316175, 0.023440087, 0.011459595, 0.0043887872 }, { 0.027714908, -0.06907548, 0.013578806, -0.009848884 }, { 0.0044782488, 0.0079432606, 0.010143137, 0.023589488 }, { 0.014325082, 0.0075465848, -0.0079373813, -0.0056032635 }, { 0.025123579, 0.01904807, -0.0092328848, -0.019002052 }, { -0.02633985, -0.019560519, -0.065544737, 0.0073352606 }, { 0.044308433, -0.0032233834, 0.01324206, -0.00047128106 }, { -0.076577611, -0.021853603, -0.020190543, 0.0026420865 }, { -0.0029799448, -0.0083566545, 0.14896601, 0.0078617095 }, { 0.021033237, -0.08234711, -0.020642328, -0.0089829962 }, { 0.043793881, 0.0096494147, 0.035831274, -0.01294602 }, { -0.014064874, 0.066144489, 0.0143429, 0.015113964 }, { 0.043111732, 0.0029232804, -0.016912145, 0.012142059 }, { 0.0014186333, -0.0078590166, 0.065781153, -0.038375123 }, { 0.02255714, -0.030191796, -0.078373164, -0.0017593196 }, { -0.033878798, 0.016266579, 0.013539653, 0.043519216 }, { 0.019046482, 0.0080403173, -0.0010755939, 0.03305222 }, { 0.023206448, -0.054323067, -0.035173093, -0.010873592 } }, { { 0.014068291, -0.026418786, 0.016375695, 0.0048801469 }, { 0.024404214, 0.0073572002, -0.027247654, 0.00093849398 }, { 0.012741523, -0.012913063, 0.0054881373, -0.021780769 }, { -0.020497215, 0.057437717, 0.0031122704, 0.014713732 }, { 0.012765254, -0.052846334, 0.048042201, 0.0016578534 }, { 0.031245254, -0.0469321, -0.057199738, 0.012436479 }, { -0.0022837759, 0.0068501747, 0.010541107, -0.0005227683 }, { -0.0187059, 0.0025631581, -0.0082184266, 0.0026294483 }, { 0.0053899388, -0.0199458, 0.0023448066, 0.016215236 }, { 0.021117204, 0.010868775, -0.016412681, -0.016399297 }, { -0.0026199223, -0.011436548, 0.0031355049, 0.011933919 }, { 0.017940023, 0.090292392, -0.061029038, 0.016388845 }, { 0.0074493061, -0.045849358, -0.082612855, 0.025851315 }, { 0.061276666, -0.024654813, 0.035447334, -0.025952766 }, { -0.0068267167, -0.02207426, 0.003724368, 0.0070458116 }, { 0.021714649, -0.017552721, -0.037105408, 0.024398534 }, { 0.0092901891, -0.021559075, 0.009034776, -0.016574279 }, { -0.017218595, -0.041930302, 0.003369899, 0.017959363 }, { -0.0022510875, 0.028106616, -0.042936548, -0.041948028 }, { -0.017145551, -0.032331654, 0.021486923, -0.020295391 }, { -0.023196465, -0.088353584, 0.010086154, 0.018689553 }, { -0.024508386, -0.00058959302, -0.02867958, 0.019018994 }, { 0.0088748911, 0.012528454, -0.016636351, 0.0078166115 }, { 0.00066772723, 0.001693912, 0.032066885, 0.016951148 } } }, { { { 0.015200105, 0.071414961, -0.020616434, 0.0063982643 }, { -0.084578144, -0.12318522, -0.035470756, 0.057833574 }, { 0.19487946, 0.44043059, 0.10981527, -0.31907303 }, { -0.17774238, -0.30460726, -0.53133003, 0.31186606 }, { -0.1172677, 0.3183613, 0.10375266, -0.066515168 }, { 0.054176263, -0.12382077, -0.033807438, 0.039809238 }, { -5.3634009e-05, 0.004084452, 0.005103199, -0.060697866 }, { 0.06093199, 0.060355274, 0.049176467, -0.060579228 }, { 0.054611799, 9.0520863e-05, -0.048891261, -0.047609349 }, { -0.036428706, 0.06336736, 0.0020843807, 0.033254378 }, { 0.26975732, 0.51328693, 0.29976157, 0.049031141 }, { -0.28383516, -0.48219276, -0.27898799, -0.033028759 }, { -0.078976834, 0.14077934, 0.098587186, 0.051336328 }, { 0.076281206, -0.074223398, -0.053178835, -0.099578331 }, { -0.056377095, -0.00066113896, -0.11597726, 0.058805777 }, { -0.0027130032, 0.12007881, 0.0081935835, -0.10415807 }, { -0.019349408, 0.06206561, -0.0079099126, 0.079363093 }, { -0.059959607, -0.0591041, -0.047505451, -0.0031496967 }, { -0.11419194, 0.20904287, 0.53960104, 0.10467592 }, { -0.21312862, -0.34770872, -0.54593093, 0.23230512 }, { -0.073229448, 0.12913, 0.27728133, -0.050627706 }, { 0.082312471, -0.24529296, -0.12381516, 0.05577292 }, { 0.03015389, -0.0015805638, 0.024306632, -0.080697961 }, { 0.061367564, 0.056058289, 0.041197211, -0.015551356 } }, { { -0.029269776, -0.030251548, 0.01352869, 0.0084860712 }, { 0.053983187, 0.047657625, -0.026379004, 0.022474039 }, { 0.011898439, 0.045120742, -0.024430477, -0.081318878 }, { -0.0012641508, -0.018495044, -0.030127865, -0.0088483264 }, { 0.040728292, 0.010691761, -0.023566342, 0.028045232 }, { 0.014593998, 0.0047006468, -0.049032498, -0.011446808 }, { 0.00045433705, -0.0030610749, -0.010359449, -0.0026455857 }, { -0.0026794352, -0.032142744, 0.010153936, -0.0034586152 }, { 0.0097198782, 0.0051005644, 0.03482872, -0.0043676475 }, { -0.0012381415, -0.025746274, -0.0081178021, 0.0041481596 }, { -0.01598781, 0.0048815642, 0.06313106, -0.0062291669 }, { 0.072970618, -0.041153529, -0.007457013, 0.059776924 }, { 0.0024768493, 0.0093018711, 0.024827984, 0.043842172 }, { -0.012927661, -0.023256709, -0.0035951539, -0.069710027 }, { 0.0064149713, 0.0019783425, 0.010135188, 0.019449636 }, { -0.0071551675, 0.015761815, 0.0086309278, 0.038854386 }, { 0.020978109, -0.0056696814, 0.0025526797, -0.017352926 }, { -0.010711116, -0.0097050903, 0.0022304504, -0.0039308489 }, { 0.036904234, 0.025927127, 0.028330671, 0.051193417 }, { -0.00076391153, -0.077528792, -0.029763477, 0.0033945843 }, { -0.01775202, 0.034507636, 0.065392848, -0.017840909 }, { -0.019567742, -0.019880035, 0.055214211, -0.02206159 }, { 0.01110111, 0.0022938832, -0.011417507, 0.017692635 }, { 0.050208493, -0.028178909, 0.0065276591, -0.0056267473 } }, { { 0.0065622702, -0.0012303136, -0.0081183663, 0.00079383048 }, { 0.030775912, 0.052260356, -0.019758331, -0.020044147 }, { 0.019016537, -0.043070451, 0.035298744, -0.040592775 }, { 0.010468089, 0.00057085185, 0.0081761984, 0.0033382478 }, { 0.047189462, -0.052695409, 0.021849623, 0.033585939 }, { 0.0012065616, -0.050287476, -0.065085924, -0.039012886 }, { -0.012294892, 0.006839242, 0.0051165438, -2.0711078e-05 }, { -0.03292822, 0.015299577, 0.0029119931, 0.0073040242 }, { -0.0086784873, 0.0085910164, -0.0059378411, -0.010259049 }, { -0.014191355, -0.011172486, -0.01299927, 0.015386671 }, { 0.040453224, -0.041489173, 0.015047889, 0.064340197 }, { -0.020000046, 0.058477092, -0.0018150465, 0.048536972 }, { -0.006105982, 0.03437044, 0.0087640339, 0.032868283 }, { -0.027120362, 0.016579996, -0.01708524, 0.011178424 }, { 0.030535528, 0.0058718219, -0.031240404, 0.024241052 }, { 0.003729958, -0.055735848, -0.0055392842, 0.03447519 }, { -0.04084502, -0.01227488, 0.0062970198, -0.021996031 }, { 0.053671675, -0.067787009, 0.0053426012, -0.0080796738 }, { -0.021911856, 0.038395527, -0.07713235, 0.024805484 }, { -0.0034319194, 0.0052741327, 0.026402991, 0.0012916612 }, { -0.033119652, -0.0046506889, 0.045613946, -0.050230593 }, { -0.0054612035, -0.033482221, 0.084267507, -0.0224334 }, { -0.0063348693, -0.0074524817, -0.0029629355, 0.035493958 }, { -0.0073519185, 0.045139911, 0.0022901735, -0.041385515 } } }, { { { 0.99640669, 0.99424882, 0.99911727, 0.99864438 }, { 0.99146493, 0.99235134, 0.99369348, 0.99764995 }, { 0.95848895, 0.89778665, 0.9720248, 0.943828 }, { 0.95896077, 0.9472107, 0.83168251, 0.89623886 }, { 0.97975356, 0.94759472, 0.99452924, 0.98394744 }, { 0.98863213, 0.99196902, 0.99652121, 0.97785007 }, { 0.99999362, 0.99994883, 0.99498061, 0.99814861 }, { 0.99040248, 0.99816269, 0.99831309, 0.99630173 }, { 0.99848953, 0.99964658, 0.9959596, 0.99884607 }, { 0.9986735, 0.99651874, 0.99788899, 0.99869411 }, { 0.91299789, 0.85766372, 0.953946, 0.97631002 }, { 0.90471405, 0.87481454, 0.959534, 0.97684726 }, { 0.9884254, 0.96811612, 0.9914694, 0.98799879 }, { 0.99232241, 0.98122887, 0.99103524, 0.99426948 }, { 0.99840731, 0.99966074, 0.99324506, 0.98912879 }, { 0.99551377, 0.99274778, 0.99617307, 0.9927827 }, { 0.99830144, 0.99552039, 0.99521214, 0.99684577 }, { 0.99211525, 0.9978808, 0.99885333, 0.99969634 }, { 0.95579147, 0.95995838, 0.84120087, 0.96022443 }, { 0.90975235, 0.9368621, 0.81871367, 0.8156339 }, { 0.98610091, 0.99158952, 0.96035822, 0.97468107 }, { 0.98366238, 0.9531543, 0.99215501, 0.98230604 }, { 0.99953301, 0.9997136, 0.99888998, 0.99490315 }, { 0.99267663, 0.998401, 0.99388534, 0.99721201 } }, { { -0.0021537732, 0.010607958, -0.0066166595, -0.0027390442 }, { -0.0069401807, 0.0053215201, 0.0062121114, 0.013403291 }, { -0.0035740125, -0.021839368, 0.00042431197, -0.029478899 }, { -0.007886159, -0.0087705321, -0.010570968, 0.0040635318 }, { -0.0021772698, 0.00025306776, -0.0092725896, -0.0075657706 }, { -0.010438319, -0.0072866821, 0.009272756, 0.0043932916 }, { -0.00058203184, 0.0081284104, 0.027749999, 0.0035426599 }, { -0.003604276, -0.012244348, 0.0072177908, 0.0026686264 }, { 0.011192179, 0.0069527119, 0.017278396, -0.0053058312 }, { -0.020276487, -0.0063228657, 0.013968347, -0.0021534789 }, { -0.0037534313, 0.00061399133, -0.02126817, 0.0085256452 }, { 0.015620795, -0.022637876, 0.00069280338, 0.0054369037 }, { 0.0095244184, -0.0026896982, -0.0057963534, 0.0067237437 }, { -0.0085689961, -0.004816024, -0.00088793436, -0.0034021999 }, { 0.015428153, 0.019777562, -0.011217833, 0.0095744159 }, { -0.003802304, 0.0022643577, 0.0054254827, 0.025560756 }, { -0.0053298651, 0.021621993, -0.01864184, 0.019120967 }, { 0.015380344, -0.0027384467, 0.0010235928, 0.0062792725 }, { -0.001166873, -0.0049586656, -0.014850883, 0.00057841904 }, { 0.0032865456, -0.033386196, 0.0032068954, 0.02854738 }, { 0.010308266, -0.000233004, -0.020287643, 0.0044441043 }, { -0.0040523345, 0.0050367711, 0.01627907, -0.010032412 }, { 0.0073463987, 0.00073274858, 0.002814661, 0.030221018 }, { 0.0057509063, -0.011441338, 0.01894259, 0.0077856453 } }, { { -0.0053054924, 0.0037677068, 0.0066263851, 0.0011220287 }, { -0.02212139, 0.013769097, -0.0013834097, 0.014152363 }, { -0.0008493126, 0.021473024, -0.0039313241, -0.017764981 }, { -0.00081897848, -0.0074161164, 0.0038179092, -0.0035760615 }, { 0.014045643, 0.015317904, 0.0045966739, 0.0075917156 }, { 0.0035574126, -0.00017773424, -0.0010937491, -0.0017762282 }, { 0.0072018344, 0.012586227, 0.0138702, -0.0085424173 }, { -0.0055783456, -0.019909385, 0.01190919, -0.0065821489 }, { 1.7402026e-05, 0.0094513341, 0.015333305, -0.0072158969 }, { -0.0063049905, 0.0021776758, 0.014376378, 0.0072426401 }, { -0.0078049673, 0.028764242, -0.0024169449, 0.0077604105 }, { 0.00047536469, 0.029806623, 0.0017798261, 0.00087410198 }, { -0.0030498401, 0.0044874501, 0.0020382571, -0.0011101062 }, { -0.0057084397, -0.0013428994, -0.001024136, 0.0066188614 }, { 0.039201052, 0.015120258, -0.0082642793, 0.0051985023 }, { -0.0091203243, 0.020790215, 0.0025270937, 0.020092044 }, { -0.0029830063, 0.006602841, -0.00833601, 0.044852353 }, { 0.025206353, -0.0038915173, 0.00045914851, 0.0037840538 }, { 0.0014814254, -0.011573911, 0.046232337, -0.015228958 }, { -0.0071984443, 0.0090004063, 0.022942838, 0.016019787 }, { 0.0050929336, 0.0060892107, -0.0061771339, 0.0047850766 }, { -0.011634853, 0.0010276548, 0.022396644, -0.0021248711 }, { -0.012943002, 0.0016430074, 0.02034928, 0.024289705 }, { 0.0051047037, 0.010052556, 0.0020923265, -0.019043181 } } }, { { { 2.1627647, 2.1788232, 1.9290264, 1.8457806 }, { 2.526488, 2.3020441, 2.538915, 2.03484 }, { 3.9987521, 4.3952121, 3.906821, 4.1693278 }, { 4.0400466, 4.1069844, 5.2512999, 5.4283264 }, { 3.0141968, 3.3306035, 3.2224806, 3.2473051 }, { 2.9840674, 3.1294685, 3.2964833, 3.2929246 }, { 1.8346741, 1.8637353, 2.3037966, 2.0860888 }, { 2.691236, 2.6068079, 1.9349032, 2.1632935 }, { 1.9231956, 1.7251627, 2.1609654, 2.1155629 }, { 2.165771, 2.1908952, 1.777038, 2.0223741 }, { 4.5166991, 4.8674508, 3.918546, 3.378087 }, { 4.4502295, 4.5429338, 3.9552598, 3.3580272 }, { 3.0973598, 3.3953852, 2.2704362, 2.6488177 }, { 3.2110537, 3.3104376, 2.515002, 2.3267785 }, { 1.8303675, 1.7094345, 3.1787979, 2.5960104 }, { 2.4391795, 2.8730077, 2.3730261, 2.1545299 }, { 2.2130903, 2.1899209, 2.4997355, 1.9058674 }, { 2.6472893, 2.5455636, 2.1164596, 1.8341163 }, { 3.9428283, 4.0433678, 4.5430063, 4.2482776 }, { 4.1941673, 4.28852, 4.64044, 4.6644567 }, { 3.0873642, 2.649364, 3.6026133, 3.2426354 }, { 3.2415154, 3.5406745, 3.2976852, 3.3100246 }, { 1.8400289, 1.8404692, 1.889289, 2.0125184 }, { 2.7063995, 2.7229173, 2.6289878, 2.4313709 } }, { { -0.015335928, -0.043382119, -0.0054163805, -0.028249934 }, { -0.017200109, 0.0027582413, -0.079612821, -0.0013966663 }, { -0.027233584, -0.018783395, -0.01183278, -0.020918937 }, { -0.0036358348, -0.015712206, -0.0089146421, -0.0057117233 }, { 0.020392865, 0.017743746, -0.068597326, -0.030425581 }, { -0.041123673, -0.020767538, -0.0087941887, -0.0065248183 }, { -0.0055478408, -0.00082196865, 0.0088521402, -0.045916836 }, { -0.010506485, 0.0078523247, -0.030002306, -0.0015085765 }, { 0.01894068, -0.012424968, -0.034837214, -0.045009941 }, { -0.045299587, 0.02630478, -0.017175711, -0.043601235 }, { -0.046003661, -0.020588165, 0.034398873, -0.054653787 }, { -0.0042534368, 0.01325834, -0.0036369576, -0.079162988 }, { -0.028728556, 0.0051289128, 0.012104313, 0.010686997 }, { -0.066337767, 0.00059928728, -0.080303668, 0.011318772 }, { -0.031879871, 0.0011317962, -0.050259029, 0.0031596552 }, { -0.090121238, -0.011196084, -0.072456123, -0.00079731072 }, { -0.024243475, 0.021401076, -0.018209385, -0.0083196072 }, { -0.079888701, 0.0032806631, -0.12762259, -0.04652308 }, { 0.031806075, -0.034165157, -0.015255921, -0.049164663 }, { -0.0012051123, 0.030788487, 0.022291919, 0.0025694519 }, { 0.035836509, 0.0055365388, 0.026704836, 0.0001547235 }, { -0.012129747, -0.0094322145, -0.040637935, -0.12125388 }, { -0.027044986, 0.04531553, -0.033484589, -0.0059927923 }, { 0.0067188802, -0.051166351, -0.048822794, -0.025926988 } }, { { 0.022049053, 0.021265778, -0.040370641, -0.036232952 }, { -0.0058098424, -0.0042264198, -0.077428509, -0.04241654 }, { -0.0026825379, -0.029453318, -0.016181275, -0.028320229 }, { -0.012541692, -0.01345735, 0.00037814888, -0.0046052489 }, { -0.026527394, 0.020033638, -0.025683861, -0.084207169 }, { -0.0010459945, -0.036745215, -0.039772051, 0.024810839 }, { 0.012134618, 0.0068515798, -0.035286972, 0.043129595 }, { -0.077093357, -0.026872688, 0.032800133, -0.090326706 }, { 0.13930909, 0.0081274014, -0.08349188, -0.012200005 }, { -0.091693797, -0.012567011, -0.069736822, -0.0061444184 }, { -0.053061301, 0.003642159, 0.0052515175, -0.036957472 }, { 0.0043493933, -0.013069332, -0.014708126, -0.032765039 }, { -0.016116105, -0.022907609, -0.043503106, -0.013266465 }, { -0.072759977, -0.077354585, 0.0043827591, -0.013821612 }, { -0.032399073, -0.045305037, -0.021840791, 0.073996542 }, { -0.057239255, -0.056581235, -0.038880927, 0.044102943 }, { -0.026951489, -0.088667645, -0.013659704, 0.033527579 }, { 0.034815442, -0.028634059, -0.036666529, 0.011546036 }, { 0.026688447, -0.0081892129, -0.031138092, -0.041739155 }, { 0.0015665701, -0.012701682, 0.0013533943, -0.002849785 }, { 0.032994636, 0.008802974, 0.019032649, 0.0039042621 }, { -0.044544917, 0.0093201326, -0.017968915, 0.01936344 }, { -0.034794535, 0.043032983, -0.051072531, -0.040148303 }, { -0.0030398597, -0.027112065, -0.064007483, -0.01798277 } } }, { { { 0.22040906, 0.24911942, 0.41660708, 0.23632869 }, { 0.25894466, 0.1416669, 0.41902981, 0.35717608 }, { 0.26918091, 0.14566759, 0.2147652, 0.15769391 }, { 0.22500921, 0.12113361, 0.11151768, 0.12348609 }, { 0.25699055, 0.056819107, 0.3859882, 0.4585378 }, { 0.7304995, 0.20719358, 0.44455636, 0.42226989 }, { 0.43602897, 0.51049581, 0.41978824, 0.62521039 }, { 0.42004119, 0.52912054, 0.33314238, 0.38257921 }, { 0.55092562, 0.43085653, 0.31149977, 0.34391138 }, { 0.40391149, 0.48820255, 0.13569806, 0.36060266 }, { 0.13647907, 0.12061002, 0.20668806, 0.30221394 }, { 0.15583476, 0.13133696, 0.22775202, 0.35653823 }, { 0.56336195, 0.25684627, 0.11118383, 0.23109245 }, { 0.45430401, 0.42843367, 0.25496534, 0.097473509 }, { 0.3420223, 0.39418925, 0.26458947, 0.30588082 }, { 0.51345558, 0.3612731, 0.41151773, 0.25269512 }, { 0.29195176, 0.42659964, 0.47971993, 0.32714756 }, { 0.49222777, 0.28477645, 0.74993827, 0.43781271 }, { 0.098434481, 0.31164923, 0.14486345, 0.11466693 }, { 0.070833248, 0.20569754, 0.10233576, 0.047352701 }, { 0.51050902, 0.15597643, 0.1417112, 0.35581415 }, { 0.48261165, 0.14592221, 0.62554576, 0.5209765 }, { 0.33562628, 0.39920067, 0.28183433, 0.297464 }, { 0.366851, 0.59278666, 0.59095922, 0.48385165 } }, { { 0.13792051, 0.072076744, 0.094800532, 0.026318377 }, { 0.13607414, -0.061382542, 0.061800151, -0.020060553 }, { 0.028096406, 0.069282616, 0.010195109, -0.010461141 }, { 0.018651237, 0.02642439, 0.0077552848, -0.051151646 }, { 0.098299803, -0.0085081153, -0.011764584, 0.087405711 }, { 0.064082346, -0.04626424, -0.071480607, 0.064447268 }, { 0.022766233, 0.0167542, -0.021285286, -0.071637286 }, { -0.0202445, 0.011692601, 0.048325551, 0.0097755172 }, { -0.027775183, 0.016463115, 0.060050391, -0.034226107 }, { 0.019412547, 0.059977501, -0.0041737169, 0.031539317 }, { 0.013192979, 0.036015595, -0.049943198, 0.014112312 }, { -0.013272349, 0.035821037, -0.060503687, 0.095316821 }, { 0.038338785, -0.059038809, -0.044954172, -0.00051347307 }, { -0.039594082, 0.018205882, 0.13413799, 0.012292954 }, { 0.015177594, -0.0082493854, 0.00029420179, 0.010356248 }, { 0.100271, -0.13623174, 0.1121235, 0.068902399 }, { 0.025189636, 0.0014918434, 0.0088847718, -0.053714493 }, { 0.06487698, -0.097217547, -0.069537353, 0.032490984 }, { -0.030729608, 0.048956315, 0.016036034, 0.022485239 }, { 0.049839618, 0.01148525, -0.021032427, -0.019665817 }, { -0.0037762817, -0.030422275, -0.062343207, 0.057994884 }, { 0.014035184, -0.021387762, -0.080846143, -0.020681511 }, { -0.03594567, 0.026862531, 0.078975557, -0.034056659 }, { -0.014490672, 0.026128902, 0.045617611, 0.090192953 } }, { { 0.011904288, -0.014624471, 0.042023114, 0.019592867 }, { 0.032705848, 0.00038558691, 0.031901745, 0.027208951 }, { -0.044369719, -0.039761364, -0.013366816, -0.019308126 }, { -0.019051023, -0.00015767269, -0.082968285, -0.035266053 }, { -0.004775162, 0.010889271, 0.0089521094, 0.027037104 }, { 0.005616143, -0.00099668486, 0.0068716426, -0.12649184 }, { 0.018531199, 0.023881776, -0.053798787, -0.041912909 }, { -0.0036187094, 0.11590788, 0.025140733, 0.022280209 }, { -0.02994342, -0.026293799, -0.017204658, 0.044901944 }, { 0.079892089, 0.10816526, 0.14667807, 0.027301352 }, { -0.045296738, -0.066748968, -0.0099354431, -0.070369692 }, { -0.08357374, -0.043311901, 0.013163375, -0.0881777 }, { -0.065923811, -0.10382274, 0.090440302, -0.013617198 }, { -0.092578587, -0.010178017, -0.01416593, 0.0432333 }, { 0.055172515, 0.10021805, -0.0062782668, -0.11791805 }, { -0.039684132, -0.08934283, 0.020686084, -0.0013788117 }, { 0.064624676, 0.051773746, 0.0045383964, -0.037696971 }, { -0.066296373, 0.020570689, -0.017742721, -0.022651449 }, { -0.0061572447, -0.094510525, -0.094775804, -0.038022514 }, { 0.0055683313, 0.039513342, -0.096815654, -0.0065483011 }, { -0.03311602, -0.018395457, 0.0028464434, -0.088048272 }, { -0.073106109, -0.055187863, -0.093209932, -0.10155137 }, { 0.042841842, -0.005778703, 0.074069607, -0.025841052 }, { -0.018569637, 0.063144303, 0.02291584, 0.005525742 } } } }, { { { { -0.20809663, -0.18346453, -0.072140694, -0.0078104407 }, { -0.19490097, 0.25712922, 0.37640771, 0.11563399 }, { 0.26894915, -0.33477877, -0.093739129, -0.55078405 }, { -0.65794103, 0.09211629, -0.19166986, 0.5574327 }, { 0.45579532, 0.23202083, 0.19626303, -0.64130523 }, { -0.018763975, -0.24981569, -0.32514026, -0.11121342 }, { 0.22376238, 0.09515938, 0.071728264, -0.02790747 }, { -0.3053338, 0.34023365, 0.099862481, 0.26163964 }, { -0.21722968, -0.094881958, -0.086364431, -0.0081863581 }, { -0.16090709, 0.23527698, 0.28947119, 0.11309742 }, { 0.26447184, -0.33536416, -0.096418234, -0.26201294 }, { -0.56343769, -0.041662822, -0.24873841, 0.67122901 }, { 0.35362642, 0.2577592, 0.2009013, -0.74233681 }, { -0.047956299, -0.54973418, -0.4958485, -0.12453303 }, { 0.06917425, 0.080509853, 0.0090863722, -0.023518805 }, { -0.27000602, 0.083167162, 0.12715558, 0.12397839 }, { -0.11376964, -0.079199259, 0.019676685, -0.0094352472 }, { -0.19185851, 0.22193112, 0.28110877, -0.06422845 }, { 0.084091992, -0.16151548, 0.091400556, -0.28257376 }, { -0.53821376, 0.21718328, -0.2234907, 0.52302804 }, { 0.71322306, 0.042728493, 0.13229522, -0.61892094 }, { 0.15270046, -0.26304886, -0.33110633, -0.052728951 }, { 0.072398971, 0.25829764, 0.25881687, -0.020942042 }, { -0.26788161, 0.055822039, 0.33817103, 0.42061402 } }, { { 0.088248648, 0.091306255, 0.020476927, 0.0030144802 }, { 0.0087376707, 0.043816157, 0.0022807168, 0.016745414 }, { -0.13412414, 0.12686539, 0.060531476, 0.044582027 }, { 0.019204757, -0.0070891897, 0.091194602, 0.065258927 }, { -0.10429513, -0.027665602, -0.064350626, 0.0053147478 }, { 0.069218141, -0.035018324, -0.088257571, 0.019279642 }, { -0.073137338, 0.040764456, -0.022352804, 0.031743288 }, { 0.040325697, -0.12840825, -0.009582113, 0.034509657 }, { 0.081971224, -0.0035223125, -0.051728499, 0.0038899717 }, { 0.050968435, 0.022254651, 0.18781134, -0.032392139 }, { 0.024342518, 0.13929014, -0.019175435, -0.0011608234 }, { -0.0021942487, -0.01251222, 0.024263454, -0.063179344 }, { -0.13071776, -0.059221747, -0.034153238, 0.036561209 }, { 0.054124093, 0.070495803, 0.081441614, 0.051900357 }, { 0.027480327, 0.028940343, -0.01469313, 0.032388411 }, { -0.039696828, -0.0069393798, -0.011361641, 0.035031025 }, { -0.039730763, 0.0085971581, -0.0077461932, -0.040735188 }, { 0.10893368, 0.00014757217, 0.025489178, -0.11388774 }, { -0.0013816669, 0.0031148929, 0.10281666, -0.019860642 }, { -0.065093128, -0.11495815, 0.041783056, -0.091373461 }, { -0.044985581, 0.0012713031, -0.16078032, 0.17303747 }, { -0.038132358, -0.02995975, -0.037612782, 0.012575173 }, { 0.0042976619, 0.027014275, 0.017518808, 0.030405184 }, { -0.0015298607, 0.029297664, -0.1034349, 0.023450502 } }, { { 0.028785558, -0.028708377, -0.010459636, 2.8360915e-05 }, { 0.091634877, 0.021214811, 0.12282079, 0.080617943 }, { -0.29287977, 0.045481846, 0.014712563, 0.057317576 }, { -0.10728772, 0.03268482, 0.015167285, -0.011256231 }, { 0.09337321, 0.037150859, 0.052549202, -0.042671474 }, { -0.0041288689, -0.024299997, -0.11357403, -0.022045772 }, { -0.041469935, -0.0071353646, -0.0086607538, 0.008536762 }, { 0.033629272, -0.0070042955, -0.037864853, -0.0055907778 }, { 0.016404597, -0.0055321059, -0.020989839, -0.013771265 }, { 0.042552435, 0.04428518, 0.0030587466, 0.044894182 }, { -0.027600219, 0.026831779, 0.051120849, -0.032184808 }, { 0.13870554, 0.15273282, 0.049260112, 0.043371121 }, { -0.018453269, -0.18061413, 0.24805649, -0.031741165 }, { -0.085137374, 0.025935867, 0.015978067, 0.067726486 }, { 0.072393868, 0.0050430488, 0.0016664585, 0.0072097064 }, { 0.033840162, 0.082225764, -0.079387016, 0.033165625 }, { 0.033170766, 0.0012231618, -0.066984982, 0.051671704 }, { 0.017894231, -0.012267532, 0.045536123, -0.07327109 }, { 0.0073109731, -0.063797898, -0.13446413, 0.1408986 }, { -0.045702456, -0.1647051, -0.14336468, 0.054543693 }, { 0.0042448876, -0.13234456, 0.092181719, -0.10440841 }, { -0.060020212, -0.011098469, -0.030257182, -0.030922037 }, { -0.018118661, 0.00067983745, -0.0061776598, -0.031721273 }, { -0.019885189, 0.094157888, 0.014017961, -0.051373389 } } }, { { { 0.12415319, -0.13611564, -0.029441661, -0.14143497 }, { -0.26074418, 0.011913326, -0.033328425, 0.43248793 }, { 0.19336432, 0.37269586, 0.36803538, -0.51720719 }, { -0.15185913, -0.47431781, -0.6593667, 0.23163184 }, { 0.18276216, 0.19248743, 0.65453332, 0.54748087 }, { 0.17751443, -0.0020337696, 0.08506463, -0.40147769 }, { -0.11370932, 0.11523476, -0.010573025, 0.082295392 }, { -0.13666335, -0.32747478, -0.16897386, 0.15359006 }, { 0.11716326, -0.12259922, 0.0033396256, -0.13240653 }, { -0.27776876, -0.10222241, -0.039920479, 0.35499708 }, { 0.090003723, 0.3313923, 0.1871549, 0.003163675 }, { -0.51626118, -0.76341562, -0.56326874, 0.20153559 }, { -0.34172723, 0.26975563, 0.67520079, -0.1252004 }, { 0.45758078, -0.19142179, 0.064180031, -0.48748431 }, { -0.12800789, 0.1399912, 0.0077954775, 0.14379741 }, { -0.13042104, -0.45670817, -0.18831095, 0.0032738639 }, { 0.12446807, -0.11504524, -0.027331682, 0.03861758 }, { -0.31337986, -0.11842668, 0.033415325, 0.45344231 }, { 0.11463107, 0.077427841, 0.060880794, -0.069619455 }, { -0.37772106, -0.59628905, -0.65426572, 0.065297039 }, { 0.29532991, 0.75920243, 0.53294265, -0.15002562 }, { 0.3618333, 0.10488387, 0.36007528, -0.30963565 }, { -0.13738196, 0.20795596, 0.029274703, 0.18017599 }, { -0.10290023, -0.48517535, -0.33278584, 0.56477854 } }, { { -0.0047891472, 0.024629901, 0.015256654, -0.0084462001 }, { 0.056227746, -0.048057782, -0.15671312, 0.06418471 }, { -0.070093217, -0.018057199, 0.062026545, -0.051053726 }, { -0.0091221476, 0.0020547295, -0.087729813, -0.10164738 }, { 0.098917091, -0.066835916, 0.083151519, 0.006342544 }, { 0.0013540606, 0.038719082, 0.036333261, -0.053178668 }, { 0.0083787438, 0.0028359378, 0.0089872852, 0.031308249 }, { 0.014379686, -0.079563474, -0.079160006, -0.016352226 }, { 0.0091376645, -0.016678006, -0.044636785, -0.0011035265 }, { 0.0099146109, 0.027589302, -0.09494437, 0.07451767 }, { 0.017453983, 0.080674871, 0.06341808, 0.048820473 }, { 0.02794057, 0.058230195, -0.010793601, 0.091813872 }, { -0.049633232, -0.1142016, 0.036984283, 0.0034294865 }, { 0.047712957, 0.10161366, 0.13774722, 0.039503136 }, { 0.014194782, -0.014555183, -0.00053182909, 0.0019143477 }, { 0.0014900262, 0.0056176356, -0.034517871, -0.0010707988 }, { 0.013287784, -0.0073967933, -0.019271341, 0.016354896 }, { -0.10345626, 0.023536634, 0.027943639, -0.015686972 }, { -0.025193395, -0.10224801, 0.078686884, -0.048574399 }, { 0.15797878, -0.0012322757, -0.036096649, -0.23983963 }, { -0.10455507, -0.056368102, -0.06570944, 0.29104616 }, { 0.05155239, -0.040940824, -0.038367594, 0.058174485 }, { 0.010471732, -0.066952904, -0.047763843, -0.021124742 }, { -0.033555686, 0.0049111983, -0.026592789, 0.014438586 } }, { { -0.0048440946, 0.025915095, -0.018325403, 0.022133613 }, { 0.059240081, -0.031272176, -0.12967647, -0.17957913 }, { 0.0574837, 0.067005152, 0.024644254, 0.10786296 }, { 0.067084865, 0.008513386, 0.04077659, 0.10587924 }, { 0.026332643, 0.1072618, -0.098375042, -0.001724609 }, { -0.021386362, -0.0020174921, 0.16800158, 0.081359882 }, { -0.018204146, -0.026432136, -0.0068153455, -0.029997667 }, { -0.043221501, -0.016869967, -0.067406967, -0.024965804 }, { -0.0033879999, 0.031310818, -0.010853802, 0.00088944004 }, { -0.068991006, 0.087874253, -0.15737392, -0.088870044 }, { 0.061763806, -0.00072874343, -0.009915009, -0.0178225 }, { -0.07340717, 0.080339271, -0.0027124572, -0.13078641 }, { -0.023682834, 0.16512313, -0.15784472, 0.047978827 }, { 0.0063250439, -0.09953777, 0.094180888, 0.010565041 }, { 0.010047311, -0.042999009, -0.012483998, -0.016966759 }, { -0.048612679, 0.051708319, 0.015059148, 0.0036776472 }, { -0.011737015, -0.0027276603, 0.026535075, -0.065453876 }, { 0.056388137, 0.061461073, -0.12726984, -0.025578248 }, { 0.0016833003, 0.10878558, 0.13254828, -0.017098914 }, { -0.031606282, -0.072245098, 0.12724789, -0.21852899 }, { -0.062502612, -0.073402771, -0.049624729, 0.069066032 }, { -0.075837195, -0.10297347, -0.07249237, -0.11538062 }, { -0.015644005, 0.039474396, 0.074415075, -0.038881161 }, { -0.040175911, 0.034030267, 0.03947059, 0.014167463 } } }, { { { 0.97019677, 0.97355703, 0.99695983, 0.98991674 }, { 0.94552952, 0.96630359, 0.92585444, 0.89419404 }, { 0.9435447, 0.86545998, 0.92507456, 0.65508294 }, { 0.73759908, 0.87552111, 0.72697883, 0.79725496 }, { 0.87111918, 0.95347518, 0.73011435, 0.53758004 }, { 0.9839393, 0.96829127, 0.94183216, 0.90909143 }, { 0.96798791, 0.98876976, 0.99736817, 0.99621717 }, { 0.9423876, 0.88147679, 0.98054848, 0.95286662 }, { 0.96906348, 0.98791034, 0.99625801, 0.99116169 }, { 0.94707625, 0.9665378, 0.9563539, 0.9280011 }, { 0.96018435, 0.88187869, 0.97758711, 0.96505917 }, { 0.64499021, 0.64456248, 0.78794513, 0.71332673 }, { 0.87073007, 0.92778882, 0.70974824, 0.65822558 }, { 0.88787388, 0.81311133, 0.86603417, 0.86420517 }, { 0.98935782, 0.98687417, 0.99992833, 0.98932764 }, { 0.95398485, 0.88572054, 0.97384313, 0.99227952 }, { 0.98567955, 0.99019799, 0.99943274, 0.99920952 }, { 0.93004482, 0.96784384, 0.95909399, 0.88896838 }, { 0.98984254, 0.98382807, 0.99395144, 0.95671584 }, { 0.75342733, 0.77283296, 0.72248756, 0.84981055 }, { 0.63568318, 0.6494505, 0.83574524, 0.77099234 }, { 0.91965169, 0.95906448, 0.87218942, 0.94939213 }, { 0.98786871, 0.94341754, 0.96548269, 0.98341143 }, { 0.95794101, 0.87263324, 0.8802806, 0.71000638 } }, { { -0.0064390277, 0.051629953, -0.011423447, 0.032337826 }, { 0.055030538, 0.061305324, -0.016012659, 0.083766345 }, { 0.052467122, 0.018425134, -0.00054737782, 0.048038459 }, { 0.076436505, 0.016815709, -0.024174832, -0.00829119 }, { 0.057903371, 0.068822104, -0.0064003131, 0.00010695928 }, { 0.067104151, 0.067284611, 0.0074295447, 0.024215238 }, { 0.073380541, 0.01486405, 0.01523157, 0.012966612 }, { -0.0002536971, 0.010628632, 0.00045031869, 0.041891438 }, { 0.055922922, 0.0090823157, 0.011101162, 0.033807592 }, { -0.040264953, 0.022318628, -0.013682045, -0.016112502 }, { -0.034286564, 4.7089727e-05, -0.013030079, -0.012231424 }, { 0.027756308, 0.084041595, 0.018308393, 0.11564334 }, { 0.0026690817, 0.058149333, -0.013682964, 0.052975934 }, { -0.03852481, 0.063493354, 0.059460027, 0.047740976 }, { 0.026410264, -0.0073902435, 0.022353771, 0.012987341 }, { 0.035217135, -0.0023455309, -0.0055505614, 0.010102857 }, { 0.00075590283, 0.038624793, -0.0040614962, 0.070039437 }, { -0.02318411, 0.04527054, 0.013119286, 0.025335215 }, { 0.021268391, 0.044855911, 0.012622905, 0.04827088 }, { -0.0046678346, -0.01934799, 0.018393432, 0.09750434 }, { 0.12480373, 0.059151139, 0.055196092, 0.26701338 }, { -0.0096669036, 0.065624767, 0.016918517, 0.028425135 }, { 0.026488514, -0.0037618693, 0.0077028717, 0.041713399 }, { 0.018628451, 0.033145064, 0.029067918, -0.000924258 } }, { { -0.043525781, 0.028119778, -0.011653105, -0.020930158 }, { -0.028099186, 0.017594088, -0.099226445, 0.10408808 }, { 0.11750066, -0.0010629746, 0.018381448, 0.096538552 }, { 0.0010069446, 0.013799541, 0.1325137, 0.020820734 }, { -0.053571928, -0.0066793785, 0.14596488, -0.03272949 }, { 0.028507895, 0.015474376, -0.025411653, 0.037264272 }, { 0.033698911, 0.018088387, 0.0038898537, 0.03163178 }, { 0.0057766828, 0.015879322, 0.012557033, 0.071771631 }, { -0.0044521866, 0.0083963511, -0.0020426175, 0.023784146 }, { -0.011508765, 0.0075020051, 0.0018808294, 0.040843424 }, { 0.0085150894, 0.0056891711, 0.010134672, 0.046224768 }, { 0.040825446, 0.10099754, 0.021853299, 0.024507528 }, { -0.0055958303, -0.0060958, 0.1115321, -0.021701014 }, { 0.010487817, -0.010033143, -0.031203025, 0.054265436 }, { 0.0040500672, 0.0053935875, 0.018233022, 0.018797311 }, { 0.064057639, 0.014318185, 0.0199119, 0.014366235 }, { 0.02411682, 0.045454692, 0.0030084434, 0.019464939 }, { 0.012500289, 0.027734846, 0.0025097372, 0.047343669 }, { 0.037625829, -0.00064472688, 0.0557556, 0.04785655 }, { 0.0020433437, 0.019929208, 0.087936103, -0.036738471 }, { 0.020811556, 0.0915387, 0.055445303, -0.065132763 }, { 0.03911814, 0.043721622, 0.0074336204, -0.031370424 }, { 0.014072509, -0.014795458, 0.010517063, 0.022409628 }, { -0.0054107234, 0.055313602, 0.053556404, 0.048574319 } } }, { { { 3.4224197, 3.3162336, 3.1136621, 3.3189801 }, { 4.0715355, 3.5614196, 4.1797877, 4.0959601 }, { 4.3979407, 4.1858272, 4.3116447, 4.5467451 }, { 4.4920032, 4.0716439, 4.6107962, 4.5268016 }, { 5.6570832, 4.9036495, 4.7373547, 4.7259419 }, { 3.3277827, 3.6015237, 4.226646, 3.7939772 }, { 3.4893058, 3.3260638, 3.0626103, 3.1798705 }, { 3.6423735, 4.1092281, 3.3264203, 3.7325301 }, { 3.4756581, 3.2550256, 3.224671, 3.4093307 }, { 3.8511362, 3.4821381, 4.3232597, 3.7357164 }, { 3.6688024, 4.0797971, 3.4140927, 3.6881261 }, { 4.5298469, 4.7472506, 4.4046473, 4.7279944 }, { 4.1614448, 4.1242955, 4.6741969, 5.0037875 }, { 4.3148703, 4.3815566, 4.1976536, 3.9032858 }, { 3.2640506, 3.3214728, 2.9463564, 3.3562068 }, { 3.6729325, 3.9218642, 3.4550701, 3.4833871 }, { 3.435975, 3.3079446, 3.3432341, 3.3632985 }, { 3.8404619, 3.4716915, 3.858149, 3.8677391 }, { 3.3181827, 3.8403872, 4.0363918, 3.9604287 }, { 5.0916792, 5.2773748, 4.5404255, 4.377031 }, { 4.6514614, 4.7569957, 4.1233238, 4.4022582 }, { 3.6884833, 3.6283543, 4.1874612, 4.2963913 }, { 3.456705, 3.6250566, 3.5292789, 3.1420033 }, { 3.5986317, 4.0596074, 4.0696874, 4.5327067 } }, { { -0.12592901, -0.14780788, -0.11051274, -0.18767653 }, { -0.020435093, 0.0055221209, -0.021183195, -0.15159792 }, { 0.022498629, -0.025100789, -0.30939177, 0.016420202 }, { 0.21296442, -0.042976575, 0.082118132, 0.14574735 }, { -0.13608022, 0.16141834, -0.015091164, 0.044951541 }, { -0.08235774, -0.10333151, 0.089785432, -0.036620639 }, { -0.17664465, -0.015842477, -0.083075331, -0.15660828 }, { -0.11292423, -0.072894494, -0.068901923, -0.2283674 }, { -0.19063437, -0.071954393, 0.091375283, -0.26993547 }, { 0.042798331, -0.06495575, 0.050221766, 0.024602586 }, { -0.026228614, 0.0049810367, 0.046584088, -0.13067577 }, { 0.072779737, -0.023369437, -0.030275791, 0.19591126 }, { -0.018649072, 0.029208952, 0.012033439, 0.00094798196 }, { -0.094599446, 0.0070746366, -0.0007115864, -0.040175552 }, { -0.027599009, -0.068747365, 0.19480498, -0.19423733 }, { -0.076671551, 0.0075475135, 0.019853903, -0.012984601 }, { 0.064371855, -0.24044027, -0.043765356, 0.0016424127 }, { -0.076744435, 0.035881398, 0.12967612, 0.081825243 }, { -0.15224256, 0.032665115, -0.027927205, 0.076091133 }, { -0.0057973613, -0.14914213, -0.047678749, -0.037214457 }, { 0.10060085, -0.099197666, -0.22704457, -0.0020812401 }, { -0.070664558, -0.13179176, -0.014217065, -0.030410253 }, { -0.12286487, -0.046623366, -0.10695394, -0.0081383175 }, { -0.14561788, 0.02765909, 0.10439783, 0.033139041 } }, { { 0.0063171031, -0.0047223477, -0.056312039, -0.065065766 }, { -0.0059575982, -0.062348475, 0.069540315, -0.090331962 }, { 0.10218203, 0.050383376, -0.0089914697, -0.037837343 }, { -0.0037657879, 0.18278082, 0.079014627, -0.052587294 }, { -0.33929282, 0.018522098, 0.0078923893, 0.042545349 }, { 0.027294929, -0.086490439, -0.0057363347, -0.035932082 }, { -0.061716003, -0.14470599, 0.033117786, -0.08112808 }, { 0.16414856, 0.082471596, -0.058497326, 0.050552718 }, { -0.07627083, -0.0064181717, -0.031179581, -0.075705068 }, { -0.057808009, -0.00074561624, -0.23990956, 0.018671772 }, { 0.1677602, 0.10757253, 0.028015134, -0.23923178 }, { 0.078827365, 0.068682485, 0.056277532, -0.069749241 }, { 0.079502977, 0.05526585, 0.0089767144, -0.15319341 }, { -0.038594242, -0.055488998, -0.043132461, 0.054313031 }, { 0.12890592, -0.082639555, 0.22520491, -0.026781096 }, { -0.071292391, 0.064592881, -0.050368563, -0.072488866 }, { 0.092998671, 0.12152394, 0.033318795, -0.039691417 }, { -0.0049706273, -0.0014175115, -0.11634604, 0.15219284 }, { -0.012414906, 0.035583927, -0.072463074, -0.058394705 }, { -0.071558898, -0.00093653835, 0.013149622, 0.01495775 }, { -0.057103279, 0.013702583, -0.020242751, 0.04649072 }, { -0.083398977, -0.20123674, 0.062758815, -0.043671819 }, { 0.084479675, 0.17868517, -0.021185269, 0.15711776 }, { 0.11862504, 0.079985297, 0.063556911, 0.14639069 } } }, { { { 0.48018566, 0.17712962, 0.45065949, 0.76214707 }, { 0.37788335, 0.385421, 0.24766167, 0.3647243 }, { 0.45095873, 0.2634498, 0.37824131, 0.10713483 }, { 0.18808611, 0.27852978, 0.23671202, 0.23174978 }, { 0.39404781, -0.7399413, 0.28511918, 0.026007027 }, { 0.46587668, 0.46802177, 0.36697974, 0.23706778 }, { 0.48925391, 0.42086488, 0.49570155, 0.45137287 }, { 0.30655255, 0.35196398, 0.23019387, 0.50586011 }, { 0.45798975, 0.34137244, 0.33289763, 0.54218519 }, { 0.42271216, 0.38700914, 0.48791862, 0.15025833 }, { 0.7282781, 0.37956244, 0.25156645, 0.51632504 }, { 0.084933462, 0.15576738, 0.16469359, 0.29684651 }, { 0.34570877, 0.34912791, 0.26663435, 0.11188061 }, { 0.48552914, 0.19012867, 0.12677402, 0.1234341 }, { 0.2190939, 0.41431469, 0.64823269, 0.51846746 }, { 0.49289149, 0.29829354, 0.29090992, 0.36465152 }, { 0.50568056, 0.64150077, 0.40217634, 0.53523743 }, { 0.24945735, 0.47058801, 0.29099852, 0.25452114 }, { 0.49039753, 0.26327736, 0.39431507, 0.50632023 }, { 0.19678915, 0.031547614, 0.22295107, 0.26300048 }, { 0.12409997, 0.11506147, 0.19327618, 0.2174585 }, { 0.15319333, 0.39177705, 0.38498586, 0.25972804 }, { 0.69027161, 0.37279682, 0.31143504, 0.23440833 }, { 0.39682066, 0.3156927, 0.36369313, 0.14308402 } }, { { 0.15030994, 0.15410005, 0.0072554408, -0.22242826 }, { -0.032421729, 0.22531436, 0.22185899, -0.022703209 }, { 0.070341052, 0.30237173, 0.047916387, 0.03629681 }, { -0.024283222, 0.075614195, 0.013940033, -0.016841468 }, { 0.077729482, 0.19455394, -0.02162282, -0.018761003 }, { -0.22986895, 0.18914992, 0.14483608, 0.11173921 }, { 0.14132894, -0.0081864768, -0.11405791, 0.031777789 }, { 0.38775389, 0.0085565642, -0.057167843, 0.09784167 }, { 0.079102739, 0.030530894, 0.041954967, 0.02957611 }, { 0.076915126, 0.18656729, 0.044218872, 0.22478833 }, { 0.017173879, 0.11961351, -0.085099523, 0.22720323 }, { 0.030466202, 0.095221887, -0.042982583, -0.069264747 }, { 0.041170442, -0.090598444, -0.021082598, -0.028016784 }, { -0.082581617, -0.023712106, 0.32427665, 0.1010696 }, { 0.19197752, 0.10900527, -0.0053794951, 0.068553764 }, { 0.18674269, 0.028895321, -0.053421028, 0.063918058 }, { 0.044090722, -0.054247791, 0.05585954, -0.13406746 }, { 0.08358642, -0.032301886, 0.010371619, 0.099505528 }, { 0.16467816, 0.044994571, -0.0045949279, 0.0626774 }, { 0.12942209, 0.092097891, 0.019866495, 0.10340014 }, { 0.037094903, 0.13829877, 0.15116473, -0.048632499 }, { 0.10749044, 0.14329542, -0.061272024, -0.1536028 }, { 0.097716907, 0.044246181, 0.056664419, 0.15804873 }, { 0.031819999, 0.10132976, 0.079198524, 0.017871462 } }, { { 0.056219172, 0.08683492, -0.061488015, 0.065746152 }, { 0.088983664, 0.19773741, -0.096766599, 0.16352101 }, { -0.0097043787, -0.040925999, 0.097458334, 0.032319634 }, { -0.024873518, 0.057873123, -0.0059256291, -0.057498398 }, { -0.13355098, 0.39190863, 0.017449142, -0.0076009344 }, { 0.10319658, 0.22069551, -0.098795717, 0.10603434 }, { 0.090765308, 0.13803326, -0.070647945, 0.14557561 }, { -0.068457348, 0.058955208, -0.050501105, 0.02914144 }, { 0.10363866, 0.060231993, 0.027681685, 0.079659088 }, { 0.01269983, 0.11977996, -0.049648315, 0.089882363 }, { -0.072877286, 0.019348792, 0.13977764, 0.055396044 }, { 0.028834456, -0.1084196, -0.0043985215, -0.072640844 }, { -0.040232522, 0.051835989, -0.02198193, 0.016421295 }, { -0.087848469, -0.04621504, 0.099259188, -0.0025909067 }, { 0.3000131, 0.10526775, 0.016890366, 0.12892588 }, { -0.021028821, -0.024429075, 0.088067677, -0.084594075 }, { 0.086861805, -0.045902006, 0.0058222123, -0.0075466204 }, { 0.14411905, 0.036488937, 0.05091815, 0.16385101 }, { 0.1576814, 0.043890956, -0.064244298, -0.087234754 }, { -0.071100004, 0.16782304, -0.10860149, -0.1601076 }, { 0.032634641, -0.0025068263, -0.093802703, -0.076176546 }, { 0.1121451, 0.15584236, 0.070074778, 0.083736091 }, { 0.16981897, -0.078106227, 0.12480295, -0.0056807652 }, { -0.20300117, -0.017467249, 0.035504155, 0.056546123 } } } }, { { { { 0.014994926, 0.3118252, 0.12179235, -0.2013765 }, { -0.2622824, 0.28086607, 0.018805882, 0.72058929 }, { -0.0081002049, -0.28176506, -0.592214, -0.15032918 }, { 0.18913426, -0.24000825, 0.0020279072, -0.54749128 }, { 0.010237954, 0.76905205, 0.80173664, -0.016024595 }, { -0.53448318, 0.31204229, -0.16183732, 0.76857439 }, { -0.57639279, -0.63719194, -0.71354849, 0.56346054 }, { 0.49443258, 0.15067585, 0.31864726, -0.30570933 }, { -0.20756322, 0.2544828, -0.005298245, 0.0073796841 }, { -0.61822672, 0.21508574, 0.6362534, 0.30433278 }, { -0.0050327191, -0.278054, -0.3460806, 0.29967778 }, { 0.33983098, -0.11715664, -0.21761592, -0.068273894 }, { 0.5550354, 0.44369709, 0.64019993, -0.026032291 }, { -0.72587268, -0.33528197, -0.33592445, 0.53027141 }, { -0.47623191, -0.61767624, -0.61525655, 0.37823554 }, { 0.82869964, 0.219401, -0.018181789, -0.56937955 }, { -0.051792934, 0.3461701, 0.20915925, 0.078166496 }, { -0.26705611, 0.14439061, 0.0055054648, 0.463243 }, { -0.0019649711, -0.34119962, -0.29306531, -0.040223173 }, { 0.29285811, -0.32824753, -0.24768208, -0.29676955 }, { 0.87604898, 0.25374435, 0.2341931, -0.77851996 }, { -0.80404697, 0.011122158, 0.18899178, 0.55592668 }, { -0.78397618, -0.53690406, -0.59931185, 0.62348293 }, { 0.54613799, 0.080819658, 0.12590931, -0.60614071 } }, { { -0.12307869, -0.20242175, 0.21530167, -0.15608553 }, { 0.00052208688, 0.09998365, -0.067550225, -0.14009319 }, { 0.12621699, -0.089024022, 0.022656689, 0.18947331 }, { 0.34838897, -0.04936051, 0.25527451, -0.18942819 }, { 0.013210249, -0.043957685, -0.19088103, -0.034189573 }, { -0.0027790938, -0.026595097, 0.087083287, -0.12513839 }, { -0.038231564, 0.013328425, -0.0091503894, -0.005743873 }, { 0.17205702, -0.14956835, -0.0088915291, 0.18720588 }, { -0.049670195, 0.39532325, 0.080260299, 0.01811245 }, { 0.043555003, -0.30289197, -0.50878196, 0.27306166 }, { 0.02555972, -0.0068359476, 0.061097702, -0.43822038 }, { -0.10926471, 0.1870906, 0.12419548, 0.1245213 }, { -0.012443149, 0.040036941, 0.18601483, 0.02310445 }, { -0.10442982, 0.057455632, 0.13475314, -0.0019859122 }, { -0.068181593, -0.0033655904, 0.01922998, -0.020393828 }, { -0.10660626, 0.0020812455, 0.081209707, 0.077131932 }, { 0.088733212, -0.10430986, 0.45554817, -0.17113078 }, { 0.0046831409, 0.13247549, -0.1077727, 0.15382275 }, { 0.022346595, 0.022924261, -0.35016323, 0.2437608 }, { 0.029795657, 0.23046877, -0.020493651, -0.33214749 }, { -0.016101582, 0.042296203, 0.046779444, 0.037412394 }, { -0.02214903, -0.025218605, 0.14797485, -0.051723623 }, { 0.021321783, 0.010405115, 0.0075476201, 0.0082410917 }, { 0.040559796, 0.027927916, -0.012812736, -0.0096642379 } }, { { -0.055647079, 0.017595207, 0.34495838, -0.03055759 }, { -0.058415094, 0.027416036, 0.18568916, 0.13044498 }, { 0.01482217, -0.17300703, 0.027540135, -0.2744944 }, { 0.25558424, -0.15324455, -0.29751197, -0.11422984 }, { -0.068936732, -0.11425403, 0.094767025, -0.0020892558 }, { 0.040887892, 0.031622148, -0.095292456, -0.02460001 }, { -0.0026237665, 0.017734103, 0.01213911, 0.0056586962 }, { -0.052138375, 0.052245567, 0.04608449, -0.043004468 }, { -0.17693366, 0.0021023738, 0.13167397, -0.14062006 }, { -0.20900333, 0.0057695127, 0.13057243, 0.046715668 }, { -0.020569928, -0.08439655, -0.09683347, 0.038139385 }, { 0.18196242, 0.44461908, -0.11388512, -0.12413082 }, { 0.072801844, -0.0017236427, -0.0026756083, 0.049805114 }, { -0.092195952, -0.0076195172, -0.22763849, -0.11320887 }, { 0.016234922, 0.007258942, 0.078535592, -0.084829275 }, { -0.15320003, 0.057490618, -0.16065455, -0.17063675 }, { -0.012856124, 0.024818957, 0.097529739, 0.11569844 }, { -0.11141243, 0.26677735, 0.1319403, -0.15699502 }, { -0.021128161, -0.12370585, 0.056198856, -0.1836225 }, { -0.01871806, 0.025525037, 0.063822152, 0.066517944 }, { -0.013759301, 0.11401068, -0.04701374, -0.021321516 }, { 0.032714649, -3.161284e-06, 0.026930697, 0.00019593482 }, { 0.10575127, 0.016956425, 0.016873291, 0.0049304377 }, { -0.11938883, 0.31242334, 0.29347156, -0.19514533 } } }, { { { -0.17374661, -0.028781395, -0.25993234, 0.27242277 }, { -0.13675759, -0.62291002, -0.80742781, 0.54260546 }, { 0.16876581, -0.052588487, 0.22415557, -0.59669887 }, { 0.1769234, 0.64210979, 0.81157479, -0.2718564 }, { -0.99873125, -0.013258174, 0.58939675, 0.99930085 }, { -0.30883355, -0.71116337, -0.76218623, 0.096388818 }, { 0.65749012, -0.54533843, -0.57508599, -0.70359398 }, { -0.27406769, 0.61006308, 0.1873512, 0.2563151 }, { -0.78453523, -0.13585943, -0.048534939, 0.02085237 }, { 0.40938527, -0.76981396, -0.42506866, 0.22362984 }, { 0.29003079, -0.20624421, 0.1151133, -0.50558933 }, { 0.0070051806, 0.20763719, 0.59485798, -0.61562639 }, { -0.4371111, 0.48314196, 0.72981069, 0.99889301 }, { 0.58257878, -0.8603979, -0.94188892, -0.83140889 }, { 0.71858167, -0.49534538, -0.63421799, -0.84488463 }, { 0.016158248, 0.65330502, 0.82883727, -0.127372 }, { -0.50292264, -0.14848746, -0.20836533, 0.2471481 }, { -0.15815031, -0.63472031, -0.79826416, 0.15325573 }, { -0.010424343, -0.022843894, 0.099730136, -0.26040744 }, { 0.15069433, 0.31188588, 0.63836617, -0.25234477 }, { -0.36946506, 0.92093529, 0.96548808, 0.62354203 }, { -0.57070465, -0.99847512, -0.47855156, -0.079970605 }, { 0.077467525, -0.71134336, -0.67172579, -0.66364974 }, { -0.27299386, 0.89512951, 0.61598356, 0.49577277 } }, { { 0.070458859, -0.28774455, 0.21287043, -0.094689772 }, { 0.0029548085, -0.31404605, -0.039280892, -0.3652277 }, { -0.033729607, 0.041215792, 0.065844258, -0.21509418 }, { 0.39270582, 0.067526811, 0.15655351, 0.053346856 }, { 0.052704394, -0.087801294, 0.18655104, 0.056114808 }, { -0.074582751, -0.055177669, -0.22165519, 0.13272162 }, { -0.027850171, 0.0029849066, -0.0062314784, -0.010484316 }, { 0.20753796, -0.0087111988, -0.13875075, -0.06137521 }, { 0.089744421, 0.07271039, 0.099417029, -0.22157272 }, { -0.013209094, 0.048633419, -0.26528065, -0.15253703 }, { 0.052922007, 0.24859103, 0.14406684, 0.13857649 }, { 0.00096142813, 0.32643367, 0.17939549, -0.39761314 }, { 0.013505803, -0.036986517, -0.12729111, 0.15459921 }, { -0.00049722057, -0.047063275, -0.0018666598, 0.1067114 }, { -0.074221027, -0.00927958, -0.029535811, -0.024240068 }, { -0.12387933, 0.06626829, 0.16422781, 0.077740779 }, { 0.14560404, -0.082132455, 0.027268021, 0.18857832 }, { 0.10470732, -0.29519533, -0.23666419, 0.10917064 }, { 0.042550279, 0.02436036, -0.31865644, -0.024987356 }, { -0.030434576, 0.082115299, 0.17770796, 0.020944092 }, { -0.17365377, 0.13807361, 0.12476029, 0.072738061 }, { -0.11503962, -0.04022554, 0.028018434, -0.070211356 }, { -0.043677907, 0.0053361863, 0.0039019898, 0.0027489647 }, { 0.27060899, -0.0016552279, 0.14166067, -0.25461265 } }, { { 0.014703402, 0.094752279, -0.32162049, 0.082335322 }, { -0.31539882, 0.44394592, 0.44316202, -0.031456167 }, { -0.024148679, 0.082370612, -0.0031744796, 0.098610537 }, { 0.46130367, -0.19989896, -0.56118891, 0.11979937 }, { 0.11784636, 0.079971516, -0.16977121, 0.014922099 }, { 0.018367216, -0.076519762, 0.13801492, 0.039682415 }, { -0.0027614728, 0.0010389006, -0.023126227, 0.0027068473 }, { 0.22249856, -0.071302328, 0.23721977, 0.10734273 }, { 0.41478408, -0.36611101, 0.18031261, -0.11176768 }, { 0.15800457, 0.23829725, -0.0016193556, 0.2112867 }, { -0.14793833, -0.15378785, 0.0082778301, 0.27105519 }, { -0.064743588, 0.44794816, -0.12599819, 0.4310022 }, { 0.092725214, 0.033947737, 0.19969884, 0.0072363359 }, { -0.074190657, 0.005985921, 0.300818, -0.090919095 }, { 0.024238118, -0.010955859, -0.068086841, -0.021137349 }, { 0.12196721, -0.19977338, -0.64428422, -0.30808722 }, { 0.46567096, -0.042072501, -0.1778338, 0.34294059 }, { -0.32528695, 0.25699981, 0.49346557, -0.20743316 }, { 0.10422458, 0.049488574, 0.49098274, -0.34871439 }, { 0.16431875, -0.050748897, -0.18464312, -0.61695364 }, { -0.1753479, 0.033238479, -0.046267845, -0.012339883 }, { -0.16098841, 0.080519992, -0.11793031, 0.036790025 }, { 0.017193144, -0.0029212372, -0.0044153187, -0.0057094316 }, { 0.23481771, -0.1556448, -0.18775429, -0.013697353 } } }, { { { 0.98467622, 0.94970347, 0.95791534, 0.9408684 }, { 0.95525144, 0.73013516, 0.58966657, 0.43166004 }, { 0.98562289, 0.95804118, 0.77397471, 0.78825859 }, { 0.96588112, 0.72807352, 0.58424502, 0.79142113 }, { -0.049305848, 0.63904864, 0.099145551, -0.03377918 }, { 0.78673348, 0.62998117, 0.62680207, 0.63245759 }, { 0.48526085, 0.544603, 0.40015579, 0.43297544 }, { 0.82487776, 0.77789448, 0.92917353, 0.91697567 }, { 0.58431326, 0.95748667, 0.99880743, 0.99975533 }, { 0.67096902, 0.60093643, 0.64381538, 0.92594344 }, { 0.95700408, 0.93816272, 0.93111608, 0.80905665 }, { 0.94046044, 0.97116483, 0.77381347, 0.78507504 }, { 0.7077214, 0.7547892, 0.23983411, -0.039180128 }, { 0.3656649, 0.38379871, -0.00015338393, 0.16604667 }, { 0.50679735, 0.6108265, 0.46821675, 0.37829596 }, { 0.55946029, 0.72460731, 0.55919425, 0.81214734 }, { 0.86277825, 0.92634645, 0.95542467, 0.96581976 }, { 0.95061533, 0.75913205, 0.60228234, 0.87287949 }, { 0.99994373, 0.93971324, 0.95087677, 0.96466059 }, { 0.9442062, 0.89161694, 0.72879505, 0.92100486 }, { 0.30989313, 0.29579046, 0.11395771, 0.071428407 }, { 0.16674735, -0.054071458, 0.85747916, 0.82737551 }, { 0.61593841, 0.45356879, 0.43544204, 0.41332561 }, { 0.79196443, 0.43841915, 0.77763172, 0.62193473 } }, { { 0.028699614, 0.071974788, -0.028868668, 0.030119772 }, { -0.16988515, -0.35713152, 0.36877151, 0.37172103 }, { 0.024472009, 0.10373643, 0.052160621, -0.12998364 }, { 0.051999909, -0.1688679, 0.05813266, -0.11063347 }, { 0.026373007, 0.067310776, 0.34433164, 0.0017481699 }, { -0.017659611, -0.10215276, -0.23736187, 0.12678732 }, { -0.0019097928, 0.02067204, -0.030447136, -0.0093192388 }, { 0.10615435, 0.11124023, 0.04473958, 0.14369936 }, { 0.14791062, -0.034502091, 0.041456555, 0.06737059 }, { 0.22389399, 0.2668048, 0.25742349, 0.03724758 }, { 0.0046009946, 0.066632032, 0.097957775, 0.22969631 }, { 0.043253167, -0.013638494, 0.071328387, -0.19249903 }, { -0.023561087, 0.011490741, 0.19824644, -0.04133258 }, { -0.057507532, -0.039265903, 0.060469313, 0.37300659 }, { 0.027051207, -0.0086784396, -0.0055877341, -0.0315352 }, { 0.15724931, 0.0099485187, 0.22462997, 0.14112999 }, { 0.13909905, 0.026199511, -0.12430815, -0.076900423 }, { -0.022327596, -0.1975812, 0.49862652, -0.096026553 }, { 0.076782007, 0.041598482, 0.0033451155, 0.039947963 }, { 0.005353589, 0.070993946, 0.0068174778, -0.17805261 }, { -0.059912765, -0.17027417, -0.060069718, 0.1561139 }, { 0.017122435, 0.048532637, -0.05315926, 0.066962855 }, { 0.058014377, 0.021874362, 0.017248667, -0.0069413843 }, { 0.099274028, 0.040622241, 0.040435904, 0.14191123 } }, { { -0.13453832, 0.071519908, -0.1597656, -0.030758273 }, { -0.13511715, 0.32373425, 0.35851035, -0.18685481 }, { 0.021440457, 0.034442875, 0.14324368, 0.15754565 }, { -0.061440371, 0.16837735, 0.47887644, -0.036265812 }, { 0.55060811, 0.14095672, 0.13077418, 0.25515565 }, { -0.084599968, -0.084002143, 0.1542308, 0.044223437 }, { 0.0017727822, 0.025149715, -0.025479364, -0.0023658361 }, { 0.1619123, 0.069159159, -0.016343512, 0.026108175 }, { 0.3296525, 0.029456656, 0.039715069, 0.015958704 }, { -0.093419591, 0.37051381, -0.063182977, -0.017764112 }, { 0.11962535, 0.062511772, -0.070445145, 0.27768911 }, { 0.07458833, -0.16218828, 0.064111239, 0.43889373 }, { -0.0326486, -0.03666828, -0.17597139, 0.34213144 }, { 0.061334301, -0.0099525239, 0.21497301, 0.0074569296 }, { -0.016749445, 0.00054557189, 0.040331287, 0.066200794 }, { 0.20620866, 0.25268529, 0.46594276, 0.059651923 }, { 0.15170896, 0.041438057, 0.021708506, -0.15049245 }, { -0.14317538, 0.13548996, 0.37297491, 0.13718874 }, { 0.053339004, 0.015014013, -0.10418356, -0.13598877 }, { -0.02227412, 0.045548464, 0.21534467, -0.23828118 }, { -0.055326885, 0.11851609, 0.28938409, 0.041373996 }, { -0.1219532, 0.57338554, -0.094571555, 0.025008596 }, { 0.070380772, 0.016993506, 0.018073937, -0.015404818 }, { 0.17033841, 0.12449473, 0.10847869, -0.11141982 } } }, { { { 4.409738, 4.5071479, 5.4761817, 5.3214091 }, { 5.3741435, 4.6270256, 5.4786338, 5.323679 }, { 4.305776, 4.4890731, 4.6894257, 4.6068436 }, { 5.4930574, 4.9116386, 5.4097636, 4.9225404 }, { 5.1861828, 5.5144226, 5.1307797, 5.0804212 }, { 6.1194597, 6.0655136, 5.7369562, 6.1076578 }, { 6.9549598, 6.9281578, 6.9549598, 6.9549598 }, { 4.5030565, 4.5849566, 4.4830953, 4.4904323 }, { 5.3629211, 5.5524848, 4.5719135, 4.9103175 }, { 4.8906163, 5.3972226, 4.8806206, 5.1834202 }, { 4.5047396, 4.5984947, 4.7039612, 4.3422371 }, { 4.5956963, 5.6294962, 4.46025, 4.4827131 }, { 5.8454206, 6.000743, 5.4594428, 4.9952614 }, { 6.09642, 6.3979283, 4.9784963, 5.6878449 }, { 6.9549598, 6.9752898, 6.9549598, 6.9549598 }, { 6.2053562, 4.9984547, 5.3887395, 4.6221036 }, { 4.5265196, 4.3684629, 5.5819288, 5.4957366 }, { 5.2220057, 4.6118907, 5.5046208, 4.9190037 }, { 4.3408178, 4.4980303, 5.4937404, 5.6154153 }, { 4.4802186, 4.4666194, 4.8546878, 5.1764252 }, { 5.7384024, 5.9048089, 5.4636107, 5.0807017 }, { 5.1013817, 5.2237041, 6.0338955, 5.8869417 }, { 6.9414339, 6.9549598, 6.9549598, 6.9549598 }, { 4.3368412, 4.9692663, 4.7090567, 4.9023075 } }, { { 0.0093525884, -0.33796029, -0.4366682, -0.18161326 }, { -0.34446047, 0.10854359, -0.61563912, -0.16514117 }, { 0.055849315, 0.093045585, 0.36722184, 0.085665647 }, { -0.21881508, -0.036846235, -0.25226403, -0.012790033 }, { -0.14697546, -0.026656628, 0.2559775, 0.026279081 }, { 0.073189287, -0.074472165, -0.15439557, 0.020907645 }, { 0, -0.015078298, 0, 0 }, { 0.027540893, -0.30876053, -0.15680794, -0.18470107 }, { -0.072547269, -0.019227086, -0.26735769, -0.1362069 }, { 0.36907279, -0.28005156, 0.01966203, -0.10277819 }, { -0.26755862, 0.066747173, 0.60834173, -0.23356165 }, { -0.12357338, -0.41742338, 0.081840746, -0.14596222 }, { -0.068599762, -0.004402392, -0.17192993, -0.15797464 }, { -0.072923207, -0.02555551, -0.21075071, 0.047272919 }, { 0, 0.0115085, 0, 0 }, { 0.32527558, 0.066048741, -0.28639187, 0.45171914 }, { -0.158086, -0.049098981, -0.17226122, -0.50289857 }, { -0.39456648, 0.031970902, -0.74883626, 0.20536003 }, { 0.22864705, -0.0095988927, -0.1155595, -0.06240073 }, { 0.12336497, -0.34128076, 0.34341316, 0.083678547 }, { -0.032718317, 0.076359349, -0.30099369, -0.016865529 }, { -0.23491753, -0.17228011, -0.044893186, -0.057411459 }, { -0.0077848677, 0, 0, 0 }, { -0.18713605, -0.11612415, 0.30907006, 0.064707406 } }, { { -0.20768494, -0.15642062, -0.079474216, -0.020948121 }, { -0.18767308, -0.013722599, 0.15827086, -0.27421942 }, { -0.11484158, -0.29325715, 0.24426149, 0.34598577 }, { -0.095599056, 0.16784413, 0.23369965, 0.15036114 }, { 0.058496274, -0.064565923, -0.076598803, -0.11988702 }, { -0.03406356, -0.010863931, -0.036116475, 0.0077051595 }, { 0, -0.015078298, 0, 0 }, { -0.21271534, 0.31678528, 0.084310434, -0.039787477 }, { 0.057420352, -0.60894321, -0.14275706, -0.29178151 }, { -0.21477227, 0.091254596, -0.053659362, -0.13299553 }, { -0.24972574, 0.22261101, -0.59415755, -0.13299464 }, { -0.406027, 0.15018847, 0.33281927, 0.28006105 }, { -0.033198856, 0.013081228, 0.0098634494, -0.18858267 }, { -0.16914457, -0.014917022, -0.15618156, 0.038961385 }, { 0, 0.0115085, 0, 0 }, { 0.047340338, -0.052961301, 0.30193278, 0.38564757 }, { -0.2009302, -0.15247105, -0.32333852, 0.22878398 }, { -0.22934017, 0.022888443, 0.30911154, -0.12420416 }, { 0.21191356, -0.33281926, -0.13523708, -0.038546557 }, { 0.28507859, -0.012777666, 0.16285544, -0.12612215 }, { -0.057034227, 0.01719448, -0.037892291, -0.13064036 }, { -0.075888865, 0.041589292, 0.0089100653, -0.10775402 }, { 0.0075560462, 0, 0, 0 }, { -0.18120766, 0.16485298, 0.58949587, 0.072313493 } } }, { { { 0.60381773, 0.64633179, 0.92301353, 0.23720177 }, { 1.1128727, 0.42172315, 1.6605811, 0.22066721 }, { 0.55829912, 0.7107351, 0.47437673, 0.53646626 }, { 0.75684406, 0.65607146, 1.5264507, 0.12817954 }, { -0.25070514, 0.30263175, -0.21070678, -0.2264813 }, { -0.24745858, -0.26801252, 0.2750925, 0.055035565 }, { -0.018769156, -0.066023008, 0.10111114, 0.0089232736 }, { 0.41152465, 0.52508091, 0.4161358, 0.39058287 }, { 0.90919582, 1.2448772, 0.61547497, 0.51303689 }, { 0.2973136, 1.2348603, 0.24154398, 0.76087607 }, { 0.23369317, 0.68368068, 0.81024353, 0.35451079 }, { 0.69272073, 0.47014545, 0.61401877, 0.43768641 }, { -0.44449894, -0.10123077, -0.19173956, -0.15811184 }, { -0.089717, -0.068601549, -0.16704813, -0.29761406 }, { 0.0055968308, -0.089855929, -0.087150641, 0.2244144 }, { 0.38902787, 0.62620686, 1.3314901, 0.26038797 }, { 0.16776511, 0.32722251, 0.71914611, 0.53556119 }, { 0.63106992, 0.46256454, 1.785895, 0.17339911 }, { 0.72516261, 0.44941094, 0.81174974, 0.61247129 }, { 0.56877815, 0.20989179, 0.7607991, 0.017998645 }, { 0.016372087, 0.26062407, -0.32771461, -0.075930098 }, { -0.11957223, -0.22579003, -0.42587945, -0.0015549589 }, { 0.0049992009, 0.053511694, 0.00053268274, 0.022778575 }, { 0.19356675, 0.5564623, 0.74981777, 0.28733119 } }, { { 0.017029304, 0.22690356, 0.25927682, -0.048136042 }, { 0.52936856, -0.26082526, 0.12568074, -0.046727529 }, { 0.08949554, -0.019090555, 0.31477592, -0.067513409 }, { 0.056302335, -0.011819435, -0.063621104, 0.27092306 }, { 0.053971592, -0.17913246, -0.14991651, -0.044263405 }, { 0.29037749, -0.040498369, -0.33600753, 0.16250066 }, { -0.067102844, -0.17843768, 0.033172168, 0.13638573 }, { 0.057127881, -0.044468822, 0.33005778, 0.34775491 }, { -0.14300931, 0.022121077, -0.045281831, -0.065216583 }, { 0.084931489, 0.06688461, 0.15758114, -0.091330485 }, { -0.014274888, 0.29139103, 0.089163749, -0.18005467 }, { -0.2191522, -0.1333803, -0.31948964, -0.28536602 }, { 0.20298891, -0.0031882515, -0.15749696, -0.014977715 }, { -0.14016857, -0.17278064, 0.01369474, 0.10971499 }, { 0.018219806, 0.080447764, 0.0056022696, -0.043028475 }, { -0.076556403, -0.13038184, -0.23788273, 0.5849635 }, { 0.1038427, 0.18199702, 0.35294355, -0.0023601311 }, { 0.22294845, -0.37427713, 0.2907529, 0.26234219 }, { 0.40809306, 0.12982813, 0.42857338, 0.14064303 }, { 0.4265028, 0.18710053, 0.15310514, 0.067551813 }, { -0.18986488, -0.029676062, -0.087045959, -0.14788626 }, { -0.07865478, 0.011558295, -0.018262356, 0.38992629 }, { 0.22297641, 0.072192947, 0.064119712, 0.12862555 }, { -0.069262467, -0.14990585, 0.31342655, -0.15002022 } }, { { 0.25288162, -0.096551539, 0.051695506, 0.20925392 }, { 0.23093904, 0.096712594, 0.19826434, 0.32530694 }, { 0.14114785, 0.071010138, -0.17642029, 0.092260082 }, { 0.39001648, -0.17666595, 0.088397252, 0.1462816 }, { 0.12484597, 0.066920676, -0.16116194, 0.21758387 }, { 0.15625272, -0.00043631439, -0.07868976, -0.19261141 }, { -0.0142415, 0.06356153, 0.026276923, -0.024546668 }, { 0.097089221, 0.085426402, 0.11936115, 0.012042542 }, { 0.52509109, -0.22465399, -0.11490612, 0.023562122 }, { -0.12418278, 0.11985465, 0.087804943, 0.25283464 }, { 0.10716753, -0.036426901, 0.2469409, -0.095816257 }, { -0.095364501, 0.14001518, -0.068636804, -0.082487255 }, { 0.074490355, 0.25323233, 0.17863748, 0.12482145 }, { -0.019616587, -0.0053326518, 0.047558858, 0.066104462 }, { 0.12647102, 0.25712368, 0.12306783, -0.050252261 }, { -0.13375041, 0.17825067, 0.026649645, -0.33338076 }, { 0.16384463, -0.022241979, 0.17817325, 0.6808721 }, { 0.42075944, -0.024292721, -0.11323318, 0.45027063 }, { -0.023953485, 0.25719992, 0.28680108, 0.33600529 }, { 0.013445546, 0.22504275, 0.17408162, 0.52860686 }, { -0.098839039, -0.27017244, 0.10293505, -0.012472685 }, { 0.074267375, -0.0056418849, 0.17632358, 0.21754089 }, { 0.1491061, 0.017927571, -0.0217757, -0.0039381966 }, { 0.067239102, -0.74624136, 0.12992555, -0.058866581 } } } }, { { { { 0.1270204, 0.7650174, 0.55252173, 0.05956498 }, { -0.36870832, 0.31227245, 0.52167466, 0.4282174 }, { -0.036761861, -0.5477415, -0.76091563, -0.37583127 }, { 0.17129434, -0.14281209, -0.40463148, -0.56367877 }, { 0.07429238, 0.45420144, 0.41919765, 0.019225986 }, { -0.44125436, -0.05567539, 0.080551064, 0.54444995 }, { -0.36600455, -0.55359309, -0.3290331, 0.33946169 }, { 0.65253747, 0.015186649, 0.0665303, -0.64649501 }, { 0.05392469, 0.54355001, 0.7539307, -0.41089455 }, { -0.29264863, 0.49684721, 0.39184208, 0.47737193 }, { 0.10885354, -0.80803227, -0.7443769, -0.3736688 }, { 0.1939378, -0.079590275, -0.42241709, -0.75536039 }, { 0.44776697, 0.44884546, 0.427965, 0.3297221 }, { -0.34595785, 0.27723463, 0.12245317, 0.43884357 }, { 0.18467758, -0.55582608, -0.99421464, -0.0096027817 }, { 0.6672057, -0.038103784, -0.048616141, -0.68508055 }, { -0.016615937, 0.62001729, 0.50530563, -0.22211425 }, { -0.16823123, 0.31934529, 0.47092187, 0.4884373 }, { 0.03194189, -0.5624624, -0.44688229, 0.223814 }, { 0.17828041, -0.080017082, -0.44239439, -0.46726625 }, { 0.19895649, 0.82568772, 0.47859751, 0.064443297 }, { -0.47464217, 0.011895223, 0.01123465, -0.010697203 }, { -0.17670677, -0.66931423, -0.5814681, -0.01325001 }, { 0.65193874, -0.010713062, -0.007915928, -0.65520853 } }, { { -0.01027431, -0.0019056004, 0.0020213958, 0.0064495753 }, { 0.0058416688, 0.0051314639, 0.021497114, 0.005870592 }, { -0.00035518612, -0.00087553938, -0.0029318969, 0.0087577986 }, { -0.0048770476, -0.015949665, -0.034816051, -0.006104917 }, { 0.0015371362, -0.0012591621, 0.01241148, 0.00096621463 }, { 0.0032416133, 0.021025709, 0.0036344622, 0.0015436078 }, { -0.0093946276, 0.0046564763, 0.028177476, -0.01022744 }, { 0.00014675555, 0.030031482, -0.0092302407, -0.001999398 }, { -0.049980321, 0.024752279, 0.016684689, -0.0045230976 }, { 0.0067493834, 0.014071508, 0.0079316435, 0.034593704 }, { 0.01971715, -0.0037227013, -0.013430278, -0.024257585 }, { -0.004342319, 0.024001878, -0.013356442, -0.022792018 }, { -0.0051709665, -0.017029547, 0.040567567, 0.0052520812 }, { 0.0090399102, 0.0079604733, 0.00018765016, -0.0092868977 }, { -0.020304032, 0.0056590257, -0.0045373063, -0.018653318 }, { -9.9636934e-05, 0.002001886, 0.0046843544, 0.0055608043 }, { 0.0018025744, -0.0025962216, 0.0068285574, -0.014851062 }, { 0.00041645221, 0.0054738242, 0.0076769026, -0.013419208 }, { 0.0038347099, -0.0042555066, -0.0066470075, 0.0039146778 }, { -0.009084153, 0.024461537, 0.0034578066, -0.0054827001 }, { 0.0033463477, 0.0045594748, 0.00037604935, -0.01571513 }, { -0.012589588, 0.029678359, -0.019924871, -0.004708459 }, { -0.0002642682, -0.0051057336, -0.0042867302, -0.00041141781 }, { -0.00086487068, -0.0025170841, 0.0030062196, -0.0030385417 } }, { { -0.01027431, -0.0019056004, 0.0020213958, 0.0064495753 }, { 0.0058416688, 0.0051314639, 0.021497114, 0.005870592 }, { -0.00035518612, -0.00087553938, -0.0029318969, 0.0087577986 }, { -0.0048770476, -0.015949665, -0.034816051, -0.006104917 }, { 0.0015371362, -0.0012591621, 0.01241148, 0.00096621463 }, { 0.0032416133, 0.021025709, 0.0036344622, 0.0015436078 }, { -0.0093946276, 0.0046564763, 0.028177476, -0.01022744 }, { 0.00014675555, 0.030031482, -0.0092302407, -0.001999398 }, { -0.049980321, 0.024752279, 0.016684689, -0.0045230976 }, { 0.0067493834, 0.014071508, 0.0079316435, 0.034593704 }, { 0.01971715, -0.0037227013, -0.013430278, -0.024257585 }, { -0.004342319, 0.024001878, -0.013356442, -0.022792018 }, { -0.0051709665, -0.017029547, 0.040567567, 0.0052520812 }, { 0.0090399102, 0.0079604733, 0.00018765016, -0.0092868977 }, { -0.020304032, 0.0056590257, -0.0045373063, -0.018653318 }, { -9.9636934e-05, 0.002001886, 0.0046843544, 0.0055608043 }, { 0.0018025744, -0.0025962216, 0.0068285574, -0.014851062 }, { 0.00041645221, 0.0054738242, 0.0076769026, -0.013419208 }, { 0.0038347099, -0.0042555066, -0.0066470075, 0.0039146778 }, { -0.009084153, 0.024461537, 0.0034578066, -0.0054827001 }, { 0.0033463477, 0.0045594748, 0.00037604935, -0.01571513 }, { -0.012589588, 0.029678359, -0.019924871, -0.004708459 }, { -0.0002642682, -0.0051057336, -0.0042867302, -0.00041141781 }, { -0.00086487068, -0.0025170841, 0.0030062196, -0.0030385417 } } }, { { { -0.68772793, 0.19029367, -0.17427646, 0.60300616 }, { -0.29980532, -0.22397537, -0.4071009, 0.36277983 }, { 0.75628069, -0.13426242, 0.13645381, -0.74653491 }, { 0.14891408, -0.13497977, 0.36807879, -0.39814386 }, { -0.20608987, -0.076497863, -0.19510375, 0.34604256 }, { -0.02421123, -0.4588774, -0.64965351, 0.083039161 }, { 0.51918764, -0.30614677, -0.25791921, -0.40837612 }, { 0.028860181, 0.63152733, 0.5876224, -0.033139773 }, { -0.63418144, 0.046874151, 0.24431924, 0.71662556 }, { -0.29088451, -0.21455586, -0.73980807, 0.65038559 }, { 0.78663226, 0.00020858525, 0.40361403, -0.75720144 }, { 0.1998276, 0.54590973, 0.1773378, -0.35464319 }, { -0.40236144, 0.31362578, -0.34406026, 0.38120073 }, { -0.27845549, -0.46862161, -0.47141499, 0.095899189 }, { 0.6004921, 0.28051621, -0.011378178, -0.98141078 }, { 0.032724674, 0.66798127, 0.66430425, -0.05209965 }, { -0.59603974, -0.083198329, 0.34616224, 0.42082916 }, { -0.14262632, -0.21418442, -0.37504914, 0.32676687 }, { 0.58204273, 0.0067537174, -0.35923481, -0.40792038 }, { 0.15607366, 0.17215007, 0.34414936, -0.33566945 }, { -0.44862333, 0.004919013, 0.0076768115, 0.41897935 }, { -0.022062848, -0.39695079, -0.0062786656, 0.042925103 }, { 0.65953535, -0.15521993, 0.011867978, -0.57721165 }, { 0.031305912, 0.65627006, 0.66779002, -0.029815636 } }, { { 0.011457792, -0.011774949, -0.012205337, 0.0048139052 }, { -0.024024566, 0.018313023, -0.023210623, -0.0046351547 }, { 0.0039133571, 0.0046801024, -0.020590099, -0.0018568631 }, { -0.015369931, -0.0092621276, -0.026149742, 0.0010335971 }, { 0.032555144, -0.01336897, -0.022733265, -0.027997469 }, { -0.028161537, -0.00073877629, -0.023989631, 0.0055660453 }, { -0.012966193, 0.003944376, 0.025685982, -0.0017458044 }, { 0.00015626641, -0.009524206, 0.0083025026, -0.00049753811 }, { -0.02358661, 0.006370149, 0.00087066462, -0.00054248544 }, { -0.0024571244, -0.023218369, -0.010895303, -0.0095647684 }, { 0.0069970393, -0.00093403301, -0.0081922371, -0.00026359768 }, { 0.0065921354, 0.028846533, -0.045676337, 0.006070217 }, { 0.0045248423, -0.0084676847, 0.028756195, 0.020612871 }, { 0.0037691244, -0.0069385161, -0.00029501448, -0.0017839033 }, { -0.0048675353, -0.011930456, 0.0044251285, -0.00016323616 }, { -0.0012291164, -0.0019575288, 0.0078250029, -0.0011151155 }, { 0.00503333, -0.0094538968, 0.0092375183, 0.018207648 }, { 0.0080615812, -0.0073583459, -0.0166794, 0.016416158 }, { 0.002192959, -0.01153759, -0.0048668362, -0.0071123281 }, { -0.010116143, -0.010224552, 0.010897731, 0.00093792816 }, { 0.017199359, -0.0087516179, 0.0021169251, -0.020946959 }, { -0.01570063, 0.020087246, 0.014492818, -0.016014018 }, { 0.0023484072, 0.0015070243, -0.00045616273, -0.001211882 }, { 0.0018090492, -0.0012261901, 0.0012809284, 0.00096488905 } }, { { 0.011457792, -0.011774949, -0.012205337, 0.0048139052 }, { -0.024024566, 0.018313023, -0.023210623, -0.0046351547 }, { 0.0039133571, 0.0046801024, -0.020590099, -0.0018568631 }, { -0.015369931, -0.0092621276, -0.026149742, 0.0010335971 }, { 0.032555144, -0.01336897, -0.022733265, -0.027997469 }, { -0.028161537, -0.00073877629, -0.023989631, 0.0055660453 }, { -0.012966193, 0.003944376, 0.025685982, -0.0017458044 }, { 0.00015626641, -0.009524206, 0.0083025026, -0.00049753811 }, { -0.02358661, 0.006370149, 0.00087066462, -0.00054248544 }, { -0.0024571244, -0.023218369, -0.010895303, -0.0095647684 }, { 0.0069970393, -0.00093403301, -0.0081922371, -0.00026359768 }, { 0.0065921354, 0.028846533, -0.045676337, 0.006070217 }, { 0.0045248423, -0.0084676847, 0.028756195, 0.020612871 }, { 0.0037691244, -0.0069385161, -0.00029501448, -0.0017839033 }, { -0.0048675353, -0.011930456, 0.0044251285, -0.00016323616 }, { -0.0012291164, -0.0019575288, 0.0078250029, -0.0011151155 }, { 0.00503333, -0.0094538968, 0.0092375183, 0.018207648 }, { 0.0080615812, -0.0073583459, -0.0166794, 0.016416158 }, { 0.002192959, -0.01153759, -0.0048668362, -0.0071123281 }, { -0.010116143, -0.010224552, 0.010897731, 0.00093792816 }, { 0.017199359, -0.0087516179, 0.0021169251, -0.020946959 }, { -0.01570063, 0.020087246, 0.014492818, -0.016014018 }, { 0.0023484072, 0.0015070243, -0.00045616273, -0.001211882 }, { 0.0018090492, -0.0012261901, 0.0012809284, 0.00096488905 } } }, { { { 0.71476997, 0.61525336, 0.81507512, 0.79550964 }, { 0.87986984, 0.9232123, 0.74974956, 0.82765975 }, { 0.65321366, 0.82580437, 0.63434042, 0.54903231 }, { 0.97390084, 0.98050251, 0.83713283, 0.72370416 }, { 0.97570877, 0.88760866, 0.88668363, 0.9380218 }, { 0.89705541, 0.88675351, 0.75595095, 0.83467284 }, { 0.77232433, 0.77447327, 0.9084134, 0.84734569 }, { -0.75720667, -0.77520488, -0.80639546, -0.76219811 }, { 0.77130152, 0.83806694, 0.60983327, 0.56357207 }, { 0.91090229, 0.84089752, 0.54694041, 0.59085922 }, { 0.60775044, 0.58913818, 0.53197627, 0.53574024 }, { 0.96044628, 0.83405513, 0.88888419, 0.55105253 }, { 0.79850486, 0.83676557, 0.83574428, 0.86369517 }, { 0.89597751, 0.83876978, 0.87336884, 0.8934314 }, { 0.77801249, 0.78253947, 0.10680725, 0.19167855 }, { -0.74415432, -0.74320194, -0.74587957, -0.72660186 }, { 0.802783, 0.78016447, 0.79046691, 0.87952719 }, { 0.97537479, 0.92311625, 0.79848027, 0.80910594 }, { 0.8125306, 0.82679528, 0.81929639, 0.88516002 }, { 0.97152309, 0.98181547, 0.82815966, 0.81791703 }, { 0.87129411, 0.56410602, 0.87800085, 0.905706 }, { 0.87990229, 0.91776281, 0.99991718, 0.99902102 }, { 0.73060786, 0.72658464, 0.81348263, 0.81648708 }, { -0.75762512, -0.75445002, -0.74430762, -0.75485946 } }, { { 0.018332644, 0.0084005452, -0.0018937689, -0.0035491975 }, { 0.0016556654, 0.0049261013, -0.021796869, 0.0025973591 }, { -0.0019671758, 0.00051947074, 0.0071261223, 0.0056689139 }, { 0.00041901024, -0.0023903288, -0.0035639711, -0.0036673013 }, { 0.009963464, 0.00099195429, -0.0042516892, 0.0092605531 }, { 0.0034813664, 0.0028575465, -0.016343415, -0.0014475905 }, { 0.0053571039, 0.0051116063, 0.016171091, -0.00052744238 }, { 0.00013272575, -0.0095491849, 0.0070156475, 0.0017057538 }, { 0.028067438, -0.0086835729, -0.0087852674, 0.0035321054 }, { 0.0025007808, -0.0075654884, -0.012551417, -0.0068823899 }, { -0.00017607308, 0.002636122, -0.011272055, -0.010314896 }, { 0.010646599, 0.00042804331, 0.013900837, -0.01279076 }, { 0.0059898286, 0.012331371, -0.0073125296, 0.016248603 }, { 0.031579315, -0.0057840222, -0.00018304192, 0.005171422 }, { 0.010928513, 0.0092660887, 0.030404621, 0.0053167707 }, { -0.00014899672, -0.0035246494, 0.0075862845, -0.005861723 }, { 0.0067791918, 0.0021224495, -0.0071755505, -0.010370936 }, { 0.0015352958, -0.0025785166, -0.0092688001, 0.003966373 }, { 0.0036915074, -0.002306452, -0.005736452, -0.0033594125 }, { 0.0065128512, 0.006188005, 0.00088322638, -0.0016227066 }, { 0.0092720771, -0.0046684631, -7.3769604e-05, 0.013807013 }, { -0.0031421984, 0.010622679, 0.00041591214, 0.0032786075 }, { -0.0021421613, -0.0041675589, -0.0029529994, -0.00085350449 }, { -0.00069204344, -0.0010785124, 0.00097549628, 0.0025280456 } }, { { 0.018332644, 0.0084005452, -0.0018937689, -0.0035491975 }, { 0.0016556654, 0.0049261013, -0.021796869, 0.0025973591 }, { -0.0019671758, 0.00051947074, 0.0071261223, 0.0056689139 }, { 0.00041901024, -0.0023903288, -0.0035639711, -0.0036673013 }, { 0.009963464, 0.00099195429, -0.0042516892, 0.0092605531 }, { 0.0034813664, 0.0028575465, -0.016343415, -0.0014475905 }, { 0.0053571039, 0.0051116063, 0.016171091, -0.00052744238 }, { 0.00013272575, -0.0095491849, 0.0070156475, 0.0017057538 }, { 0.028067438, -0.0086835729, -0.0087852674, 0.0035321054 }, { 0.0025007808, -0.0075654884, -0.012551417, -0.0068823899 }, { -0.00017607308, 0.002636122, -0.011272055, -0.010314896 }, { 0.010646599, 0.00042804331, 0.013900837, -0.01279076 }, { 0.0059898286, 0.012331371, -0.0073125296, 0.016248603 }, { 0.031579315, -0.0057840222, -0.00018304192, 0.005171422 }, { 0.010928513, 0.0092660887, 0.030404621, 0.0053167707 }, { -0.00014899672, -0.0035246494, 0.0075862845, -0.005861723 }, { 0.0067791918, 0.0021224495, -0.0071755505, -0.010370936 }, { 0.0015352958, -0.0025785166, -0.0092688001, 0.003966373 }, { 0.0036915074, -0.002306452, -0.005736452, -0.0033594125 }, { 0.0065128512, 0.006188005, 0.00088322638, -0.0016227066 }, { 0.0092720771, -0.0046684631, -7.3769604e-05, 0.013807013 }, { -0.0031421984, 0.010622679, 0.00041591214, 0.0032786075 }, { -0.0021421613, -0.0041675589, -0.0029529994, -0.00085350449 }, { -0.00069204344, -0.0010785124, 0.00097549628, 0.0025280456 } } }, { { { 5.3792285, 5.1960477, 5.5112916, 5.6615254 }, { 5.0489877, 5.2428834, 5.1752035, 5.1109826 }, { 5.5205204, 5.7511938, 5.0202917, 4.9168865 }, { 4.9522523, 4.8880256, 5.1015936, 5.2858816 }, { 5.7256502, 5.7919759, 5.645241, 5.6035708 }, { 6.4076931, 6.4822111, 6.2642633, 6.3925959 }, { 6.9797014, 6.981436, 7.0028674, 6.9976464 }, { -0.03290957, -0.03290957, -0.03290957, -0.03290957 }, { 5.4977854, 5.7684965, 5.3463095, 4.8810492 }, { 4.9869047, 5.4896416, 4.9647805, 4.884877 }, { 5.3141219, 5.3357788, 4.7695434, 4.8709631 }, { 5.2056063, 5.407802, 5.2123857, 4.9428208 }, { 6.2188218, 6.17756, 6.2751008, 6.3672109 }, { 6.9105856, 6.7986798, 6.5712335, 6.5907061 }, { 6.9797014, 6.9797014, 5.6859993, 5.5642483 }, { -0.032764603, -0.032764603, -0.032764603, -0.032764603 }, { 5.7724142, 6.0929556, 5.99581, 5.9265164 }, { 4.9363192, 4.9823732, 5.1732995, 5.2475265 }, { 5.8365191, 5.9972902, 5.9778441, 5.9270668 }, { 4.8706768, 5.0194503, 5.155585, 5.2188041 }, { 6.1569904, 6.0563989, 6.0989699, 6.2139837 }, { 5.8727399, 5.8948086, 5.5734095, 5.5536103 }, { 6.9797014, 6.9797014, 6.9797014, 6.9797014 }, { -0.032766769, -0.032766769, -0.032766769, -0.032766769 } }, { { 0.0011802354, -0.006546101, -0.02103972, 0.0008654047 }, { -0.015460534, 0.017874544, 0.0029121134, 0.023511773 }, { -0.040909245, 0.011927691, 0.011991588, 0.01677931 }, { -0.015633544, -0.0042321141, 0.026623034, 0.0080414514 }, { 0.012614382, 0.0065080145, 0.035716738, -0.0080665814 }, { -0.0057849744, -0.017478461, -0.031219642, 0.00016446523 }, { 0, 0.00032235028, 0, 0 }, { 0, 0, 0, 0 }, { -0.068586697, -0.024228236, -0.012857221, -0.039493706 }, { -0.018078201, -0.015140979, 0.00072119173, -0.051249859 }, { -0.054228277, 0.0097895101, 0.0019832646, -0.011715411 }, { -0.042326208, -0.010160072, 0.037088052, -0.031848667 }, { 0.00067130897, -0.013966717, -0.017268559, -0.0074614576 }, { 0.070515961, 0.012848107, -0.0008396517, 0.0049006506 }, { 0, 0, -0.063014256, -0.0085124986 }, { 0, 0, 0, 0 }, { -0.040302299, 0.0048936307, 0.0064406394, 0.0034044871 }, { -0.010453589, 0.0035820836, -0.017384391, -0.038199947 }, { -0.044968611, -0.0088322127, 0.020303819, 0.0058131005 }, { -0.0056838535, 0.010211409, -0.010999927, -0.027621859 }, { 0.0064753811, -0.0059341242, -0.014902755, 0.0082868118 }, { -0.0013222735, 0.0028492181, -0.023523273, -0.02576271 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }, { { 0.0011802354, -0.006546101, -0.02103972, 0.00086540469 }, { -0.015460534, 0.017874544, 0.0029121134, 0.023511773 }, { -0.040909245, 0.011927691, 0.011991588, 0.01677931 }, { -0.015633544, -0.0042321141, 0.026623034, 0.0080414514 }, { 0.012614382, 0.0065080145, 0.035716738, -0.0080665814 }, { -0.0057849744, -0.017478461, -0.031219642, 0.00016446523 }, { 0, 0.00032235028, 0, 0 }, { 0, 0, 0, 0 }, { -0.068586697, -0.024228236, -0.012857221, -0.039493706 }, { -0.018078201, -0.015140979, 0.00072119173, -0.051249859 }, { -0.054228277, 0.0097895101, 0.0019832646, -0.011715411 }, { -0.042326208, -0.010160072, 0.037088052, -0.031848667 }, { 0.00067130897, -0.013966717, -0.017268559, -0.0074614576 }, { 0.070515961, 0.012848107, -0.0008396517, 0.0049006506 }, { 0, 0, -0.063014256, -0.0085124986 }, { 0, 0, 0, 0 }, { -0.040302299, 0.0048936307, 0.0064406394, 0.0034044871 }, { -0.010453589, 0.0035820836, -0.017384391, -0.038199947 }, { -0.044968611, -0.0088322127, 0.020303819, 0.0058131005 }, { -0.0056838535, 0.010211409, -0.010999927, -0.027621859 }, { 0.0064753811, -0.0059341242, -0.014902755, 0.0082868118 }, { -0.0013222735, 0.0028492181, -0.023523273, -0.02576271 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } } }, { { { 0.72189984, 0.22069996, 0.71952927, 0.77725949 }, { 0.4054405, 0.20582059, 0.2747016, 0.37612563 }, { 0.58887422, 0.27441131, 0.19468101, 0.21480554 }, { 0.46814145, 0.34317, 0.46068212, 0.13962064 }, { -0.18134132, -0.26668789, -0.60984999, -0.67879259 }, { -0.47870351, -0.34453227, 0.32494779, 0.10292971 }, { 0.087252967, 0.066950358, 0.31813819, 0.071094818 }, { -0.0031436256, 0.038245091, -0.0076651913, -0.015389479 }, { 1.2668531, 1.2894974, 0.40584018, 0.51755806 }, { 1.3207257, 1.3403747, 0.54924634, 0.40282713 }, { 0.78581828, 0.56379328, 0.27901993, 0.56429306 }, { 0.8748226, 1.0271253, 1.0085726, 0.3888545 }, { -0.22577636, -0.32895071, -0.2846317, -0.11679531 }, { 0.26477285, 0.3179447, -0.063393238, 0.024059773 }, { -0.15463395, -0.22721468, -0.20680404, -0.15700788 }, { 0.012107106, -0.0061245949, -0.024224367, 0.005040693 }, { 0.97943693, 0.64840429, 0.45106998, 0.40771935 }, { 0.49907853, 0.1562184, 0.34338458, 0.39710628 }, { 0.95047709, 0.53336107, 0.38318275, 0.44919148 }, { 0.41892697, 0.069965886, 0.45831656, 0.38821529 }, { -0.20216736, -0.43209441, -0.57684857, -0.40189427 }, { -0.63992377, -0.40683032, -0.59207903, -0.57251716 }, { -0.047117438, -0.1880015, -0.12265155, 0.00059988607 }, { -0.011836442, -0.010049497, -0.0026152072, 0.016137736 } }, { { 0.092068993, 0.0045466749, 0.0054574031, 0.02582156 }, { 0.022115456, -0.015664041, -0.022004653, 0.041431654 }, { 0.029951298, -0.0004408542, 0.0087496069, 0.017850027 }, { 0.029086373, 0.022116039, 0.044010315, 0.001644876 }, { 0.016256387, 0.0083249367, 0.019570849, -0.0021276222 }, { 0.0079070076, -0.024696939, 0.044311101, 0.023671132 }, { -0.0081796119, -0.0024995551, 0.033501743, -0.031958988 }, { 0.0065005403, -0.076642001, 0.015736477, 0.030966939 }, { 0.029110717, 0.039154477, -0.074376619, 0.025532063 }, { -0.10980761, 0.0038346834, 0.014449171, -0.030702653 }, { -0.00068350423, -0.037251569, -0.008409224, -0.026322878 }, { 0.035406012, 0.064176275, 0.031437854, -0.0344642 }, { 0.037145809, -0.024909212, 0.041030386, 0.035216105 }, { -0.093276646, -0.013904083, -0.019536023, -0.023834405 }, { 0.042751846, -0.03620164, 0.081115921, 0.018379967 }, { -0.023909625, 0.012833691, 0.048086442, -0.0097340268 }, { 0.039552712, -0.00026806514, 0.011646753, 0.0065939486 }, { 0.058985248, 0.020165701, 0.0076721521, 0.033274221 }, { 0.052889871, 0.0042520093, 0.016490396, 0.009287973 }, { 0.044305975, -0.0016263469, 0.041390177, 0.033541355 }, { 0.014595133, -0.004801042, -0.0049517302, 0.015714264 }, { 0.00075086205, 0.0080838736, -0.037611057, -0.030488441 }, { 0.0019178075, -0.0082517768, -0.002525773, 0.0043993022 }, { 0.023774971, 0.020335611, 0.0056643868, -0.032100338 } }, { { 0.092068993, 0.0045466749, 0.0054574031, 0.02582156 }, { 0.022115456, -0.015664041, -0.022004653, 0.041431654 }, { 0.029951298, -0.0004408542, 0.0087496069, 0.017850027 }, { 0.029086373, 0.022116039, 0.044010315, 0.001644876 }, { 0.016256387, 0.0083249367, 0.019570849, -0.0021276222 }, { 0.0079070076, -0.024696939, 0.044311101, 0.023671132 }, { -0.0081796119, -0.0024995551, 0.033501743, -0.031958988 }, { 0.0065005403, -0.076642001, 0.015736477, 0.030966939 }, { 0.029110717, 0.039154477, -0.074376619, 0.025532063 }, { -0.10980761, 0.0038346834, 0.014449171, -0.030702653 }, { -0.00068350423, -0.037251569, -0.008409224, -0.026322878 }, { 0.035406012, 0.064176275, 0.031437854, -0.0344642 }, { 0.037145809, -0.024909212, 0.041030386, 0.035216105 }, { -0.093276646, -0.013904083, -0.019536023, -0.023834405 }, { 0.042751846, -0.03620164, 0.081115921, 0.018379967 }, { -0.023909625, 0.012833691, 0.048086442, -0.0097340268 }, { 0.039552712, -0.00026806514, 0.011646753, 0.0065939486 }, { 0.058985248, 0.020165701, 0.0076721521, 0.033274221 }, { 0.052889871, 0.0042520093, 0.016490396, 0.009287973 }, { 0.044305975, -0.0016263469, 0.041390177, 0.033541355 }, { 0.014595133, -0.004801042, -0.0049517303, 0.015714264 }, { 0.00075086205, 0.0080838736, -0.037611057, -0.030488441 }, { 0.0019178075, -0.0082517768, -0.002525773, 0.0043993022 }, { 0.023774971, 0.020335611, 0.0056643868, -0.032100338 } } } } }; + +#endif
\ No newline at end of file diff --git a/servers/visual/rasterizer_rd/rasterizer_effects_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_effects_rd.cpp index c05f5cead0..be9f1901a7 100644 --- a/servers/visual/rasterizer_rd/rasterizer_effects_rd.cpp +++ b/servers/visual/rasterizer_rd/rasterizer_effects_rd.cpp @@ -30,6 +30,8 @@ #include "rasterizer_effects_rd.h" #include "core/os/os.h" +#include "core/project_settings.h" +#include "cubemap_coeffs.h" static _FORCE_INLINE_ void store_transform_3x3(const Basis &p_basis, float *p_array) { p_array[0] = p_basis.elements[0][0]; @@ -750,6 +752,44 @@ void RasterizerEffectsRD::roughness_limit(RID p_source_normal, RID p_roughness, RD::get_singleton()->compute_list_end(); } +void RasterizerEffectsRD::cubemap_downsample(RID p_source_cubemap, bool p_source_is_panorama, RID p_dest_cubemap, const Size2i &p_size) { + + cubemap_downsampler.push_constant.face_size = p_size.x; + + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, cubemap_downsampler.pipelines[p_source_is_panorama ? CUBEMAP_DOWNSAMPLER_SOURCE_PANORAMA : CUBEMAP_DOWNSAMPLER_SOURCE_CUBEMAP]); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_cubemap), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_cubemap), 1); + + int x_groups = (p_size.x - 1) / 8 + 1; + int y_groups = (p_size.y - 1) / 8 + 1; + + RD::get_singleton()->compute_list_set_push_constant(compute_list, &cubemap_downsampler.push_constant, sizeof(CubemapDownsamplerPushConstant)); + + RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 6); // one z_group for each face + + RD::get_singleton()->compute_list_end(); +} + +void RasterizerEffectsRD::cubemap_filter(RID p_source_cubemap, Vector<RID> p_dest_cubemap, bool p_use_array) { + + int pipeline = p_use_array ? FILTER_MODE_HIGH_QUALITY_ARRAY : FILTER_MODE_HIGH_QUALITY; + pipeline = filter.use_high_quality ? pipeline : pipeline + 1; + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, filter.pipelines[pipeline]); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_cubemap, true), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, filter.uniform_set, 1); + for (int i = 0; i < p_dest_cubemap.size(); i++) { + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_cubemap[i]), i + 2); + } + + int x_groups = p_use_array ? 1792 : 342; // (128 * 128 * 7) / 64 : (128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2) / 64 + + RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, 6, 1); // one y_group for each face + + RD::get_singleton()->compute_list_end(); +} + RasterizerEffectsRD::RasterizerEffectsRD() { { @@ -930,7 +970,7 @@ RasterizerEffectsRD::RasterizerEffectsRD() { } { - // Initialize copier + // Initialize roughness limiter Vector<String> shader_modes; shader_modes.push_back(""); @@ -941,6 +981,55 @@ RasterizerEffectsRD::RasterizerEffectsRD() { roughness_limiter.pipeline = RD::get_singleton()->compute_pipeline_create(roughness_limiter.shader.version_get_shader(roughness_limiter.shader_version, 0)); } + { + //Initialize cubemap downsampler + Vector<String> cubemap_downsampler_modes; + cubemap_downsampler_modes.push_back("\n#define MODE_SOURCE_PANORAMA\n"); + cubemap_downsampler_modes.push_back("\n#define MODE_SOURCE_CUBEMAP\n"); + cubemap_downsampler.shader.initialize(cubemap_downsampler_modes); + + cubemap_downsampler.shader_version = cubemap_downsampler.shader.version_create(); + + for (int i = 0; i < CUBEMAP_DOWNSAMPLER_SOURCE_MAX; i++) { + cubemap_downsampler.pipelines[i] = RD::get_singleton()->compute_pipeline_create(cubemap_downsampler.shader.version_get_shader(cubemap_downsampler.shader_version, i)); + } + } + + { + // Initialize cubemap filter + filter.use_high_quality = GLOBAL_GET("rendering/quality/reflections/fast_filter_high_quality"); + + Vector<String> cubemap_filter_modes; + cubemap_filter_modes.push_back("\n#define USE_HIGH_QUALITY\n"); + cubemap_filter_modes.push_back("\n#define USE_LOW_QUALITY\n"); + cubemap_filter_modes.push_back("\n#define USE_HIGH_QUALITY\n#define USE_TEXTURE_ARRAY\n"); + cubemap_filter_modes.push_back("\n#define USE_LOW_QUALITY\n#define USE_TEXTURE_ARRAY\n"); + filter.shader.initialize(cubemap_filter_modes); + filter.shader_version = filter.shader.version_create(); + + for (int i = 0; i < FILTER_MODE_MAX; i++) { + filter.pipelines[i] = RD::get_singleton()->compute_pipeline_create(filter.shader.version_get_shader(filter.shader_version, i)); + } + + if (filter.use_high_quality) { + filter.coefficient_buffer = RD::get_singleton()->storage_buffer_create(sizeof(high_quality_coeffs)); + RD::get_singleton()->buffer_update(filter.coefficient_buffer, 0, sizeof(high_quality_coeffs), &high_quality_coeffs[0], false); + } else { + filter.coefficient_buffer = RD::get_singleton()->storage_buffer_create(sizeof(low_quality_coeffs)); + RD::get_singleton()->buffer_update(filter.coefficient_buffer, 0, sizeof(low_quality_coeffs), &low_quality_coeffs[0], false); + } + + Vector<RD::Uniform> uniforms; + { + RD::Uniform u; + u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER; + u.binding = 0; + u.ids.push_back(filter.coefficient_buffer); + uniforms.push_back(u); + } + filter.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, filter.shader.version_get_shader(filter.shader_version, filter.use_high_quality ? 0 : 1), 1); + } + RD::SamplerState sampler; sampler.mag_filter = RD::SAMPLER_FILTER_LINEAR; sampler.min_filter = RD::SAMPLER_FILTER_LINEAR; @@ -974,6 +1063,20 @@ RasterizerEffectsRD::RasterizerEffectsRD() { RasterizerEffectsRD::~RasterizerEffectsRD() { RD::get_singleton()->free(default_sampler); - blur.shader.version_free(blur.shader_version); + RD::get_singleton()->free(default_mipmap_sampler); RD::get_singleton()->free(index_buffer); //array gets freed as dependency + blur.shader.version_free(blur.shader_version); + roughness.shader.version_free(roughness.shader_version); + sky.shader.version_free(sky.shader_version); + tonemap.shader.version_free(tonemap.shader_version); + luminance_reduce.shader.version_free(luminance_reduce.shader_version); + copy.shader.version_free(copy.shader_version); + bokeh.shader.version_free(bokeh.shader_version); + ssao.minify_shader.version_free(ssao.minify_shader_version); + ssao.gather_shader.version_free(ssao.gather_shader_version); + ssao.blur_shader.version_free(ssao.blur_shader_version); + roughness_limiter.shader.version_free(roughness_limiter.shader_version); + cubemap_downsampler.shader.version_free(cubemap_downsampler.shader_version); + filter.shader.version_free(filter.shader_version); + RD::get_singleton()->free(filter.coefficient_buffer); } diff --git a/servers/visual/rasterizer_rd/rasterizer_effects_rd.h b/servers/visual/rasterizer_rd/rasterizer_effects_rd.h index cd5634d564..003ea33516 100644 --- a/servers/visual/rasterizer_rd/rasterizer_effects_rd.h +++ b/servers/visual/rasterizer_rd/rasterizer_effects_rd.h @@ -36,6 +36,8 @@ #include "servers/visual/rasterizer_rd/shaders/blur.glsl.gen.h" #include "servers/visual/rasterizer_rd/shaders/bokeh_dof.glsl.gen.h" #include "servers/visual/rasterizer_rd/shaders/copy.glsl.gen.h" +#include "servers/visual/rasterizer_rd/shaders/cubemap_downsampler.glsl.gen.h" +#include "servers/visual/rasterizer_rd/shaders/cubemap_filter.glsl.gen.h" #include "servers/visual/rasterizer_rd/shaders/cubemap_roughness.glsl.gen.h" #include "servers/visual/rasterizer_rd/shaders/luminance_reduce.glsl.gen.h" #include "servers/visual/rasterizer_rd/shaders/roughness_limiter.glsl.gen.h" @@ -355,6 +357,45 @@ class RasterizerEffectsRD { } roughness_limiter; + enum CubemapDownsamplerSource { + CUBEMAP_DOWNSAMPLER_SOURCE_PANORAMA, + CUBEMAP_DOWNSAMPLER_SOURCE_CUBEMAP, + CUBEMAP_DOWNSAMPLER_SOURCE_MAX + }; + + struct CubemapDownsamplerPushConstant { + uint32_t face_size; + float pad[3]; + }; + + struct CubemapDownsampler { + + CubemapDownsamplerPushConstant push_constant; + CubemapDownsamplerShaderRD shader; + RID shader_version; + RID pipelines[CUBEMAP_DOWNSAMPLER_SOURCE_MAX]; + + } cubemap_downsampler; + + enum CubemapFilterMode { + FILTER_MODE_HIGH_QUALITY, + FILTER_MODE_LOW_QUALITY, + FILTER_MODE_HIGH_QUALITY_ARRAY, + FILTER_MODE_LOW_QUALITY_ARRAY, + FILTER_MODE_MAX, + }; + + struct CubemapFilter { + + CubemapFilterShaderRD shader; + RID shader_version; + RID pipelines[FILTER_MODE_MAX]; + RID uniform_set; + RID coefficient_buffer; + bool use_high_quality; + + } filter; + RID default_sampler; RID default_mipmap_sampler; RID index_buffer; @@ -424,6 +465,8 @@ public: void generate_ssao(RID p_depth_buffer, RID p_normal_buffer, const Size2i &p_depth_buffer_size, RID p_depth_mipmaps_texture, const Vector<RID> &depth_mipmaps, RID p_ao1, bool p_half_size, RID p_ao2, RID p_upscale_buffer, float p_intensity, float p_radius, float p_bias, const CameraMatrix &p_projection, VS::EnvironmentSSAOQuality p_quality, VS::EnvironmentSSAOBlur p_blur, float p_edge_sharpness); void roughness_limit(RID p_source_normal, RID p_roughness, const Size2i &p_size, float p_curve); + void cubemap_downsample(RID p_source_cubemap, bool p_source_is_panorama, RID p_dest_cubemap, const Size2i &p_size); + void cubemap_filter(RID p_source_cubemap, Vector<RID> p_dest_cubemap, bool p_use_array); RasterizerEffectsRD(); ~RasterizerEffectsRD(); diff --git a/servers/visual/rasterizer_rd/rasterizer_scene_high_end_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_scene_high_end_rd.cpp index dd6bece11d..0a3105b143 100644 --- a/servers/visual/rasterizer_rd/rasterizer_scene_high_end_rd.cpp +++ b/servers/visual/rasterizer_rd/rasterizer_scene_high_end_rd.cpp @@ -2693,6 +2693,11 @@ RasterizerSceneHighEndRD::~RasterizerSceneHighEndRD() { RD::get_singleton()->free(view_dependant_uniform_set); } + RD::get_singleton()->free(default_render_buffers_uniform_set); + RD::get_singleton()->free(default_radiance_uniform_set); + RD::get_singleton()->free(default_vec4_xform_buffer); + RD::get_singleton()->free(shadow_sampler); + storage->free(wireframe_material_shader); storage->free(overdraw_material_shader); storage->free(default_shader); @@ -2702,6 +2707,11 @@ RasterizerSceneHighEndRD::~RasterizerSceneHighEndRD() { storage->free(default_material); { + RD::get_singleton()->free(scene_state.uniform_buffer); + RD::get_singleton()->free(scene_state.instance_buffer); + RD::get_singleton()->free(scene_state.gi_probe_buffer); + RD::get_singleton()->free(scene_state.directional_light_buffer); + RD::get_singleton()->free(scene_state.light_buffer); RD::get_singleton()->free(scene_state.reflection_buffer); memdelete_arr(scene_state.instances); memdelete_arr(scene_state.gi_probes); diff --git a/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp index a19e633089..7476bb6ae4 100644 --- a/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp +++ b/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp @@ -40,21 +40,29 @@ void RasterizerSceneRD::_clear_reflection_data(ReflectionData &rd) { rd.layers.clear(); rd.radiance_base_cubemap = RID(); + if (rd.downsampled_radiance_cubemap.is_valid()) { + RD::get_singleton()->free(rd.downsampled_radiance_cubemap); + } + rd.downsampled_radiance_cubemap = RID(); + rd.downsampled_layer.mipmaps.clear(); + rd.coefficient_buffer = RID(); } -void RasterizerSceneRD::_update_reflection_data(ReflectionData &rd, int p_size, int p_mipmaps, bool p_use_array, RID p_base_cube, int p_base_layer) { +void RasterizerSceneRD::_update_reflection_data(ReflectionData &rd, int p_size, int p_mipmaps, bool p_use_array, RID p_base_cube, int p_base_layer, bool p_low_quality) { //recreate radiance and all data int mipmaps = p_mipmaps; uint32_t w = p_size, h = p_size; if (p_use_array) { + int layers = p_low_quality ? 7 : roughness_layers; - for (int i = 0; i < roughness_layers; i++) { + for (int i = 0; i < layers; i++) { ReflectionData::Layer layer; uint32_t mmw = w; uint32_t mmh = h; layer.mipmaps.resize(mipmaps); + layer.views.resize(mipmaps); for (int j = 0; j < mipmaps; j++) { ReflectionData::Layer::Mipmap &mm = layer.mipmaps.write[j]; mm.size.width = mmw; @@ -66,6 +74,8 @@ void RasterizerSceneRD::_update_reflection_data(ReflectionData &rd, int p_size, mm.framebuffers[k] = RD::get_singleton()->framebuffer_create(fbtex); } + layer.views.write[j] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_base_cube, p_base_layer + i * 6, j, RD::TEXTURE_SLICE_CUBEMAP); + mmw = MAX(1, mmw >> 1); mmh = MAX(1, mmh >> 1); } @@ -74,12 +84,14 @@ void RasterizerSceneRD::_update_reflection_data(ReflectionData &rd, int p_size, } } else { + mipmaps = p_low_quality ? 7 : mipmaps; //regular cubemap, lower quality (aliasing, less memory) ReflectionData::Layer layer; uint32_t mmw = w; uint32_t mmh = h; - layer.mipmaps.resize(roughness_layers); - for (int j = 0; j < roughness_layers; j++) { + layer.mipmaps.resize(mipmaps); + layer.views.resize(mipmaps); + for (int j = 0; j < mipmaps; j++) { ReflectionData::Layer::Mipmap &mm = layer.mipmaps.write[j]; mm.size.width = mmw; mm.size.height = mmh; @@ -90,6 +102,8 @@ void RasterizerSceneRD::_update_reflection_data(ReflectionData &rd, int p_size, mm.framebuffers[k] = RD::get_singleton()->framebuffer_create(fbtex); } + layer.views.write[j] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_base_cube, p_base_layer, j, RD::TEXTURE_SLICE_CUBEMAP); + mmw = MAX(1, mmw >> 1); mmh = MAX(1, mmh >> 1); } @@ -98,13 +112,35 @@ void RasterizerSceneRD::_update_reflection_data(ReflectionData &rd, int p_size, } rd.radiance_base_cubemap = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_base_cube, p_base_layer, 0, RD::TEXTURE_SLICE_CUBEMAP); + + RD::TextureFormat tf; + tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; + tf.width = 64; // Always 64x64 + tf.height = 64; + tf.type = RD::TEXTURE_TYPE_CUBE; + tf.array_layers = 6; + tf.mipmaps = 7; + tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; + + rd.downsampled_radiance_cubemap = RD::get_singleton()->texture_create(tf, RD::TextureView()); + { + uint32_t mmw = 64; + uint32_t mmh = 64; + rd.downsampled_layer.mipmaps.resize(7); + for (int j = 0; j < rd.downsampled_layer.mipmaps.size(); j++) { + ReflectionData::DownsampleLayer::Mipmap &mm = rd.downsampled_layer.mipmaps.write[j]; + mm.size.width = mmw; + mm.size.height = mmh; + mm.view = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rd.downsampled_radiance_cubemap, 0, j, RD::TEXTURE_SLICE_CUBEMAP); + + mmw = MAX(1, mmw >> 1); + mmh = MAX(1, mmh >> 1); + } + } } void RasterizerSceneRD::_create_reflection_from_panorama(ReflectionData &rd, RID p_panorama, bool p_quality) { -#ifndef _MSC_VER -#warning TODO, should probably use this algorithm instead. Volunteers? - https://www.ppsloan.org/publications/ggx_filtering.pdf / https://github.com/dariomanesku/cmft -#endif if (sky_use_cubemap_array) { if (p_quality) { @@ -115,19 +151,18 @@ void RasterizerSceneRD::_create_reflection_from_panorama(ReflectionData &rd, RID } } } else { - //render to first mipmap - for (int j = 0; j < 6; j++) { - storage->get_effects()->cubemap_roughness(p_panorama, true, rd.layers[0].mipmaps[0].framebuffers[j], j, sky_ggx_samples_realtime, 0.0); + // Use fast filtering. Render directly to base mip levels + storage->get_effects()->cubemap_downsample(p_panorama, true, rd.downsampled_layer.mipmaps[0].view, rd.downsampled_layer.mipmaps[0].size); + + for (int i = 1; i < rd.downsampled_layer.mipmaps.size(); i++) { + storage->get_effects()->cubemap_downsample(rd.downsampled_layer.mipmaps[i - 1].view, false, rd.downsampled_layer.mipmaps[i].view, rd.downsampled_layer.mipmaps[i].size); } - //do the rest in other mipmaps and use cubemap itself as source - for (int i = 1; i < roughness_layers; i++) { - //render using a smaller mipmap, then copy to main layer - for (int j = 0; j < 6; j++) { - //storage->get_effects()->cubemap_roughness(rd.radiance_base_cubemap, false, rd.layers[0].mipmaps[i].framebuffers[0], j, sky_ggx_samples_realtime, float(i) / (rd.layers.size() - 1.0)); - storage->get_effects()->cubemap_roughness(p_panorama, true, rd.layers[0].mipmaps[i].framebuffers[0], j, sky_ggx_samples_realtime, float(i) / (rd.layers.size() - 1.0)); - storage->get_effects()->region_copy(rd.layers[0].mipmaps[i].views[0], rd.layers[i].mipmaps[0].framebuffers[j], Rect2()); - } + Vector<RID> views; + for (int i = 0; i < rd.layers.size(); i++) { + views.push_back(rd.layers[i].views[0]); } + + storage->get_effects()->cubemap_filter(rd.downsampled_radiance_cubemap, views, true); } } else { @@ -139,16 +174,13 @@ void RasterizerSceneRD::_create_reflection_from_panorama(ReflectionData &rd, RID } } } else { + // Use fast filtering. Render directly to each mip level + storage->get_effects()->cubemap_downsample(p_panorama, true, rd.downsampled_layer.mipmaps[0].view, rd.downsampled_layer.mipmaps[0].size); - for (int j = 0; j < 6; j++) { - storage->get_effects()->cubemap_roughness(p_panorama, true, rd.layers[0].mipmaps[0].framebuffers[j], j, sky_ggx_samples_realtime, 0); - } - - for (int i = 1; i < rd.layers[0].mipmaps.size(); i++) { - for (int j = 0; j < 6; j++) { - storage->get_effects()->cubemap_roughness(rd.radiance_base_cubemap, false, rd.layers[0].mipmaps[i].framebuffers[j], j, sky_ggx_samples_realtime, float(i) / (rd.layers[0].mipmaps.size() - 1.0)); - } + for (int i = 1; i < rd.downsampled_layer.mipmaps.size(); i++) { + storage->get_effects()->cubemap_downsample(rd.downsampled_layer.mipmaps[i - 1].view, false, rd.downsampled_layer.mipmaps[i].view, rd.downsampled_layer.mipmaps[i].size); } + storage->get_effects()->cubemap_filter(rd.downsampled_radiance_cubemap, rd.layers[0].views, false); } } } @@ -163,12 +195,18 @@ void RasterizerSceneRD::_create_reflection_from_base_mipmap(ReflectionData &rd, storage->get_effects()->cubemap_roughness(rd.radiance_base_cubemap, false, rd.layers[i].mipmaps[0].framebuffers[p_cube_side], p_cube_side, sky_ggx_samples_quality, float(i) / (rd.layers.size() - 1.0)); } } else { - //do the rest in other mipmaps and use cubemap itself as source - for (int i = 1; i < roughness_layers; i++) { - //render using a smaller mipmap, then copy to main layer - storage->get_effects()->cubemap_roughness(rd.radiance_base_cubemap, false, rd.layers[0].mipmaps[i].framebuffers[0], p_cube_side, sky_ggx_samples_realtime, float(i) / (rd.layers.size() - 1.0)); - storage->get_effects()->region_copy(rd.layers[0].mipmaps[i].views[0], rd.layers[i].mipmaps[0].framebuffers[p_cube_side], Rect2()); + + storage->get_effects()->cubemap_downsample(rd.radiance_base_cubemap, false, rd.downsampled_layer.mipmaps[0].view, rd.downsampled_layer.mipmaps[0].size); + + for (int i = 1; i < rd.downsampled_layer.mipmaps.size(); i++) { + storage->get_effects()->cubemap_downsample(rd.downsampled_layer.mipmaps[i - 1].view, false, rd.downsampled_layer.mipmaps[i].view, rd.downsampled_layer.mipmaps[i].size); + } + Vector<RID> views; + for (int i = 0; i < rd.layers.size(); i++) { + views.push_back(rd.layers[i].views[0]); } + + storage->get_effects()->cubemap_filter(rd.downsampled_radiance_cubemap, views, true); } } else { @@ -179,9 +217,12 @@ void RasterizerSceneRD::_create_reflection_from_base_mipmap(ReflectionData &rd, } } else { - for (int i = 1; i < rd.layers[0].mipmaps.size(); i++) { - storage->get_effects()->cubemap_roughness(rd.radiance_base_cubemap, false, rd.layers[0].mipmaps[i].framebuffers[p_cube_side], p_cube_side, sky_ggx_samples_realtime, float(i) / (rd.layers[0].mipmaps.size() - 1.0)); + storage->get_effects()->cubemap_downsample(rd.radiance_base_cubemap, false, rd.downsampled_layer.mipmaps[0].view, rd.downsampled_layer.mipmaps[0].size); + + for (int i = 1; i < rd.downsampled_layer.mipmaps.size(); i++) { + storage->get_effects()->cubemap_downsample(rd.downsampled_layer.mipmaps[i - 1].view, false, rd.downsampled_layer.mipmaps[i].view, rd.downsampled_layer.mipmaps[i].size); } + storage->get_effects()->cubemap_filter(rd.downsampled_radiance_cubemap, rd.layers[0].views, false); } } } @@ -224,6 +265,12 @@ void RasterizerSceneRD::sky_set_radiance_size(RID p_sky, int p_radiance_size) { return; } sky->radiance_size = p_radiance_size; + + if (sky->mode == VS::SKY_MODE_REALTIME && sky->radiance_size != 128) { + WARN_PRINT("Realtime Skies can only use a radiance size of 128. Radiance size will be set to 128 internally."); + sky->radiance_size = 128; + } + _sky_invalidate(sky); if (sky->radiance.is_valid()) { RD::get_singleton()->free(sky->radiance); @@ -241,7 +288,18 @@ void RasterizerSceneRD::sky_set_mode(RID p_sky, VS::SkyMode p_mode) { } sky->mode = p_mode; + + if (sky->mode == VS::SKY_MODE_REALTIME && sky->radiance_size != 128) { + WARN_PRINT("Realtime Skies can only use a radiance size of 128. Radiance size will be set to 128 internally."); + sky_set_radiance_size(p_sky, 128); + } + _sky_invalidate(sky); + if (sky->radiance.is_valid()) { + RD::get_singleton()->free(sky->radiance); + sky->radiance = RID(); + } + _clear_reflection_data(sky->reflection); } void RasterizerSceneRD::sky_set_texture(RID p_sky, RID p_panorama) { @@ -275,27 +333,24 @@ void RasterizerSceneRD::_update_dirty_skys() { if (sky->radiance.is_null()) { int mipmaps = Image::get_image_required_mipmaps(sky->radiance_size, sky->radiance_size, Image::FORMAT_RGBAH) + 1; - if (sky->mode != VS::SKY_MODE_QUALITY) { - //use less mipmaps - mipmaps = MIN(8, mipmaps); - } uint32_t w = sky->radiance_size, h = sky->radiance_size; + int layers = sky->mode == VS::SKY_MODE_REALTIME ? 7 : roughness_layers; if (sky_use_cubemap_array) { //array (higher quality, 6 times more memory) RD::TextureFormat tf; - tf.array_layers = roughness_layers * 6; + tf.array_layers = layers * 6; tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; tf.type = RD::TEXTURE_TYPE_CUBE_ARRAY; tf.mipmaps = mipmaps; tf.width = w; tf.height = h; - tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT; + tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; sky->radiance = RD::get_singleton()->texture_create(tf, RD::TextureView()); - _update_reflection_data(sky->reflection, sky->radiance_size, mipmaps, true, sky->radiance, 0); + _update_reflection_data(sky->reflection, sky->radiance_size, mipmaps, true, sky->radiance, 0, sky->mode == VS::SKY_MODE_REALTIME); } else { //regular cubemap, lower quality (aliasing, less memory) @@ -303,14 +358,14 @@ void RasterizerSceneRD::_update_dirty_skys() { tf.array_layers = 6; tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; tf.type = RD::TEXTURE_TYPE_CUBE; - tf.mipmaps = roughness_layers; + tf.mipmaps = MIN(mipmaps, layers); tf.width = w; tf.height = h; - tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT; + tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; sky->radiance = RD::get_singleton()->texture_create(tf, RD::TextureView()); - _update_reflection_data(sky->reflection, sky->radiance_size, mipmaps, false, sky->radiance, 0); + _update_reflection_data(sky->reflection, sky->radiance_size, MIN(mipmaps, layers), false, sky->radiance, 0, sky->mode == VS::SKY_MODE_REALTIME); } } @@ -591,6 +646,9 @@ void RasterizerSceneRD::reflection_atlas_set_size(RID p_ref_atlas, int p_reflect return; //no changes } + ra->size = p_reflection_size; + ra->count = p_reflection_count; + if (ra->reflection.is_valid()) { //clear and invalidate everything RD::get_singleton()->free(ra->reflection); @@ -673,17 +731,27 @@ bool RasterizerSceneRD::reflection_probe_instance_begin_render(RID p_instance, R ERR_FAIL_COND_V(!atlas, false); + ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); + ERR_FAIL_COND_V(!rpi, false); + + if (storage->reflection_probe_get_update_mode(rpi->probe) == VS::REFLECTION_PROBE_UPDATE_ALWAYS && atlas->reflection.is_valid() && atlas->size != 128) { + WARN_PRINT("ReflectionProbes set to UPDATE_ALWAYS must have an atlas size of 128. Please update the atlas size in the ProjectSettings."); + reflection_atlas_set_size(p_reflection_atlas, 128, atlas->count); + } + if (atlas->reflection.is_null()) { + int mipmaps = MIN(roughness_layers, Image::get_image_required_mipmaps(atlas->size, atlas->size, Image::FORMAT_RGBAH) + 1); + mipmaps = storage->reflection_probe_get_update_mode(rpi->probe) == VS::REFLECTION_PROBE_UPDATE_ALWAYS ? 7 : mipmaps; // always use 7 mipmaps with real time filtering { //reflection atlas was unused, create: RD::TextureFormat tf; tf.array_layers = 6 * atlas->count; tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; tf.type = RD::TEXTURE_TYPE_CUBE_ARRAY; - tf.mipmaps = roughness_layers; + tf.mipmaps = mipmaps; tf.width = atlas->size; tf.height = atlas->size; - tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT; + tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; atlas->reflection = RD::get_singleton()->texture_create(tf, RD::TextureView()); } @@ -698,7 +766,7 @@ bool RasterizerSceneRD::reflection_probe_instance_begin_render(RID p_instance, R } atlas->reflections.resize(atlas->count); for (int i = 0; i < atlas->count; i++) { - _update_reflection_data(atlas->reflections.write[i].data, atlas->size, roughness_layers, false, atlas->reflection, i * 6); + _update_reflection_data(atlas->reflections.write[i].data, atlas->size, mipmaps, false, atlas->reflection, i * 6, storage->reflection_probe_get_update_mode(rpi->probe) == VS::REFLECTION_PROBE_UPDATE_ALWAYS); for (int j = 0; j < 6; j++) { Vector<RID> fb; fb.push_back(atlas->reflections.write[i].data.layers[0].mipmaps[0].views[j]); @@ -712,9 +780,6 @@ bool RasterizerSceneRD::reflection_probe_instance_begin_render(RID p_instance, R atlas->depth_fb = RD::get_singleton()->framebuffer_create(fb); } - ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance); - ERR_FAIL_COND_V(!rpi, false); - if (rpi->atlas_index == -1) { for (int i = 0; i < atlas->reflections.size(); i++) { if (atlas->reflections[i].owner.is_null()) { @@ -761,6 +826,13 @@ bool RasterizerSceneRD::reflection_probe_instance_postprocess_step(RID p_instanc _create_reflection_from_base_mipmap(atlas->reflections.write[rpi->atlas_index].data, false, storage->reflection_probe_get_update_mode(rpi->probe) == VS::REFLECTION_PROBE_UPDATE_ONCE, rpi->processing_side); + if (storage->reflection_probe_get_update_mode(rpi->probe) == VS::REFLECTION_PROBE_UPDATE_ALWAYS) { + // Using real time reflections, all roughness is done in one step + rpi->rendering = false; + rpi->processing_side = 0; + return true; + } + rpi->processing_side++; if (rpi->processing_side == 6) { @@ -814,7 +886,7 @@ void RasterizerSceneRD::shadow_atlas_set_size(RID p_atlas, int p_size) { ERR_FAIL_COND(!shadow_atlas); ERR_FAIL_COND(p_size < 0); p_size = next_power_of_2(p_size); - p_size = MAX(p_size, 1 << roughness_layers); + p_size = MAX(p_size, 1 << roughness_layers); // TODO: use a number related to shadows rather than reflections if (p_size == shadow_atlas->size) return; @@ -3025,7 +3097,6 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) { roughness_layers = GLOBAL_GET("rendering/quality/reflections/roughness_layers"); sky_ggx_samples_quality = GLOBAL_GET("rendering/quality/reflections/ggx_samples"); - sky_ggx_samples_realtime = GLOBAL_GET("rendering/quality/reflections/ggx_samples_realtime"); sky_use_cubemap_array = GLOBAL_GET("rendering/quality/reflections/texture_array_reflections"); // sky_use_cubemap_array = false; @@ -3130,5 +3201,7 @@ RasterizerSceneRD::~RasterizerSceneRD() { } RD::get_singleton()->free(gi_probe_lights_uniform); + giprobe_debug_shader.version_free(giprobe_debug_shader_version); + giprobe_shader.version_free(giprobe_lighting_shader_version); memdelete_arr(gi_probe_lights); } diff --git a/servers/visual/rasterizer_rd/rasterizer_scene_rd.h b/servers/visual/rasterizer_rd/rasterizer_scene_rd.h index 541c28f11f..3e3ad5e4f5 100644 --- a/servers/visual/rasterizer_rd/rasterizer_scene_rd.h +++ b/servers/visual/rasterizer_rd/rasterizer_scene_rd.h @@ -85,15 +85,28 @@ private: RID views[6]; Size2i size; }; + Vector<Mipmap> mipmaps; //per-face view + Vector<RID> views; // per-cubemap view + }; + + struct DownsampleLayer { + struct Mipmap { + RID view; + Size2i size; + }; Vector<Mipmap> mipmaps; }; + RID radiance_base_cubemap; //cubemap for first layer, first cubemap + RID downsampled_radiance_cubemap; + DownsampleLayer downsampled_layer; + RID coefficient_buffer; Vector<Layer> layers; }; void _clear_reflection_data(ReflectionData &rd); - void _update_reflection_data(ReflectionData &rd, int p_size, int p_mipmaps, bool p_use_array, RID p_base_cube, int p_base_layer); + void _update_reflection_data(ReflectionData &rd, int p_size, int p_mipmaps, bool p_use_array, RID p_base_cube, int p_base_layer, bool p_low_quality); void _create_reflection_from_panorama(ReflectionData &rd, RID p_panorama, bool p_quality); void _create_reflection_from_base_mipmap(ReflectionData &rd, bool p_use_arrays, bool p_quality, int p_cube_side); void _update_reflection_mipmaps(ReflectionData &rd, bool p_quality); @@ -102,7 +115,7 @@ private: struct Sky { RID radiance; RID uniform_set; - int radiance_size = 256; + int radiance_size = 128; VS::SkyMode mode = VS::SKY_MODE_QUALITY; RID panorama; ReflectionData reflection; @@ -116,7 +129,6 @@ private: void _update_dirty_skys(); uint32_t sky_ggx_samples_quality; - uint32_t sky_ggx_samples_realtime; bool sky_use_cubemap_array; mutable RID_Owner<Sky> sky_owner; diff --git a/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp index 5d43876192..15cbc61b76 100644 --- a/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp +++ b/servers/visual/rasterizer_rd/rasterizer_storage_rd.cpp @@ -4814,4 +4814,5 @@ RasterizerStorageRD::~RasterizerStorageRD() { for (int i = 0; i < DEFAULT_RD_BUFFER_MAX; i++) { RD::get_singleton()->free(mesh_default_rd_buffers[i]); } + giprobe_sdf_shader.version_free(giprobe_sdf_shader_version); } diff --git a/servers/visual/rasterizer_rd/shader_rd.cpp b/servers/visual/rasterizer_rd/shader_rd.cpp index cc6c13f598..857a29f7f4 100644 --- a/servers/visual/rasterizer_rd/shader_rd.cpp +++ b/servers/visual/rasterizer_rd/shader_rd.cpp @@ -342,23 +342,21 @@ void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) { } if (!build_ok) { - variant_set_mutex.lock(); //properly print the errors + MutexLock lock(variant_set_mutex); //properly print the errors ERR_PRINT("Error compiling " + String(current_stage == RD::SHADER_STAGE_COMPUTE ? "Compute " : (current_stage == RD::SHADER_STAGE_VERTEX ? "Vertex" : "Fragment")) + " shader, variant #" + itos(p_variant) + " (" + variant_defines[p_variant].get_data() + ")."); ERR_PRINT(error); #ifdef DEBUG_ENABLED ERR_PRINT("code:\n" + current_source.get_with_code_lines()); #endif - - variant_set_mutex.unlock(); return; } RID shader = RD::get_singleton()->shader_create(stages); - - variant_set_mutex.lock(); - p_version->variants[p_variant] = shader; - variant_set_mutex.unlock(); + { + MutexLock lock(variant_set_mutex); + p_version->variants[p_variant] = shader; + } } void ShaderRD::_compile_version(Version *p_version) { diff --git a/servers/visual/rasterizer_rd/shader_rd.h b/servers/visual/rasterizer_rd/shader_rd.h index 8581b85ff4..6635b08cc8 100644 --- a/servers/visual/rasterizer_rd/shader_rd.h +++ b/servers/visual/rasterizer_rd/shader_rd.h @@ -33,11 +33,11 @@ #include "core/hash_map.h" #include "core/map.h" +#include "core/os/mutex.h" #include "core/rid_owner.h" #include "core/variant.h" #include <stdio.h> -#include <mutex> /** @author Juan Linietsky <reduzio@gmail.com> */ @@ -66,7 +66,7 @@ class ShaderRD { bool initialize_needed; }; - std::mutex variant_set_mutex; + Mutex variant_set_mutex; void _compile_variant(uint32_t p_variant, Version *p_version); diff --git a/servers/visual/rasterizer_rd/shaders/SCsub b/servers/visual/rasterizer_rd/shaders/SCsub index 9a28ef062c..2dcb2a703f 100644 --- a/servers/visual/rasterizer_rd/shaders/SCsub +++ b/servers/visual/rasterizer_rd/shaders/SCsub @@ -7,6 +7,8 @@ if 'RD_GLSL' in env['BUILDERS']: env.RD_GLSL('canvas_occlusion.glsl'); env.RD_GLSL('blur.glsl'); env.RD_GLSL('cubemap_roughness.glsl'); + env.RD_GLSL('cubemap_downsampler.glsl'); + env.RD_GLSL('cubemap_filter.glsl'); env.RD_GLSL('scene_high_end.glsl'); env.RD_GLSL('sky.glsl'); env.RD_GLSL('tonemap.glsl'); diff --git a/servers/visual/rasterizer_rd/shaders/cubemap_downsampler.glsl b/servers/visual/rasterizer_rd/shaders/cubemap_downsampler.glsl new file mode 100644 index 0000000000..b042dc8868 --- /dev/null +++ b/servers/visual/rasterizer_rd/shaders/cubemap_downsampler.glsl @@ -0,0 +1,220 @@ +// Copyright 2016 Activision Publishing, Inc. +// +// 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. + +/* clang-format off */ +[compute] + +#version 450 + +VERSION_DEFINES + +#define BLOCK_SIZE 8 + +layout(local_size_x = BLOCK_SIZE, local_size_y = BLOCK_SIZE, local_size_z = 1) in; +/* clang-format on */ + +#ifdef MODE_SOURCE_PANORAMA +layout(set = 0, binding = 0) uniform sampler2D source_panorama; +#endif + +#ifdef MODE_SOURCE_CUBEMAP +layout(set = 0, binding = 0) uniform samplerCube source_cubemap; +#endif + +layout(rgba16f, set = 1, binding = 0) uniform restrict writeonly imageCube dest_cubemap; + +layout(push_constant, binding = 1, std430) uniform Params { + uint face_size; +} +params; + +#define M_PI 3.14159265359 + +void get_dir_0(out vec3 dir, in float u, in float v) { + dir[0] = 1.0; + dir[1] = v; + dir[2] = -u; +} +void get_dir_1(out vec3 dir, in float u, in float v) { + dir[0] = -1.0; + dir[1] = v; + dir[2] = u; +} +void get_dir_2(out vec3 dir, in float u, in float v) { + dir[0] = u; + dir[1] = 1.0; + dir[2] = -v; +} +void get_dir_3(out vec3 dir, in float u, in float v) { + dir[0] = u; + dir[1] = -1.0; + dir[2] = v; +} +void get_dir_4(out vec3 dir, in float u, in float v) { + dir[0] = u; + dir[1] = v; + dir[2] = 1.0; +} +void get_dir_5(out vec3 dir, in float u, in float v) { + dir[0] = -u; + dir[1] = v; + dir[2] = -1.0; +} + +float calcWeight(float u, float v) { + float val = u * u + v * v + 1.0; + return val * sqrt(val); +} + +#ifdef MODE_SOURCE_PANORAMA + +vec4 texturePanorama(vec3 normal, sampler2D pano) { + + vec2 st = vec2( + atan(normal.x, -normal.z), + acos(normal.y)); + + if (st.x < 0.0) + st.x += M_PI * 2.0; + + st /= vec2(M_PI * 2.0, M_PI); + + return textureLod(pano, st, 0.0); +} + +#endif + +vec4 get_texture(vec3 p_dir) { +#ifdef MODE_SOURCE_PANORAMA + return texturePanorama(normalize(p_dir), source_panorama); +#else + return textureLod(source_cubemap, normalize(p_dir), 0.0); +#endif +} + +void main() { + uvec3 id = gl_GlobalInvocationID; + uint face_size = params.face_size; + + if (id.x < face_size && id.y < face_size) { + float inv_face_size = 1.0 / float(face_size); + + float u0 = (float(id.x) * 2.0 + 1.0 - 0.75) * inv_face_size - 1.0; + float u1 = (float(id.x) * 2.0 + 1.0 + 0.75) * inv_face_size - 1.0; + + float v0 = (float(id.y) * 2.0 + 1.0 - 0.75) * -inv_face_size + 1.0; + float v1 = (float(id.y) * 2.0 + 1.0 + 0.75) * -inv_face_size + 1.0; + + float weights[4]; + weights[0] = calcWeight(u0, v0); + weights[1] = calcWeight(u1, v0); + weights[2] = calcWeight(u0, v1); + weights[3] = calcWeight(u1, v1); + + const float wsum = 0.5 / (weights[0] + weights[1] + weights[2] + weights[3]); + for (int i = 0; i < 4; i++) { + weights[i] = weights[i] * wsum + .125; + } + + vec3 dir; + vec4 color; + switch (id.z) { + case 0: + get_dir_0(dir, u0, v0); + color = get_texture(dir) * weights[0]; + + get_dir_0(dir, u1, v0); + color += get_texture(dir) * weights[1]; + + get_dir_0(dir, u0, v1); + color += get_texture(dir) * weights[2]; + + get_dir_0(dir, u1, v1); + color += get_texture(dir) * weights[3]; + break; + case 1: + get_dir_1(dir, u0, v0); + color = get_texture(dir) * weights[0]; + + get_dir_1(dir, u1, v0); + color += get_texture(dir) * weights[1]; + + get_dir_1(dir, u0, v1); + color += get_texture(dir) * weights[2]; + + get_dir_1(dir, u1, v1); + color += get_texture(dir) * weights[3]; + break; + case 2: + get_dir_2(dir, u0, v0); + color = get_texture(dir) * weights[0]; + + get_dir_2(dir, u1, v0); + color += get_texture(dir) * weights[1]; + + get_dir_2(dir, u0, v1); + color += get_texture(dir) * weights[2]; + + get_dir_2(dir, u1, v1); + color += get_texture(dir) * weights[3]; + break; + case 3: + get_dir_3(dir, u0, v0); + color = get_texture(dir) * weights[0]; + + get_dir_3(dir, u1, v0); + color += get_texture(dir) * weights[1]; + + get_dir_3(dir, u0, v1); + color += get_texture(dir) * weights[2]; + + get_dir_3(dir, u1, v1); + color += get_texture(dir) * weights[3]; + break; + case 4: + get_dir_4(dir, u0, v0); + color = get_texture(dir) * weights[0]; + + get_dir_4(dir, u1, v0); + color += get_texture(dir) * weights[1]; + + get_dir_4(dir, u0, v1); + color += get_texture(dir) * weights[2]; + + get_dir_4(dir, u1, v1); + color += get_texture(dir) * weights[3]; + break; + default: + get_dir_5(dir, u0, v0); + color = get_texture(dir) * weights[0]; + + get_dir_5(dir, u1, v0); + color += get_texture(dir) * weights[1]; + + get_dir_5(dir, u0, v1); + color += get_texture(dir) * weights[2]; + + get_dir_5(dir, u1, v1); + color += get_texture(dir) * weights[3]; + break; + } + imageStore(dest_cubemap, ivec3(id), color); + } +}
\ No newline at end of file diff --git a/servers/visual/rasterizer_rd/shaders/cubemap_filter.glsl b/servers/visual/rasterizer_rd/shaders/cubemap_filter.glsl new file mode 100644 index 0000000000..58c5af9c41 --- /dev/null +++ b/servers/visual/rasterizer_rd/shaders/cubemap_filter.glsl @@ -0,0 +1,289 @@ +// Copyright 2016 Activision Publishing, Inc. +// +// 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. + +/* clang-format off */ +[compute] + +#version 450 + +VERSION_DEFINES + +#define GROUP_SIZE 64 + +layout(local_size_x = GROUP_SIZE, local_size_y = 1, local_size_z = 1) in; +/* clang-format on */ + +layout(set = 0, binding = 0) uniform samplerCube source_cubemap; +layout(rgba16f, set = 2, binding = 0) uniform restrict writeonly imageCube dest_cubemap0; +layout(rgba16f, set = 3, binding = 0) uniform restrict writeonly imageCube dest_cubemap1; +layout(rgba16f, set = 4, binding = 0) uniform restrict writeonly imageCube dest_cubemap2; +layout(rgba16f, set = 5, binding = 0) uniform restrict writeonly imageCube dest_cubemap3; +layout(rgba16f, set = 6, binding = 0) uniform restrict writeonly imageCube dest_cubemap4; +layout(rgba16f, set = 7, binding = 0) uniform restrict writeonly imageCube dest_cubemap5; +layout(rgba16f, set = 8, binding = 0) uniform restrict writeonly imageCube dest_cubemap6; + +#ifdef USE_HIGH_QUALITY +#define NUM_TAPS 32 +#else +#define NUM_TAPS 8 +#endif + +#define BASE_RESOLUTION 128 + +#ifdef USE_HIGH_QUALITY +layout(set = 1, binding = 0, std430) buffer restrict readonly Data { + vec4[7][5][3][24] coeffs; +} +data; +#else +layout(set = 1, binding = 0, std430) buffer restrict readonly Data { + vec4[7][5][6] coeffs; +} +data; +#endif + +void get_dir(out vec3 dir, in vec2 uv, in uint face) { + switch (face) { + case 0: + dir = vec3(1.0, uv[1], -uv[0]); + break; + case 1: + dir = vec3(-1.0, uv[1], uv[0]); + break; + case 2: + dir = vec3(uv[0], 1.0, -uv[1]); + break; + case 3: + dir = vec3(uv[0], -1.0, uv[1]); + break; + case 4: + dir = vec3(uv[0], uv[1], 1.0); + break; + default: + dir = vec3(-uv[0], uv[1], -1.0); + break; + } +} + +void main() { + // INPUT: + // id.x = the linear address of the texel (ignoring face) + // id.y = the face + // -> use to index output texture + // id.x = texel x + // id.y = texel y + // id.z = face + uvec3 id = gl_GlobalInvocationID; + + // determine which texel this is +#ifndef USE_TEXTURE_ARRAY + int level = 0; + if (id.x < (128 * 128)) { + level = 0; + } else if (id.x < (128 * 128 + 64 * 64)) { + level = 1; + id.x -= (128 * 128); + } else if (id.x < (128 * 128 + 64 * 64 + 32 * 32)) { + level = 2; + id.x -= (128 * 128 + 64 * 64); + } else if (id.x < (128 * 128 + 64 * 64 + 32 * 32 + 16 * 16)) { + level = 3; + id.x -= (128 * 128 + 64 * 64 + 32 * 32); + } else if (id.x < (128 * 128 + 64 * 64 + 32 * 32 + 16 * 16 + 8 * 8)) { + level = 4; + id.x -= (128 * 128 + 64 * 64 + 32 * 32 + 16 * 16); + } else if (id.x < (128 * 128 + 64 * 64 + 32 * 32 + 16 * 16 + 8 * 8 + 4 * 4)) { + level = 5; + id.x -= (128 * 128 + 64 * 64 + 32 * 32 + 16 * 16 + 8 * 8); + } else if (id.x < (128 * 128 + 64 * 64 + 32 * 32 + 16 * 16 + 8 * 8 + 4 * 4 + 2 * 2)) { + level = 6; + id.x -= (128 * 128 + 64 * 64 + 32 * 32 + 16 * 16 + 8 * 8 + 4 * 4); + } else { + return; + } + int res = BASE_RESOLUTION >> level; +#else // Using Texture Arrays so all levels are the same resolution + int res = BASE_RESOLUTION; + int level = int(id.x / (BASE_RESOLUTION * BASE_RESOLUTION)); + id.x -= level * BASE_RESOLUTION * BASE_RESOLUTION; +#endif + + // determine dir / pos for the texel + vec3 dir, adir, frameZ; + { + id.z = id.y; + id.y = id.x / res; + id.x -= id.y * res; + + vec2 uv; + uv.x = (float(id.x) * 2.0 + 1.0) / float(res) - 1.0; + uv.y = -(float(id.y) * 2.0 + 1.0) / float(res) + 1.0; + + get_dir(dir, uv, id.z); + frameZ = normalize(dir); + + adir = abs(dir); + } + + // GGX gather colors + vec4 color = vec4(0.0); + for (int axis = 0; axis < 3; axis++) { + const int otherAxis0 = 1 - (axis & 1) - (axis >> 1); + const int otherAxis1 = 2 - (axis >> 1); + + float frameweight = (max(adir[otherAxis0], adir[otherAxis1]) - .75) / .25; + if (frameweight > 0.0) { + // determine frame + vec3 UpVector; + switch (axis) { + case 0: + UpVector = vec3(1, 0, 0); + break; + case 1: + UpVector = vec3(0, 1, 0); + break; + default: + UpVector = vec3(0, 0, 1); + break; + } + + vec3 frameX = normalize(cross(UpVector, frameZ)); + vec3 frameY = cross(frameZ, frameX); + + // calculate parametrization for polynomial + float Nx = dir[otherAxis0]; + float Ny = dir[otherAxis1]; + float Nz = adir[axis]; + + float NmaxXY = max(abs(Ny), abs(Nx)); + Nx /= NmaxXY; + Ny /= NmaxXY; + + float theta; + if (Ny < Nx) { + if (Ny <= -0.999) + theta = Nx; + else + theta = Ny; + } else { + if (Ny >= 0.999) + theta = -Nx; + else + theta = -Ny; + } + + float phi; + if (Nz <= -0.999) + phi = -NmaxXY; + else if (Nz >= 0.999) + phi = NmaxXY; + else + phi = Nz; + + float theta2 = theta * theta; + float phi2 = phi * phi; + + // sample + for (int iSuperTap = 0; iSuperTap < NUM_TAPS / 4; iSuperTap++) { + const int index = (NUM_TAPS / 4) * axis + iSuperTap; + +#ifdef USE_HIGH_QUALITY + vec4 coeffsDir0[3]; + vec4 coeffsDir1[3]; + vec4 coeffsDir2[3]; + vec4 coeffsLevel[3]; + vec4 coeffsWeight[3]; + + for (int iCoeff = 0; iCoeff < 3; iCoeff++) { + coeffsDir0[iCoeff] = data.coeffs[level][0][iCoeff][index]; + coeffsDir1[iCoeff] = data.coeffs[level][1][iCoeff][index]; + coeffsDir2[iCoeff] = data.coeffs[level][2][iCoeff][index]; + coeffsLevel[iCoeff] = data.coeffs[level][3][iCoeff][index]; + coeffsWeight[iCoeff] = data.coeffs[level][4][iCoeff][index]; + } + + for (int iSubTap = 0; iSubTap < 4; iSubTap++) { + // determine sample attributes (dir, weight, level) + vec3 sample_dir = frameX * (coeffsDir0[0][iSubTap] + coeffsDir0[1][iSubTap] * theta2 + coeffsDir0[2][iSubTap] * phi2) + frameY * (coeffsDir1[0][iSubTap] + coeffsDir1[1][iSubTap] * theta2 + coeffsDir1[2][iSubTap] * phi2) + frameZ * (coeffsDir2[0][iSubTap] + coeffsDir2[1][iSubTap] * theta2 + coeffsDir2[2][iSubTap] * phi2); + + float sample_level = coeffsLevel[0][iSubTap] + coeffsLevel[1][iSubTap] * theta2 + coeffsLevel[2][iSubTap] * phi2; + + float sample_weight = coeffsWeight[0][iSubTap] + coeffsWeight[1][iSubTap] * theta2 + coeffsWeight[2][iSubTap] * phi2; +#else + vec4 coeffsDir0 = data.coeffs[level][0][index]; + vec4 coeffsDir1 = data.coeffs[level][1][index]; + vec4 coeffsDir2 = data.coeffs[level][2][index]; + vec4 coeffsLevel = data.coeffs[level][3][index]; + vec4 coeffsWeight = data.coeffs[level][4][index]; + + for (int iSubTap = 0; iSubTap < 4; iSubTap++) { + // determine sample attributes (dir, weight, level) + vec3 sample_dir = frameX * coeffsDir0[iSubTap] + frameY * coeffsDir1[iSubTap] + frameZ * coeffsDir2[iSubTap]; + + float sample_level = coeffsLevel[iSubTap]; + + float sample_weight = coeffsWeight[iSubTap]; +#endif + + sample_weight *= frameweight; + + // adjust for jacobian + sample_dir /= max(abs(sample_dir[0]), max(abs(sample_dir[1]), abs(sample_dir[2]))); + sample_level += 0.75 * log2(dot(sample_dir, sample_dir)); +#ifndef USE_TEXTURE_ARRAY + sample_level += float(level) / 6.0; // Hack to increase the perceived roughness and reduce upscaling artifacts +#endif + // sample cubemap + color.xyz += textureLod(source_cubemap, normalize(sample_dir), sample_level).xyz * sample_weight; + color.w += sample_weight; + } + } + } + } + color /= color.w; + + // write color + color.xyz = max(vec3(0.0), color.xyz); + color.w = 1.0; + + switch (level) { + case 0: + imageStore(dest_cubemap0, ivec3(id), color); + break; + case 1: + imageStore(dest_cubemap1, ivec3(id), color); + break; + case 2: + imageStore(dest_cubemap2, ivec3(id), color); + break; + case 3: + imageStore(dest_cubemap3, ivec3(id), color); + break; + case 4: + imageStore(dest_cubemap4, ivec3(id), color); + break; + case 5: + imageStore(dest_cubemap5, ivec3(id), color); + break; + default: + imageStore(dest_cubemap6, ivec3(id), color); + break; + } +}
\ No newline at end of file diff --git a/servers/visual/visual_server_wrap_mt.cpp b/servers/visual/visual_server_wrap_mt.cpp index 9a5e5e896a..90d301c0cd 100644 --- a/servers/visual/visual_server_wrap_mt.cpp +++ b/servers/visual/visual_server_wrap_mt.cpp @@ -180,7 +180,6 @@ VisualServerWrapMT::VisualServerWrapMT(VisualServer *p_contained, bool p_create_ thread = NULL; draw_pending = 0; draw_thread_up = false; - alloc_mutex = Mutex::create(); pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc"); if (!p_create_thread) { @@ -193,6 +192,5 @@ VisualServerWrapMT::VisualServerWrapMT(VisualServer *p_contained, bool p_create_ VisualServerWrapMT::~VisualServerWrapMT() { memdelete(visual_server); - memdelete(alloc_mutex); //finish(); } diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index 9d5281b17a..2eaafe220b 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -57,7 +57,7 @@ class VisualServerWrapMT : public VisualServer { void thread_exit(); - Mutex *alloc_mutex; + Mutex alloc_mutex; int pool_max_size; diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp index d493c20e9a..b30d5e1dd1 100644 --- a/servers/visual_server.cpp +++ b/servers/visual_server.cpp @@ -2316,9 +2316,8 @@ VisualServer::VisualServer() { GLOBAL_DEF("rendering/quality/reflections/texture_array_reflections.mobile", false); GLOBAL_DEF("rendering/quality/reflections/ggx_samples", 1024); GLOBAL_DEF("rendering/quality/reflections/ggx_samples.mobile", 128); - GLOBAL_DEF("rendering/quality/reflections/ggx_samples_realtime", 64); - GLOBAL_DEF("rendering/quality/reflections/ggx_samples_realtime.mobile", 16); - GLOBAL_DEF("rendering/quality/reflection_atlas/reflection_size", 256); + GLOBAL_DEF("rendering/quality/reflections/fast_filter_high_quality", false); + GLOBAL_DEF("rendering/quality/reflection_atlas/reflection_size", 128); GLOBAL_DEF("rendering/quality/reflection_atlas/reflection_size.mobile", 128); GLOBAL_DEF("rendering/quality/reflection_atlas/reflection_count", 64); |