diff options
Diffstat (limited to 'modules')
150 files changed, 5195 insertions, 1271 deletions
diff --git a/modules/SCsub b/modules/SCsub index dc0420616c..5b39b18334 100644 --- a/modules/SCsub +++ b/modules/SCsub @@ -2,23 +2,32 @@ Import('env') +import modules_builders + env_modules = env.Clone() Export('env_modules') -env.modules_sources = [] +# Header with MODULE_*_ENABLED defines. +env.CommandNoCache("modules_enabled.gen.h", Value(env.module_list), modules_builders.generate_modules_enabled) -env_modules.add_source_files(env.modules_sources, "register_module_types.gen.cpp") +# libmodule_<name>.a for each active module. +for module in env.module_list: + env.modules_sources = [] + SConscript(module + "/SCsub") -for x in env.module_list: - if (x in env.disabled_modules): + # Some modules are not linked automatically but can be enabled optionally + # on iOS, so we handle those specially. + if env["platform"] == "iphone" and module in ["arkit", "camera"]: continue - env_modules.Append(CPPDEFINES=["MODULE_" + x.upper() + "_ENABLED"]) - SConscript(x + "/SCsub") - -if env['split_libmodules']: - env.split_lib("modules", env_lib = env_modules) -else: - lib = env_modules.add_library("modules", env.modules_sources) + lib = env_modules.add_library("module_%s" % module, env.modules_sources) env.Prepend(LIBS=[lib]) + +# libmodules.a with only register_module_types. +# Must be last so that all libmodule_<name>.a libraries are on the right side +# in the linker command. +env.modules_sources = [] +env_modules.add_source_files(env.modules_sources, "register_module_types.gen.cpp") +lib = env_modules.add_library("modules", env.modules_sources) +env.Prepend(LIBS=[lib]) diff --git a/modules/assimp/editor_scene_importer_assimp.cpp b/modules/assimp/editor_scene_importer_assimp.cpp index a547dabb60..2e653f4c5d 100644 --- a/modules/assimp/editor_scene_importer_assimp.cpp +++ b/modules/assimp/editor_scene_importer_assimp.cpp @@ -167,8 +167,7 @@ struct EditorSceneImporterAssetImportInterpolate { float t2 = t * t; float t3 = t2 * t; - return 0.5f * ((2.0f * p1) + (-p0 + p2) * t + (2.0f * p0 - 5.0f * p1 + 4 * p2 - p3) * t2 + - (-p0 + 3.0f * p1 - 3.0f * p2 + p3) * t3); + return 0.5f * ((2.0f * p1) + (-p0 + p2) * t + (2.0f * p0 - 5.0f * p1 + 4.0f * p2 - p3) * t2 + (-p0 + 3.0f * p1 - 3.0f * p2 + p3) * t3); } T bezier(T start, T control_1, T control_2, T end, float t) { @@ -389,7 +388,7 @@ EditorSceneImporterAssimp::_generate_scene(const String &p_path, aiScene *scene, Spatial *parent_node = parent_lookup->value(); ERR_FAIL_COND_V_MSG(parent_node == NULL, state.root, - "Parent node invalid even though lookup successful, out of ram?") + "Parent node invalid even though lookup successful, out of ram?"); if (spatial != state.root) { parent_node->add_child(spatial); @@ -995,15 +994,15 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat } aiMaterial *ai_material = state.assimp_scene->mMaterials[ai_mesh->mMaterialIndex]; - Ref<SpatialMaterial> mat; + Ref<StandardMaterial3D> mat; mat.instance(); int32_t mat_two_sided = 0; if (AI_SUCCESS == ai_material->Get(AI_MATKEY_TWOSIDED, mat_two_sided)) { if (mat_two_sided > 0) { - mat->set_cull_mode(SpatialMaterial::CULL_DISABLED); + mat->set_cull_mode(StandardMaterial3D::CULL_DISABLED); } else { - mat->set_cull_mode(SpatialMaterial::CULL_BACK); + mat->set_cull_mode(StandardMaterial3D::CULL_BACK); } } @@ -1015,7 +1014,7 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat // Culling handling for meshes // cull all back faces - mat->set_cull_mode(SpatialMaterial::CULL_DISABLED); + mat->set_cull_mode(StandardMaterial3D::CULL_DISABLED); // Now process materials aiTextureType base_color = aiTextureType_BASE_COLOR; @@ -1028,13 +1027,11 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat // anything transparent must be culled if (image_data.raw_image->detect_alpha() != Image::ALPHA_NONE) { - mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); - mat->set_depth_draw_mode(SpatialMaterial::DepthDrawMode::DEPTH_DRAW_ALPHA_OPAQUE_PREPASS); - mat->set_cull_mode( - SpatialMaterial::CULL_DISABLED); // since you can see both sides in transparent mode + mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA_DEPTH_PRE_PASS); + mat->set_cull_mode(StandardMaterial3D::CULL_DISABLED); // since you can see both sides in transparent mode } - mat->set_texture(SpatialMaterial::TEXTURE_ALBEDO, image_data.texture); + mat->set_texture(StandardMaterial3D::TEXTURE_ALBEDO, image_data.texture); } } @@ -1048,22 +1045,18 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat // anything transparent must be culled if (image_data.raw_image->detect_alpha() != Image::ALPHA_NONE) { - mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); - mat->set_depth_draw_mode(SpatialMaterial::DepthDrawMode::DEPTH_DRAW_ALPHA_OPAQUE_PREPASS); - mat->set_cull_mode( - SpatialMaterial::CULL_DISABLED); // since you can see both sides in transparent mode + mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA_DEPTH_PRE_PASS); + mat->set_cull_mode(StandardMaterial3D::CULL_DISABLED); // since you can see both sides in transparent mode } - mat->set_texture(SpatialMaterial::TEXTURE_ALBEDO, image_data.texture); + mat->set_texture(StandardMaterial3D::TEXTURE_ALBEDO, image_data.texture); } aiColor4D clr_diffuse; if (AI_SUCCESS == ai_material->Get(AI_MATKEY_COLOR_DIFFUSE, clr_diffuse)) { if (Math::is_equal_approx(clr_diffuse.a, 1.0f) == false) { - mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); - mat->set_depth_draw_mode(SpatialMaterial::DepthDrawMode::DEPTH_DRAW_ALPHA_OPAQUE_PREPASS); - mat->set_cull_mode( - SpatialMaterial::CULL_DISABLED); // since you can see both sides in transparent mode + mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA_DEPTH_PRE_PASS); + mat->set_cull_mode(StandardMaterial3D::CULL_DISABLED); // since you can see both sides in transparent mode } mat->set_albedo(Color(clr_diffuse.r, clr_diffuse.g, clr_diffuse.b, clr_diffuse.a)); } @@ -1078,14 +1071,14 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat // Process texture normal map if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_normal, filename, path, image_data)) { AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture); - mat->set_feature(SpatialMaterial::Feature::FEATURE_NORMAL_MAPPING, true); - mat->set_texture(SpatialMaterial::TEXTURE_NORMAL, image_data.texture); + mat->set_feature(StandardMaterial3D::Feature::FEATURE_NORMAL_MAPPING, true); + mat->set_texture(StandardMaterial3D::TEXTURE_NORMAL, image_data.texture); } else { aiString texture_path; if (AI_SUCCESS == ai_material->Get(AI_MATKEY_FBX_NORMAL_TEXTURE, AI_PROPERTIES, texture_path)) { if (AssimpUtils::CreateAssimpTexture(state, texture_path, filename, path, image_data)) { - mat->set_feature(SpatialMaterial::Feature::FEATURE_NORMAL_MAPPING, true); - mat->set_texture(SpatialMaterial::TEXTURE_NORMAL, image_data.texture); + mat->set_feature(StandardMaterial3D::Feature::FEATURE_NORMAL_MAPPING, true); + mat->set_texture(StandardMaterial3D::TEXTURE_NORMAL, image_data.texture); } } } @@ -1100,8 +1093,8 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat // Process texture normal map if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_normal_camera, filename, path, image_data)) { AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture); - mat->set_feature(SpatialMaterial::Feature::FEATURE_NORMAL_MAPPING, true); - mat->set_texture(SpatialMaterial::TEXTURE_NORMAL, image_data.texture); + mat->set_feature(StandardMaterial3D::Feature::FEATURE_NORMAL_MAPPING, true); + mat->set_texture(StandardMaterial3D::TEXTURE_NORMAL, image_data.texture); } } @@ -1114,8 +1107,8 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat // Process texture normal map if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_emission_color, filename, path, image_data)) { AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture); - mat->set_feature(SpatialMaterial::Feature::FEATURE_NORMAL_MAPPING, true); - mat->set_texture(SpatialMaterial::TEXTURE_NORMAL, image_data.texture); + mat->set_feature(StandardMaterial3D::Feature::FEATURE_NORMAL_MAPPING, true); + mat->set_texture(StandardMaterial3D::TEXTURE_NORMAL, image_data.texture); } } @@ -1128,7 +1121,7 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat // Process texture normal map if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_metalness, filename, path, image_data)) { AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture); - mat->set_texture(SpatialMaterial::TEXTURE_METALLIC, image_data.texture); + mat->set_texture(StandardMaterial3D::TEXTURE_METALLIC, image_data.texture); } } @@ -1141,7 +1134,7 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat // Process texture normal map if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_roughness, filename, path, image_data)) { AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture); - mat->set_texture(SpatialMaterial::TEXTURE_ROUGHNESS, image_data.texture); + mat->set_texture(StandardMaterial3D::TEXTURE_ROUGHNESS, image_data.texture); } } @@ -1154,16 +1147,16 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_emissive, filename, path, image_data)) { AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture); - mat->set_feature(SpatialMaterial::FEATURE_EMISSION, true); - mat->set_texture(SpatialMaterial::TEXTURE_EMISSION, image_data.texture); + mat->set_feature(StandardMaterial3D::FEATURE_EMISSION, true); + mat->set_texture(StandardMaterial3D::TEXTURE_EMISSION, image_data.texture); } else { // Process emission textures aiString texture_emissive_path; if (AI_SUCCESS == ai_material->Get(AI_MATKEY_FBX_MAYA_EMISSION_TEXTURE, AI_PROPERTIES, texture_emissive_path)) { if (AssimpUtils::CreateAssimpTexture(state, texture_emissive_path, filename, path, image_data)) { - mat->set_feature(SpatialMaterial::FEATURE_EMISSION, true); - mat->set_texture(SpatialMaterial::TEXTURE_EMISSION, image_data.texture); + mat->set_feature(StandardMaterial3D::FEATURE_EMISSION, true); + mat->set_texture(StandardMaterial3D::TEXTURE_EMISSION, image_data.texture); } } else { float pbr_emission = 0.0f; @@ -1183,7 +1176,7 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat // Process texture normal map if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_specular, filename, path, image_data)) { AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture); - mat->set_texture(SpatialMaterial::TEXTURE_METALLIC, image_data.texture); + mat->set_texture(StandardMaterial3D::TEXTURE_METALLIC, image_data.texture); } } @@ -1196,8 +1189,8 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat // Process texture normal map if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_ao_map, filename, path, image_data)) { AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture); - mat->set_feature(SpatialMaterial::FEATURE_AMBIENT_OCCLUSION, true); - mat->set_texture(SpatialMaterial::TEXTURE_AMBIENT_OCCLUSION, image_data.texture); + mat->set_feature(StandardMaterial3D::FEATURE_AMBIENT_OCCLUSION, true); + mat->set_texture(StandardMaterial3D::TEXTURE_AMBIENT_OCCLUSION, image_data.texture); } } diff --git a/modules/assimp/import_utils.h b/modules/assimp/import_utils.h index c522b01727..d037efce21 100644 --- a/modules/assimp/import_utils.h +++ b/modules/assimp/import_utils.h @@ -189,7 +189,7 @@ public: } /** - * Converts aiMatrix4x4 to godot Transform + * Converts aiMatrix4x4 to godot Transform */ static const Transform assimp_matrix_transform(const aiMatrix4x4 p_matrix) { aiMatrix4x4 matrix = p_matrix; @@ -320,17 +320,20 @@ public: static void set_texture_mapping_mode(aiTextureMapMode *map_mode, Ref<ImageTexture> texture) { ERR_FAIL_COND(texture.is_null()); ERR_FAIL_COND(map_mode == NULL); + // FIXME: Commented out during Vulkan port. + /* aiTextureMapMode tex_mode = map_mode[0]; - int32_t flags = Texture::FLAGS_DEFAULT; + int32_t flags = Texture2D::FLAGS_DEFAULT; if (tex_mode == aiTextureMapMode_Wrap) { //Default } else if (tex_mode == aiTextureMapMode_Clamp) { - flags = flags & ~Texture::FLAG_REPEAT; + flags = flags & ~Texture2D::FLAG_REPEAT; } else if (tex_mode == aiTextureMapMode_Mirror) { - flags = flags | Texture::FLAG_MIRRORED_REPEAT; + flags = flags | Texture2D::FLAG_MIRRORED_REPEAT; } texture->set_flags(flags); + */ } /** @@ -391,7 +394,7 @@ public: } return Ref<Image>(); } else { - Ref<Texture> texture = ResourceLoader::load(p_path); + Ref<Texture2D> texture = ResourceLoader::load(p_path); ERR_FAIL_COND_V(texture.is_null(), Ref<Image>()); Ref<Image> image = texture->get_data(); ERR_FAIL_COND_V(image.is_null(), Ref<Image>()); @@ -418,7 +421,8 @@ public: if (image_state.raw_image.is_valid()) { image_state.texture.instance(); image_state.texture->create_from_image(image_state.raw_image); - image_state.texture->set_storage(ImageTexture::STORAGE_COMPRESS_LOSSY); + // FIXME: Commented out during Vulkan port. + //image_state.texture->set_storage(ImageTexture::STORAGE_COMPRESS_LOSSY); return true; } } diff --git a/modules/basis_universal/SCsub b/modules/basis_universal/SCsub new file mode 100644 index 0000000000..d7342358d7 --- /dev/null +++ b/modules/basis_universal/SCsub @@ -0,0 +1,47 @@ +#!/usr/bin/env python + +Import('env') +Import('env_modules') + +env_basisu = env_modules.Clone() + +# Thirdparty source files +# Not unbundled so far since not widespread as shared library +thirdparty_dir = "#thirdparty/basis_universal/" +tool_sources = [ + "basisu_astc_decomp.cpp", + "basisu_backend.cpp", + "basisu_basis_file.cpp", + "basisu_comp.cpp", + "basisu_enc.cpp", + "basisu_etc.cpp", + "basisu_frontend.cpp", + "basisu_global_selector_palette_helpers.cpp", + "basisu_gpu_texture.cpp", + "basisu_pvrtc1_4.cpp", + "basisu_resample_filters.cpp", + "basisu_resampler.cpp", + "basisu_ssim.cpp", + "basisu_tool.cpp", + "lodepng.cpp", +] +tool_sources = [thirdparty_dir + file for file in tool_sources] +transcoder_sources = [thirdparty_dir + "transcoder/basisu_transcoder.cpp"] + +# Treat Basis headers as system headers to avoid raising warnings. Not supported on MSVC. +if not env.msvc: + env_basisu.Append(CPPFLAGS=['-isystem', Dir(thirdparty_dir).path, '-isystem', Dir(thirdparty_dir + "transcoder").path]) +else: + env_basisu.Prepend(CPPPATH=[thirdparty_dir, thirdparty_dir + "transcoder"]) + +if env['target'] == "debug": + env_basisu.Append(CPPFLAGS=["-DBASISU_DEVEL_MESSAGES=1", "-DBASISD_ENABLE_DEBUG_FLAGS=1"]) + +env_thirdparty = env_basisu.Clone() +env_thirdparty.disable_warnings() +if env['tools']: + env_thirdparty.add_source_files(env.modules_sources, tool_sources) +env_thirdparty.add_source_files(env.modules_sources, transcoder_sources) + +# Godot source files +env_basisu.add_source_files(env.modules_sources, "*.cpp") diff --git a/modules/recast/config.py b/modules/basis_universal/config.py index 098f1eafa9..1c8cd12a2d 100644 --- a/modules/recast/config.py +++ b/modules/basis_universal/config.py @@ -1,5 +1,5 @@ def can_build(env, platform): - return env['tools'] + return True def configure(env): pass diff --git a/modules/basis_universal/register_types.cpp b/modules/basis_universal/register_types.cpp new file mode 100644 index 0000000000..f5ae424b56 --- /dev/null +++ b/modules/basis_universal/register_types.cpp @@ -0,0 +1,292 @@ +/*************************************************************************/ +/* register_types.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 "register_types.h" + +#include "core/os/os.h" +#include "servers/visual_server.h" +#include "texture_basisu.h" + +#ifdef TOOLS_ENABLED +#include <basisu_comp.h> +#endif + +#include <transcoder/basisu_transcoder.h> + +enum BasisDecompressFormat { + BASIS_DECOMPRESS_RG, + BASIS_DECOMPRESS_RGB, + BASIS_DECOMPRESS_RGBA, + BASIS_DECOMPRESS_RG_AS_RA +}; + +//workaround for lack of ETC2 RG +#define USE_RG_AS_RGBA + +basist::etc1_global_selector_codebook *sel_codebook = nullptr; + +static PoolVector<uint8_t> basis_universal_packer(const Ref<Image> &p_image, Image::UsedChannels p_channels) { + + PoolVector<uint8_t> budata; + +#ifdef TOOLS_ENABLED + + { + Ref<Image> image = p_image->duplicate(); + + // unfortunately, basis universal does not support compressing supplied mipmaps, + // so for the time being, only compressing individual images will have to do. + + if (image->has_mipmaps()) { + image->clear_mipmaps(); + } + if (image->get_format() != Image::FORMAT_RGBA8) { + image->convert(Image::FORMAT_RGBA8); + } + + basisu::image buimg(image->get_width(), image->get_height()); + + { + PoolVector<uint8_t> vec = image->get_data(); + PoolVector<uint8_t>::Read r = vec.read(); + + memcpy(buimg.get_ptr(), r.ptr(), vec.size()); + } + + //image->save_png("pepeche.png"); + + basisu::basis_compressor_params params; + params.m_max_endpoint_clusters = 512; + params.m_max_selector_clusters = 512; + params.m_multithreading = true; + //params.m_no_hybrid_sel_cb = true; //fixme, default on this causes crashes //seems fixed? + params.m_pSel_codebook = sel_codebook; + //params.m_quality_level = 0; + //params.m_disable_hierarchical_endpoint_codebooks = true; + //params.m_no_selector_rdo = true; + params.m_auto_global_sel_pal = false; + + basisu::job_pool jpool(OS::get_singleton()->get_processor_count()); + params.m_pJob_pool = &jpool; + + params.m_mip_gen = false; //sorry, please some day support provided mipmaps. + params.m_source_images.push_back(buimg); + + BasisDecompressFormat decompress_format; + params.m_check_for_alpha = false; + + switch (p_channels) { + case Image::USED_CHANNELS_L: { + decompress_format = BASIS_DECOMPRESS_RGB; + } break; + case Image::USED_CHANNELS_LA: { + params.m_force_alpha = true; + decompress_format = BASIS_DECOMPRESS_RGBA; + } break; + case Image::USED_CHANNELS_R: { + decompress_format = BASIS_DECOMPRESS_RGB; + } break; + case Image::USED_CHANNELS_RG: { +#ifdef USE_RG_AS_RGBA + image->convert_rg_to_ra_rgba8(); + decompress_format = BASIS_DECOMPRESS_RG_AS_RA; + +#else + + params.m_seperate_rg_to_color_alpha = true; + decompress_format = BASIS_DECOMPRESS_RG; + +#endif + + } break; + case Image::USED_CHANNELS_RGB: { + decompress_format = BASIS_DECOMPRESS_RGB; + } break; + case Image::USED_CHANNELS_RGBA: { + params.m_force_alpha = true; + decompress_format = BASIS_DECOMPRESS_RGBA; + } break; + } + + basisu::basis_compressor c; + c.init(params); + + int buerr = c.process(); + ERR_FAIL_COND_V(buerr != basisu::basis_compressor::cECSuccess, budata); + + const basisu::uint8_vec &buvec = c.get_output_basis_file(); + budata.resize(buvec.size() + 4); + + { + PoolVector<uint8_t>::Write w = budata.write(); + uint32_t *decf = (uint32_t *)w.ptr(); + *decf = decompress_format; + memcpy(w.ptr() + 4, &buvec[0], buvec.size()); + } + } + +#endif + return budata; +} + +static Ref<Image> basis_universal_unpacker(const PoolVector<uint8_t> &p_buffer) { + Ref<Image> image; + + PoolVector<uint8_t>::Read r = p_buffer.read(); + const uint8_t *ptr = r.ptr(); + int size = p_buffer.size(); + + basist::transcoder_texture_format format; + Image::Format imgfmt; + + switch (*(uint32_t *)(ptr)) { + case BASIS_DECOMPRESS_RG: { + + if (VS::get_singleton()->has_os_feature("rgtc")) { + format = basist::transcoder_texture_format::cTFBC5; // get this from renderer + imgfmt = Image::FORMAT_RGTC_RG; + } else if (VS::get_singleton()->has_os_feature("etc2")) { + //unfortunately, basis universal does not support + // + ERR_FAIL_V(image); //unimplemented here + //format = basist::transcoder_texture_format::cTFETC1; // get this from renderer + //imgfmt = Image::FORMAT_RGTC_RG; + } else { + //decompress + } + } break; + case BASIS_DECOMPRESS_RGB: { + if (VS::get_singleton()->has_os_feature("bptc")) { + format = basist::transcoder_texture_format::cTFBC7_M6_OPAQUE_ONLY; // get this from renderer + imgfmt = Image::FORMAT_BPTC_RGBA; + } else if (VS::get_singleton()->has_os_feature("s3tc")) { + format = basist::transcoder_texture_format::cTFBC1; // get this from renderer + imgfmt = Image::FORMAT_DXT1; + } else if (VS::get_singleton()->has_os_feature("etc")) { + + format = basist::transcoder_texture_format::cTFETC1; // get this from renderer + imgfmt = Image::FORMAT_ETC; + } else { + format = basist::transcoder_texture_format::cTFBGR565; // get this from renderer + imgfmt = Image::FORMAT_RGB565; + } + + } break; + case BASIS_DECOMPRESS_RGBA: { + if (VS::get_singleton()->has_os_feature("bptc")) { + format = basist::transcoder_texture_format::cTFBC7_M5; // get this from renderer + imgfmt = Image::FORMAT_BPTC_RGBA; + } else if (VS::get_singleton()->has_os_feature("s3tc")) { + format = basist::transcoder_texture_format::cTFBC3; // get this from renderer + imgfmt = Image::FORMAT_DXT5; + } else if (VS::get_singleton()->has_os_feature("etc2")) { + format = basist::transcoder_texture_format::cTFETC2; // get this from renderer + imgfmt = Image::FORMAT_ETC2_RGBA8; + } else { + //gles2 most likely + format = basist::transcoder_texture_format::cTFRGBA4444; // get this from renderer + imgfmt = Image::FORMAT_RGBA4444; + } + } break; + case BASIS_DECOMPRESS_RG_AS_RA: { + if (VS::get_singleton()->has_os_feature("s3tc")) { + format = basist::transcoder_texture_format::cTFBC3; // get this from renderer + imgfmt = Image::FORMAT_DXT5_RA_AS_RG; + } else if (VS::get_singleton()->has_os_feature("etc2")) { + format = basist::transcoder_texture_format::cTFETC2; // get this from renderer + imgfmt = Image::FORMAT_ETC2_RGBA8; + } else { + //gles2 most likely, bad for normalmaps, nothing to do about this. + format = basist::transcoder_texture_format::cTFRGBA32; + imgfmt = Image::FORMAT_RGBA8; + } + } break; + } + + ptr += 4; + size -= 4; + + basist::basisu_transcoder tr(NULL); + + ERR_FAIL_COND_V(!tr.validate_header(ptr, size), image); + + basist::basisu_image_info info; + tr.get_image_info(ptr, size, info, 0); + + int block_size = basist::basis_get_bytes_per_block(format); + PoolVector<uint8_t> gpudata; + gpudata.resize(info.m_total_blocks * block_size); + + { + PoolVector<uint8_t>::Write w = gpudata.write(); + uint8_t *dst = w.ptr(); + for (int i = 0; i < gpudata.size(); i++) + dst[i] = 0x00; + + int ofs = 0; + tr.start_transcoding(ptr, size); + for (uint32_t i = 0; i < info.m_total_levels; i++) { + + basist::basisu_image_level_info level; + tr.get_image_level_info(ptr, size, level, 0, i); + + bool ret = tr.transcode_image_level(ptr, size, 0, i, dst + ofs, level.m_total_blocks - i, format); + if (!ret) { + printf("failed! on level %i\n", i); + break; + }; + + ofs += level.m_total_blocks * block_size; + }; + }; + + image.instance(); + image->create(info.m_width, info.m_height, info.m_total_levels > 1, imgfmt, gpudata); + + return image; +} + +void register_basis_universal_types() { +#ifdef TOOLS_ENABLED + sel_codebook = new basist::etc1_global_selector_codebook(basist::g_global_selector_cb_size, basist::g_global_selector_cb); + Image::basis_universal_packer = basis_universal_packer; +#endif + Image::basis_universal_unpacker = basis_universal_unpacker; + //ClassDB::register_class<TextureBasisU>(); +} + +void unregister_basis_universal_types() { + +#ifdef TOOLS_ENABLED + delete sel_codebook; +#endif + Image::basis_universal_packer = NULL; + Image::basis_universal_unpacker = NULL; +} diff --git a/modules/recast/register_types.h b/modules/basis_universal/register_types.h index d16ba37f5e..977374fbfc 100644 --- a/modules/recast/register_types.h +++ b/modules/basis_universal/register_types.h @@ -28,5 +28,5 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -void register_recast_types(); -void unregister_recast_types(); +void register_basis_universal_types(); +void unregister_basis_universal_types(); diff --git a/modules/basis_universal/texture_basisu.cpp b/modules/basis_universal/texture_basisu.cpp new file mode 100644 index 0000000000..3b3805157b --- /dev/null +++ b/modules/basis_universal/texture_basisu.cpp @@ -0,0 +1,233 @@ +/*************************************************************************/ +/* texture_basisu.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 "texture_basisu.h" +#if 0 +#include "core/os/os.h" + +#ifdef TOOLS_ENABLED +#include <basisu_comp.h> +#endif + +#include <transcoder/basisu_transcoder.h> + +void TextureBasisU::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_basisu_data", "data"), &TextureBasisU::set_basisu_data); + ClassDB::bind_method(D_METHOD("get_basisu_data"), &TextureBasisU::get_data); + ClassDB::bind_method(D_METHOD("import"), &TextureBasisU::import); + + ADD_PROPERTY(PropertyInfo(Variant::POOL_BYTE_ARRAY, "basisu_data"), "set_basisu_data", "get_basisu_data"); + +}; + +int TextureBasisU::get_width() const { + + return tex_size.x; +}; + +int TextureBasisU::get_height() const { + + return tex_size.y; +}; + +RID TextureBasisU::get_rid() const { + + return texture; +}; + + +bool TextureBasisU::has_alpha() const { + + return false; +}; + +void TextureBasisU::set_flags(uint32_t p_flags) { + + flags = p_flags; + VisualServer::get_singleton()->texture_set_flags(texture, p_flags); +}; + +uint32_t TextureBasisU::get_flags() const { + + return flags; +}; + + +void TextureBasisU::set_basisu_data(const PoolVector<uint8_t>& p_data) { + +#ifdef TOOLS_ENABLED + data = p_data; +#endif + + PoolVector<uint8_t>::Read r = p_data.read(); + const void* ptr = r.ptr(); + int size = p_data.size(); + + basist::transcoder_texture_format format; + Image::Format imgfmt; + + if (OS::get_singleton()->has_feature("s3tc")) { + + format = basist::cTFBC3; // get this from renderer + imgfmt = Image::FORMAT_DXT5; + + } else if (OS::get_singleton()->has_feature("etc2")) { + + format = basist::cTFETC2; + imgfmt = Image::FORMAT_ETC2_RGBA8; + }; + + basist::basisu_transcoder tr(NULL); + + ERR_FAIL_COND(!tr.validate_header(ptr, size)); + + basist::basisu_image_info info; + tr.get_image_info(ptr, size, info, 0); + tex_size = Size2(info.m_width, info.m_height); + + int block_size = basist::basis_get_bytes_per_block(format); + PoolVector<uint8_t> gpudata; + gpudata.resize(info.m_total_blocks * block_size); + + { + PoolVector<uint8_t>::Write w = gpudata.write(); + uint8_t* dst = w.ptr(); + for (int i=0; i<gpudata.size(); i++) + dst[i] = 0x00; + + int ofs = 0; + tr.start_transcoding(ptr, size); + for (int i=0; i<info.m_total_levels; i++) { + + basist::basisu_image_level_info level; + tr.get_image_level_info(ptr, size, level, 0, i); + + bool ret = tr.transcode_image_level(ptr, size, 0, i, dst + ofs, level.m_total_blocks - i, format); + if (!ret) { + printf("failed! on level %i\n", i); + break; + }; + + ofs += level.m_total_blocks * block_size; + }; + }; + + Ref<Image> img; + img.instance(); + img->create(info.m_width, info.m_height, info.m_total_levels > 1, imgfmt, gpudata); + + VisualServer::get_singleton()->texture_allocate(texture, tex_size.x, tex_size.y, 0, img->get_format(), VS::TEXTURE_TYPE_2D, flags); + VisualServer::get_singleton()->texture_set_data(texture, img); +}; + +Error TextureBasisU::import(const Ref<Image>& p_img) { + +#ifdef TOOLS_ENABLED + + PoolVector<uint8_t> budata; + + { + Image::Format format = p_img->get_format(); + if (format != Image::FORMAT_RGB8 && format != Image::FORMAT_RGBA8) { + ERR_FAIL_V(ERR_INVALID_PARAMETER); + return ERR_INVALID_PARAMETER; + }; + + Ref<Image> copy = p_img->duplicate(); + if (format == Image::FORMAT_RGB8) + copy->convert(Image::FORMAT_RGBA8); + + basisu::image buimg(p_img->get_width(), p_img->get_height()); + int size = p_img->get_width() * p_img->get_height() * 4; + + PoolVector<uint8_t> vec = copy->get_data(); + { + PoolVector<uint8_t>::Read r = vec.read(); + memcpy(buimg.get_ptr(), r.ptr(), size); + }; + + basisu::basis_compressor_params params; + params.m_max_endpoint_clusters = 512; + params.m_max_selector_clusters = 512; + params.m_multithreading = true; + + basisu::job_pool jpool(1); + params.m_pJob_pool = &jpool; + + params.m_mip_gen = p_img->get_mipmap_count() > 0; + params.m_source_images.push_back(buimg); + + basisu::basis_compressor c; + c.init(params); + + int buerr = c.process(); + if (buerr != basisu::basis_compressor::cECSuccess) { + ERR_FAIL_V(ERR_INVALID_PARAMETER); + return ERR_INVALID_PARAMETER; + }; + + const basisu::uint8_vec& buvec = c.get_output_basis_file(); + budata.resize(buvec.size()); + + { + PoolVector<uint8_t>::Write w = budata.write(); + memcpy(w.ptr(), &buvec[0], budata.size()); + }; + }; + + set_basisu_data(budata); + + return OK; +#else + + return ERR_UNAVAILABLE; +#endif +}; + + +PoolVector<uint8_t> TextureBasisU::get_basisu_data() const { + + return data; +}; + +TextureBasisU::TextureBasisU() { + + flags = FLAGS_DEFAULT; + texture = VisualServer::get_singleton()->texture_create(); +}; + + +TextureBasisU::~TextureBasisU() { + + VisualServer::get_singleton()->free(texture); +}; + +#endif diff --git a/modules/basis_universal/texture_basisu.h b/modules/basis_universal/texture_basisu.h new file mode 100644 index 0000000000..8474a63258 --- /dev/null +++ b/modules/basis_universal/texture_basisu.h @@ -0,0 +1,77 @@ +/*************************************************************************/ +/* texture_basisu.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. */ +/*************************************************************************/ + +#include "scene/resources/texture.h" + +#ifdef TOOLS_ENABLED +#include <basisu_comp.h> +#endif + +#include <transcoder/basisu_transcoder.h> + +#if 0 +class TextureBasisU : public Texture { + + GDCLASS(TextureBasisU, Texture); + RES_BASE_EXTENSION("butex"); + + RID texture; + Size2 tex_size; + + uint32_t flags; + + PoolVector<uint8_t> data; + + static void _bind_methods(); + +public: + + virtual int get_width() const; + virtual int get_height() const; + virtual RID get_rid() const; + virtual bool has_alpha() const; + + virtual void set_flags(uint32_t p_flags); + virtual uint32_t get_flags() const; + + + Error import(const Ref<Image> &p_img); + + void set_basisu_data(const PoolVector<uint8_t>& p_data); + + PoolVector<uint8_t> get_basisu_data() const; + String get_img_path() const; + + TextureBasisU(); + ~TextureBasisU(); + +}; + +#endif diff --git a/modules/bullet/area_bullet.cpp b/modules/bullet/area_bullet.cpp index 79ada54f0f..7806145390 100644 --- a/modules/bullet/area_bullet.cpp +++ b/modules/bullet/area_bullet.cpp @@ -107,7 +107,7 @@ void AreaBullet::call_event(CollisionObjectBullet *p_otherObject, PhysicsServer: Object *areaGodoObject = ObjectDB::get_instance(event.event_callback_id); if (!areaGodoObject) { - event.event_callback_id = 0; + event.event_callback_id = ObjectID(); return; } @@ -167,7 +167,7 @@ bool AreaBullet::is_monitoring() const { } void AreaBullet::main_shape_changed() { - CRASH_COND(!get_main_shape()) + CRASH_COND(!get_main_shape()); btGhost->setCollisionShape(get_main_shape()); } @@ -245,7 +245,7 @@ void AreaBullet::set_param(PhysicsServer::AreaParameter p_param, const Variant & set_spOv_gravityPointAttenuation(p_value); break; default: - WARN_PRINTS("Area doesn't support this parameter in the Bullet backend: " + itos(p_param)); + WARN_PRINT("Area doesn't support this parameter in the Bullet backend: " + itos(p_param)); } } @@ -268,7 +268,7 @@ Variant AreaBullet::get_param(PhysicsServer::AreaParameter p_param) const { case PhysicsServer::AREA_PARAM_GRAVITY_POINT_ATTENUATION: return spOv_gravityPointAttenuation; default: - WARN_PRINTS("Area doesn't support this parameter in the Bullet backend: " + itos(p_param)); + WARN_PRINT("Area doesn't support this parameter in the Bullet backend: " + itos(p_param)); return Variant(); } } @@ -279,7 +279,7 @@ void AreaBullet::set_event_callback(Type p_callbackObjectType, ObjectID p_id, co ev.event_callback_method = p_method; /// Set if monitoring - if (eventsCallbacks[0].event_callback_id || eventsCallbacks[1].event_callback_id) { + if (eventsCallbacks[0].event_callback_id.is_valid() || eventsCallbacks[1].event_callback_id.is_valid()) { set_godot_object_flags(get_godot_object_flags() | GOF_IS_MONITORING_AREA); } else { set_godot_object_flags(get_godot_object_flags() & (~GOF_IS_MONITORING_AREA)); @@ -287,7 +287,7 @@ void AreaBullet::set_event_callback(Type p_callbackObjectType, ObjectID p_id, co } bool AreaBullet::has_event_callback(Type p_callbackObjectType) { - return eventsCallbacks[static_cast<int>(p_callbackObjectType)].event_callback_id; + return eventsCallbacks[static_cast<int>(p_callbackObjectType)].event_callback_id.is_valid(); } void AreaBullet::on_enter_area(AreaBullet *p_area) { diff --git a/modules/bullet/area_bullet.h b/modules/bullet/area_bullet.h index f770c63bcc..18888c6725 100644 --- a/modules/bullet/area_bullet.h +++ b/modules/bullet/area_bullet.h @@ -50,8 +50,7 @@ public: ObjectID event_callback_id; StringName event_callback_method; - InOutEventCallback() : - event_callback_id(0) {} + InOutEventCallback() {} }; enum OverlapState { diff --git a/modules/bullet/bullet_physics_server.cpp b/modules/bullet/bullet_physics_server.cpp index 6662e130c8..89868babc6 100644 --- a/modules/bullet/bullet_physics_server.cpp +++ b/modules/bullet/bullet_physics_server.cpp @@ -57,10 +57,10 @@ // <--------------- Joint creation asserts /// Assert the body is assigned to a space -#define JointAssertSpace(body, bIndex, ret) \ - if (!body->get_space()) { \ - ERR_PRINTS("Before create a joint the Body" + String(bIndex) + " must be added to a space!"); \ - return ret; \ +#define JointAssertSpace(body, bIndex, ret) \ + if (!body->get_space()) { \ + ERR_PRINT("Before create a joint the Body" + String(bIndex) + " must be added to a space!"); \ + return ret; \ } /// Assert the two bodies of joint are in the same space @@ -134,7 +134,7 @@ RID BulletPhysicsServer::shape_create(ShapeType p_shape) { } void BulletPhysicsServer::shape_set_data(RID p_shape, const Variant &p_data) { - ShapeBullet *shape = shape_owner.get(p_shape); + ShapeBullet *shape = shape_owner.getornull(p_shape); ERR_FAIL_COND(!shape); shape->set_data(p_data); } @@ -144,25 +144,25 @@ void BulletPhysicsServer::shape_set_custom_solver_bias(RID p_shape, real_t p_bia } PhysicsServer::ShapeType BulletPhysicsServer::shape_get_type(RID p_shape) const { - ShapeBullet *shape = shape_owner.get(p_shape); + ShapeBullet *shape = shape_owner.getornull(p_shape); ERR_FAIL_COND_V(!shape, PhysicsServer::SHAPE_CUSTOM); return shape->get_type(); } Variant BulletPhysicsServer::shape_get_data(RID p_shape) const { - ShapeBullet *shape = shape_owner.get(p_shape); + ShapeBullet *shape = shape_owner.getornull(p_shape); ERR_FAIL_COND_V(!shape, Variant()); return shape->get_data(); } void BulletPhysicsServer::shape_set_margin(RID p_shape, real_t p_margin) { - ShapeBullet *shape = shape_owner.get(p_shape); + ShapeBullet *shape = shape_owner.getornull(p_shape); ERR_FAIL_COND(!shape); shape->set_margin(p_margin); } real_t BulletPhysicsServer::shape_get_margin(RID p_shape) const { - ShapeBullet *shape = shape_owner.get(p_shape); + ShapeBullet *shape = shape_owner.getornull(p_shape); ERR_FAIL_COND_V(!shape, 0.0); return shape->get_margin(); } @@ -179,7 +179,7 @@ RID BulletPhysicsServer::space_create() { void BulletPhysicsServer::space_set_active(RID p_space, bool p_active) { - SpaceBullet *space = space_owner.get(p_space); + SpaceBullet *space = space_owner.getornull(p_space); ERR_FAIL_COND(!space); if (space_is_active(p_space) == p_active) { @@ -196,47 +196,47 @@ void BulletPhysicsServer::space_set_active(RID p_space, bool p_active) { } bool BulletPhysicsServer::space_is_active(RID p_space) const { - SpaceBullet *space = space_owner.get(p_space); + SpaceBullet *space = space_owner.getornull(p_space); ERR_FAIL_COND_V(!space, false); return -1 != active_spaces.find(space); } void BulletPhysicsServer::space_set_param(RID p_space, SpaceParameter p_param, real_t p_value) { - SpaceBullet *space = space_owner.get(p_space); + SpaceBullet *space = space_owner.getornull(p_space); ERR_FAIL_COND(!space); space->set_param(p_param, p_value); } real_t BulletPhysicsServer::space_get_param(RID p_space, SpaceParameter p_param) const { - SpaceBullet *space = space_owner.get(p_space); + SpaceBullet *space = space_owner.getornull(p_space); ERR_FAIL_COND_V(!space, 0); return space->get_param(p_param); } PhysicsDirectSpaceState *BulletPhysicsServer::space_get_direct_state(RID p_space) { - SpaceBullet *space = space_owner.get(p_space); + SpaceBullet *space = space_owner.getornull(p_space); ERR_FAIL_COND_V(!space, NULL); return space->get_direct_state(); } void BulletPhysicsServer::space_set_debug_contacts(RID p_space, int p_max_contacts) { - SpaceBullet *space = space_owner.get(p_space); + SpaceBullet *space = space_owner.getornull(p_space); ERR_FAIL_COND(!space); space->set_debug_contacts(p_max_contacts); } Vector<Vector3> BulletPhysicsServer::space_get_contacts(RID p_space) const { - SpaceBullet *space = space_owner.get(p_space); + SpaceBullet *space = space_owner.getornull(p_space); ERR_FAIL_COND_V(!space, Vector<Vector3>()); return space->get_debug_contacts(); } int BulletPhysicsServer::space_get_contact_count(RID p_space) const { - SpaceBullet *space = space_owner.get(p_space); + SpaceBullet *space = space_owner.getornull(p_space); ERR_FAIL_COND_V(!space, 0); return space->get_debug_contact_count(); @@ -250,91 +250,91 @@ RID BulletPhysicsServer::area_create() { } void BulletPhysicsServer::area_set_space(RID p_area, RID p_space) { - AreaBullet *area = area_owner.get(p_area); + AreaBullet *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); SpaceBullet *space = NULL; if (p_space.is_valid()) { - space = space_owner.get(p_space); + space = space_owner.getornull(p_space); ERR_FAIL_COND(!space); } area->set_space(space); } RID BulletPhysicsServer::area_get_space(RID p_area) const { - AreaBullet *area = area_owner.get(p_area); + AreaBullet *area = area_owner.getornull(p_area); return area->get_space()->get_self(); } void BulletPhysicsServer::area_set_space_override_mode(RID p_area, AreaSpaceOverrideMode p_mode) { - AreaBullet *area = area_owner.get(p_area); + AreaBullet *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); area->set_spOv_mode(p_mode); } PhysicsServer::AreaSpaceOverrideMode BulletPhysicsServer::area_get_space_override_mode(RID p_area) const { - AreaBullet *area = area_owner.get(p_area); + AreaBullet *area = area_owner.getornull(p_area); ERR_FAIL_COND_V(!area, PhysicsServer::AREA_SPACE_OVERRIDE_DISABLED); return area->get_spOv_mode(); } void BulletPhysicsServer::area_add_shape(RID p_area, RID p_shape, const Transform &p_transform, bool p_disabled) { - AreaBullet *area = area_owner.get(p_area); + AreaBullet *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); - ShapeBullet *shape = shape_owner.get(p_shape); + ShapeBullet *shape = shape_owner.getornull(p_shape); ERR_FAIL_COND(!shape); area->add_shape(shape, p_transform, p_disabled); } void BulletPhysicsServer::area_set_shape(RID p_area, int p_shape_idx, RID p_shape) { - AreaBullet *area = area_owner.get(p_area); + AreaBullet *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); - ShapeBullet *shape = shape_owner.get(p_shape); + ShapeBullet *shape = shape_owner.getornull(p_shape); ERR_FAIL_COND(!shape); area->set_shape(p_shape_idx, shape); } void BulletPhysicsServer::area_set_shape_transform(RID p_area, int p_shape_idx, const Transform &p_transform) { - AreaBullet *area = area_owner.get(p_area); + AreaBullet *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); area->set_shape_transform(p_shape_idx, p_transform); } int BulletPhysicsServer::area_get_shape_count(RID p_area) const { - AreaBullet *area = area_owner.get(p_area); + AreaBullet *area = area_owner.getornull(p_area); ERR_FAIL_COND_V(!area, 0); return area->get_shape_count(); } RID BulletPhysicsServer::area_get_shape(RID p_area, int p_shape_idx) const { - AreaBullet *area = area_owner.get(p_area); + AreaBullet *area = area_owner.getornull(p_area); ERR_FAIL_COND_V(!area, RID()); return area->get_shape(p_shape_idx)->get_self(); } Transform BulletPhysicsServer::area_get_shape_transform(RID p_area, int p_shape_idx) const { - AreaBullet *area = area_owner.get(p_area); + AreaBullet *area = area_owner.getornull(p_area); ERR_FAIL_COND_V(!area, Transform()); return area->get_shape_transform(p_shape_idx); } void BulletPhysicsServer::area_remove_shape(RID p_area, int p_shape_idx) { - AreaBullet *area = area_owner.get(p_area); + AreaBullet *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); return area->remove_shape_full(p_shape_idx); } void BulletPhysicsServer::area_clear_shapes(RID p_area) { - AreaBullet *area = area_owner.get(p_area); + AreaBullet *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); for (int i = area->get_shape_count(); 0 < i; --i) @@ -342,7 +342,7 @@ void BulletPhysicsServer::area_clear_shapes(RID p_area) { } void BulletPhysicsServer::area_set_shape_disabled(RID p_area, int p_shape_idx, bool p_disabled) { - AreaBullet *area = area_owner.get(p_area); + AreaBullet *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); area->set_shape_disabled(p_shape_idx, p_disabled); @@ -352,29 +352,29 @@ void BulletPhysicsServer::area_attach_object_instance_id(RID p_area, ObjectID p_ if (space_owner.owns(p_area)) { return; } - AreaBullet *area = area_owner.get(p_area); + AreaBullet *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); area->set_instance_id(p_id); } ObjectID BulletPhysicsServer::area_get_object_instance_id(RID p_area) const { if (space_owner.owns(p_area)) { - return 0; + return ObjectID(); } - AreaBullet *area = area_owner.get(p_area); + AreaBullet *area = area_owner.getornull(p_area); ERR_FAIL_COND_V(!area, ObjectID()); return area->get_instance_id(); } void BulletPhysicsServer::area_set_param(RID p_area, AreaParameter p_param, const Variant &p_value) { if (space_owner.owns(p_area)) { - SpaceBullet *space = space_owner.get(p_area); + SpaceBullet *space = space_owner.getornull(p_area); if (space) { space->set_param(p_param, p_value); } } else { - AreaBullet *area = area_owner.get(p_area); + AreaBullet *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); area->set_param(p_param, p_value); @@ -383,10 +383,10 @@ void BulletPhysicsServer::area_set_param(RID p_area, AreaParameter p_param, cons Variant BulletPhysicsServer::area_get_param(RID p_area, AreaParameter p_param) const { if (space_owner.owns(p_area)) { - SpaceBullet *space = space_owner.get(p_area); + SpaceBullet *space = space_owner.getornull(p_area); return space->get_param(p_param); } else { - AreaBullet *area = area_owner.get(p_area); + AreaBullet *area = area_owner.getornull(p_area); ERR_FAIL_COND_V(!area, Variant()); return area->get_param(p_param); @@ -394,58 +394,58 @@ Variant BulletPhysicsServer::area_get_param(RID p_area, AreaParameter p_param) c } void BulletPhysicsServer::area_set_transform(RID p_area, const Transform &p_transform) { - AreaBullet *area = area_owner.get(p_area); + AreaBullet *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); area->set_transform(p_transform); } Transform BulletPhysicsServer::area_get_transform(RID p_area) const { - AreaBullet *area = area_owner.get(p_area); + AreaBullet *area = area_owner.getornull(p_area); ERR_FAIL_COND_V(!area, Transform()); return area->get_transform(); } void BulletPhysicsServer::area_set_collision_mask(RID p_area, uint32_t p_mask) { - AreaBullet *area = area_owner.get(p_area); + AreaBullet *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); area->set_collision_mask(p_mask); } void BulletPhysicsServer::area_set_collision_layer(RID p_area, uint32_t p_layer) { - AreaBullet *area = area_owner.get(p_area); + AreaBullet *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); area->set_collision_layer(p_layer); } void BulletPhysicsServer::area_set_monitorable(RID p_area, bool p_monitorable) { - AreaBullet *area = area_owner.get(p_area); + AreaBullet *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); area->set_monitorable(p_monitorable); } void BulletPhysicsServer::area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) { - AreaBullet *area = area_owner.get(p_area); + AreaBullet *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); - area->set_event_callback(CollisionObjectBullet::TYPE_RIGID_BODY, p_receiver ? p_receiver->get_instance_id() : 0, p_method); + area->set_event_callback(CollisionObjectBullet::TYPE_RIGID_BODY, p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method); } void BulletPhysicsServer::area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) { - AreaBullet *area = area_owner.get(p_area); + AreaBullet *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); - area->set_event_callback(CollisionObjectBullet::TYPE_AREA, p_receiver ? p_receiver->get_instance_id() : 0, p_method); + area->set_event_callback(CollisionObjectBullet::TYPE_AREA, p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method); } void BulletPhysicsServer::area_set_ray_pickable(RID p_area, bool p_enable) { - AreaBullet *area = area_owner.get(p_area); + AreaBullet *area = area_owner.getornull(p_area); ERR_FAIL_COND(!area); area->set_ray_pickable(p_enable); } bool BulletPhysicsServer::area_is_ray_pickable(RID p_area) const { - AreaBullet *area = area_owner.get(p_area); + AreaBullet *area = area_owner.getornull(p_area); ERR_FAIL_COND_V(!area, false); return area->is_ray_pickable(); } @@ -461,12 +461,12 @@ RID BulletPhysicsServer::body_create(BodyMode p_mode, bool p_init_sleeping) { } void BulletPhysicsServer::body_set_space(RID p_body, RID p_space) { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND(!body); SpaceBullet *space = NULL; if (p_space.is_valid()) { - space = space_owner.get(p_space); + space = space_owner.getornull(p_space); ERR_FAIL_COND(!space); } @@ -477,7 +477,7 @@ void BulletPhysicsServer::body_set_space(RID p_body, RID p_space) { } RID BulletPhysicsServer::body_get_space(RID p_body) const { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, RID()); SpaceBullet *space = body->get_space(); @@ -487,53 +487,53 @@ RID BulletPhysicsServer::body_get_space(RID p_body) const { } void BulletPhysicsServer::body_set_mode(RID p_body, PhysicsServer::BodyMode p_mode) { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_mode(p_mode); } PhysicsServer::BodyMode BulletPhysicsServer::body_get_mode(RID p_body) const { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, BODY_MODE_STATIC); return body->get_mode(); } void BulletPhysicsServer::body_add_shape(RID p_body, RID p_shape, const Transform &p_transform, bool p_disabled) { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND(!body); - ShapeBullet *shape = shape_owner.get(p_shape); + ShapeBullet *shape = shape_owner.getornull(p_shape); ERR_FAIL_COND(!shape); body->add_shape(shape, p_transform, p_disabled); } void BulletPhysicsServer::body_set_shape(RID p_body, int p_shape_idx, RID p_shape) { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND(!body); - ShapeBullet *shape = shape_owner.get(p_shape); + ShapeBullet *shape = shape_owner.getornull(p_shape); ERR_FAIL_COND(!shape); body->set_shape(p_shape_idx, shape); } void BulletPhysicsServer::body_set_shape_transform(RID p_body, int p_shape_idx, const Transform &p_transform) { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_shape_transform(p_shape_idx, p_transform); } int BulletPhysicsServer::body_get_shape_count(RID p_body) const { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, 0); return body->get_shape_count(); } RID BulletPhysicsServer::body_get_shape(RID p_body, int p_shape_idx) const { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, RID()); ShapeBullet *shape = body->get_shape(p_shape_idx); @@ -543,83 +543,83 @@ RID BulletPhysicsServer::body_get_shape(RID p_body, int p_shape_idx) const { } Transform BulletPhysicsServer::body_get_shape_transform(RID p_body, int p_shape_idx) const { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, Transform()); return body->get_shape_transform(p_shape_idx); } void BulletPhysicsServer::body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_shape_disabled(p_shape_idx, p_disabled); } void BulletPhysicsServer::body_remove_shape(RID p_body, int p_shape_idx) { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->remove_shape_full(p_shape_idx); } void BulletPhysicsServer::body_clear_shapes(RID p_body) { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->remove_all_shapes(); } -void BulletPhysicsServer::body_attach_object_instance_id(RID p_body, uint32_t p_id) { +void BulletPhysicsServer::body_attach_object_instance_id(RID p_body, ObjectID p_id) { CollisionObjectBullet *body = get_collisin_object(p_body); ERR_FAIL_COND(!body); body->set_instance_id(p_id); } -uint32_t BulletPhysicsServer::body_get_object_instance_id(RID p_body) const { +ObjectID BulletPhysicsServer::body_get_object_instance_id(RID p_body) const { CollisionObjectBullet *body = get_collisin_object(p_body); - ERR_FAIL_COND_V(!body, 0); + ERR_FAIL_COND_V(!body, ObjectID()); return body->get_instance_id(); } void BulletPhysicsServer::body_set_enable_continuous_collision_detection(RID p_body, bool p_enable) { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_continuous_collision_detection(p_enable); } bool BulletPhysicsServer::body_is_continuous_collision_detection_enabled(RID p_body) const { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, false); return body->is_continuous_collision_detection_enabled(); } void BulletPhysicsServer::body_set_collision_layer(RID p_body, uint32_t p_layer) { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_collision_layer(p_layer); } uint32_t BulletPhysicsServer::body_get_collision_layer(RID p_body) const { - const RigidBodyBullet *body = rigid_body_owner.get(p_body); + const RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, 0); return body->get_collision_layer(); } void BulletPhysicsServer::body_set_collision_mask(RID p_body, uint32_t p_mask) { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_collision_mask(p_mask); } uint32_t BulletPhysicsServer::body_get_collision_mask(RID p_body) const { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, 0); return body->get_collision_mask(); @@ -635,21 +635,21 @@ uint32_t BulletPhysicsServer::body_get_user_flags(RID p_body) const { } void BulletPhysicsServer::body_set_param(RID p_body, BodyParameter p_param, float p_value) { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_param(p_param, p_value); } float BulletPhysicsServer::body_get_param(RID p_body, BodyParameter p_param) const { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, 0); return body->get_param(p_param); } void BulletPhysicsServer::body_set_kinematic_safe_margin(RID p_body, real_t p_margin) { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND(!body); if (body->get_kinematic_utilities()) { @@ -659,7 +659,7 @@ void BulletPhysicsServer::body_set_kinematic_safe_margin(RID p_body, real_t p_ma } real_t BulletPhysicsServer::body_get_kinematic_safe_margin(RID p_body) const { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, 0); if (body->get_kinematic_utilities()) { @@ -671,90 +671,90 @@ real_t BulletPhysicsServer::body_get_kinematic_safe_margin(RID p_body) const { } void BulletPhysicsServer::body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_state(p_state, p_variant); } Variant BulletPhysicsServer::body_get_state(RID p_body, BodyState p_state) const { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, Variant()); return body->get_state(p_state); } void BulletPhysicsServer::body_set_applied_force(RID p_body, const Vector3 &p_force) { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_applied_force(p_force); } Vector3 BulletPhysicsServer::body_get_applied_force(RID p_body) const { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, Vector3()); return body->get_applied_force(); } void BulletPhysicsServer::body_set_applied_torque(RID p_body, const Vector3 &p_torque) { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_applied_torque(p_torque); } Vector3 BulletPhysicsServer::body_get_applied_torque(RID p_body) const { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, Vector3()); return body->get_applied_torque(); } void BulletPhysicsServer::body_add_central_force(RID p_body, const Vector3 &p_force) { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->apply_central_force(p_force); } void BulletPhysicsServer::body_add_force(RID p_body, const Vector3 &p_force, const Vector3 &p_pos) { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->apply_force(p_force, p_pos); } void BulletPhysicsServer::body_add_torque(RID p_body, const Vector3 &p_torque) { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->apply_torque(p_torque); } void BulletPhysicsServer::body_apply_central_impulse(RID p_body, const Vector3 &p_impulse) { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->apply_central_impulse(p_impulse); } void BulletPhysicsServer::body_apply_impulse(RID p_body, const Vector3 &p_pos, const Vector3 &p_impulse) { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->apply_impulse(p_pos, p_impulse); } void BulletPhysicsServer::body_apply_torque_impulse(RID p_body, const Vector3 &p_impulse) { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->apply_torque_impulse(p_impulse); } void BulletPhysicsServer::body_set_axis_velocity(RID p_body, const Vector3 &p_axis_velocity) { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND(!body); Vector3 v = body->get_linear_velocity(); @@ -765,39 +765,39 @@ void BulletPhysicsServer::body_set_axis_velocity(RID p_body, const Vector3 &p_ax } void BulletPhysicsServer::body_set_axis_lock(RID p_body, BodyAxis p_axis, bool p_lock) { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_axis_lock(p_axis, p_lock); } bool BulletPhysicsServer::body_is_axis_locked(RID p_body, BodyAxis p_axis) const { - const RigidBodyBullet *body = rigid_body_owner.get(p_body); + const RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, 0); return body->is_axis_locked(p_axis); } void BulletPhysicsServer::body_add_collision_exception(RID p_body, RID p_body_b) { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND(!body); - RigidBodyBullet *other_body = rigid_body_owner.get(p_body_b); + RigidBodyBullet *other_body = rigid_body_owner.getornull(p_body_b); ERR_FAIL_COND(!other_body); body->add_collision_exception(other_body); } void BulletPhysicsServer::body_remove_collision_exception(RID p_body, RID p_body_b) { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND(!body); - RigidBodyBullet *other_body = rigid_body_owner.get(p_body_b); + RigidBodyBullet *other_body = rigid_body_owner.getornull(p_body_b); ERR_FAIL_COND(!other_body); body->remove_collision_exception(other_body); } void BulletPhysicsServer::body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND(!body); for (int i = 0; i < body->get_exceptions().size(); i++) { p_exceptions->push_back(body->get_exceptions()[i]); @@ -805,14 +805,14 @@ void BulletPhysicsServer::body_get_collision_exceptions(RID p_body, List<RID> *p } void BulletPhysicsServer::body_set_max_contacts_reported(RID p_body, int p_contacts) { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_max_collisions_detection(p_contacts); } int BulletPhysicsServer::body_get_max_contacts_reported(RID p_body) const { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, 0); return body->get_max_collisions_detection(); @@ -828,45 +828,45 @@ float BulletPhysicsServer::body_get_contacts_reported_depth_threshold(RID p_body } void BulletPhysicsServer::body_set_omit_force_integration(RID p_body, bool p_omit) { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_omit_forces_integration(p_omit); } bool BulletPhysicsServer::body_is_omitting_force_integration(RID p_body) const { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, false); return body->get_omit_forces_integration(); } void BulletPhysicsServer::body_set_force_integration_callback(RID p_body, Object *p_receiver, const StringName &p_method, const Variant &p_udata) { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND(!body); - body->set_force_integration_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(0), p_method, p_udata); + body->set_force_integration_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method, p_udata); } void BulletPhysicsServer::body_set_ray_pickable(RID p_body, bool p_enable) { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_ray_pickable(p_enable); } bool BulletPhysicsServer::body_is_ray_pickable(RID p_body) const { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, false); return body->is_ray_pickable(); } PhysicsDirectBodyState *BulletPhysicsServer::body_get_direct_state(RID p_body) { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, NULL); return BulletPhysicsDirectBodyState::get_singleton(body); } bool BulletPhysicsServer::body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result, bool p_exclude_raycast_shapes) { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, false); ERR_FAIL_COND_V(!body->get_space(), false); @@ -874,7 +874,7 @@ bool BulletPhysicsServer::body_test_motion(RID p_body, const Transform &p_from, } int BulletPhysicsServer::body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin) { - RigidBodyBullet *body = rigid_body_owner.get(p_body); + RigidBodyBullet *body = rigid_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, 0); ERR_FAIL_COND_V(!body->get_space(), 0); @@ -891,19 +891,19 @@ RID BulletPhysicsServer::soft_body_create(bool p_init_sleeping) { } void BulletPhysicsServer::soft_body_update_visual_server(RID p_body, class SoftBodyVisualServerHandler *p_visual_server_handler) { - SoftBodyBullet *body = soft_body_owner.get(p_body); + SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->update_visual_server(p_visual_server_handler); } void BulletPhysicsServer::soft_body_set_space(RID p_body, RID p_space) { - SoftBodyBullet *body = soft_body_owner.get(p_body); + SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND(!body); SpaceBullet *space = NULL; if (p_space.is_valid()) { - space = space_owner.get(p_space); + space = space_owner.getornull(p_space); ERR_FAIL_COND(!space); } @@ -914,7 +914,7 @@ void BulletPhysicsServer::soft_body_set_space(RID p_body, RID p_space) { } RID BulletPhysicsServer::soft_body_get_space(RID p_body) const { - SoftBodyBullet *body = soft_body_owner.get(p_body); + SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, RID()); SpaceBullet *space = body->get_space(); @@ -924,47 +924,47 @@ RID BulletPhysicsServer::soft_body_get_space(RID p_body) const { } void BulletPhysicsServer::soft_body_set_mesh(RID p_body, const REF &p_mesh) { - SoftBodyBullet *body = soft_body_owner.get(p_body); + SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_soft_mesh(p_mesh); } void BulletPhysicsServer::soft_body_set_collision_layer(RID p_body, uint32_t p_layer) { - SoftBodyBullet *body = soft_body_owner.get(p_body); + SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_collision_layer(p_layer); } uint32_t BulletPhysicsServer::soft_body_get_collision_layer(RID p_body) const { - const SoftBodyBullet *body = soft_body_owner.get(p_body); + const SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, 0); return body->get_collision_layer(); } void BulletPhysicsServer::soft_body_set_collision_mask(RID p_body, uint32_t p_mask) { - SoftBodyBullet *body = soft_body_owner.get(p_body); + SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_collision_mask(p_mask); } uint32_t BulletPhysicsServer::soft_body_get_collision_mask(RID p_body) const { - const SoftBodyBullet *body = soft_body_owner.get(p_body); + const SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, 0); return body->get_collision_mask(); } void BulletPhysicsServer::soft_body_add_collision_exception(RID p_body, RID p_body_b) { - SoftBodyBullet *body = soft_body_owner.get(p_body); + SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND(!body); - CollisionObjectBullet *other_body = rigid_body_owner.get(p_body_b); + CollisionObjectBullet *other_body = rigid_body_owner.getornull(p_body_b); if (!other_body) { - other_body = soft_body_owner.get(p_body_b); + other_body = soft_body_owner.getornull(p_body_b); } ERR_FAIL_COND(!other_body); @@ -972,12 +972,12 @@ void BulletPhysicsServer::soft_body_add_collision_exception(RID p_body, RID p_bo } void BulletPhysicsServer::soft_body_remove_collision_exception(RID p_body, RID p_body_b) { - SoftBodyBullet *body = soft_body_owner.get(p_body); + SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND(!body); - CollisionObjectBullet *other_body = rigid_body_owner.get(p_body_b); + CollisionObjectBullet *other_body = rigid_body_owner.getornull(p_body_b); if (!other_body) { - other_body = soft_body_owner.get(p_body_b); + other_body = soft_body_owner.getornull(p_body_b); } ERR_FAIL_COND(!other_body); @@ -985,7 +985,7 @@ void BulletPhysicsServer::soft_body_remove_collision_exception(RID p_body, RID p } void BulletPhysicsServer::soft_body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) { - SoftBodyBullet *body = soft_body_owner.get(p_body); + SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND(!body); for (int i = 0; i < body->get_exceptions().size(); i++) { p_exceptions->push_back(body->get_exceptions()[i]); @@ -1004,14 +1004,14 @@ Variant BulletPhysicsServer::soft_body_get_state(RID p_body, BodyState p_state) } void BulletPhysicsServer::soft_body_set_transform(RID p_body, const Transform &p_transform) { - SoftBodyBullet *body = soft_body_owner.get(p_body); + SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_soft_transform(p_transform); } Vector3 BulletPhysicsServer::soft_body_get_vertex_position(RID p_body, int vertex_index) const { - const SoftBodyBullet *body = soft_body_owner.get(p_body); + const SoftBodyBullet *body = soft_body_owner.getornull(p_body); Vector3 pos; ERR_FAIL_COND_V(!body, pos); @@ -1020,133 +1020,133 @@ Vector3 BulletPhysicsServer::soft_body_get_vertex_position(RID p_body, int verte } void BulletPhysicsServer::soft_body_set_ray_pickable(RID p_body, bool p_enable) { - SoftBodyBullet *body = soft_body_owner.get(p_body); + SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_ray_pickable(p_enable); } bool BulletPhysicsServer::soft_body_is_ray_pickable(RID p_body) const { - SoftBodyBullet *body = soft_body_owner.get(p_body); + SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, false); return body->is_ray_pickable(); } void BulletPhysicsServer::soft_body_set_simulation_precision(RID p_body, int p_simulation_precision) { - SoftBodyBullet *body = soft_body_owner.get(p_body); + SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_simulation_precision(p_simulation_precision); } int BulletPhysicsServer::soft_body_get_simulation_precision(RID p_body) { - SoftBodyBullet *body = soft_body_owner.get(p_body); + SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, 0.f); return body->get_simulation_precision(); } void BulletPhysicsServer::soft_body_set_total_mass(RID p_body, real_t p_total_mass) { - SoftBodyBullet *body = soft_body_owner.get(p_body); + SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_total_mass(p_total_mass); } real_t BulletPhysicsServer::soft_body_get_total_mass(RID p_body) { - SoftBodyBullet *body = soft_body_owner.get(p_body); + SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, 0.f); return body->get_total_mass(); } void BulletPhysicsServer::soft_body_set_linear_stiffness(RID p_body, real_t p_stiffness) { - SoftBodyBullet *body = soft_body_owner.get(p_body); + SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_linear_stiffness(p_stiffness); } real_t BulletPhysicsServer::soft_body_get_linear_stiffness(RID p_body) { - SoftBodyBullet *body = soft_body_owner.get(p_body); + SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, 0.f); return body->get_linear_stiffness(); } void BulletPhysicsServer::soft_body_set_areaAngular_stiffness(RID p_body, real_t p_stiffness) { - SoftBodyBullet *body = soft_body_owner.get(p_body); + SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_areaAngular_stiffness(p_stiffness); } real_t BulletPhysicsServer::soft_body_get_areaAngular_stiffness(RID p_body) { - SoftBodyBullet *body = soft_body_owner.get(p_body); + SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, 0.f); return body->get_areaAngular_stiffness(); } void BulletPhysicsServer::soft_body_set_volume_stiffness(RID p_body, real_t p_stiffness) { - SoftBodyBullet *body = soft_body_owner.get(p_body); + SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_volume_stiffness(p_stiffness); } real_t BulletPhysicsServer::soft_body_get_volume_stiffness(RID p_body) { - SoftBodyBullet *body = soft_body_owner.get(p_body); + SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, 0.f); return body->get_volume_stiffness(); } void BulletPhysicsServer::soft_body_set_pressure_coefficient(RID p_body, real_t p_pressure_coefficient) { - SoftBodyBullet *body = soft_body_owner.get(p_body); + SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_pressure_coefficient(p_pressure_coefficient); } real_t BulletPhysicsServer::soft_body_get_pressure_coefficient(RID p_body) { - SoftBodyBullet *body = soft_body_owner.get(p_body); + SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, 0.f); return body->get_pressure_coefficient(); } void BulletPhysicsServer::soft_body_set_pose_matching_coefficient(RID p_body, real_t p_pose_matching_coefficient) { - SoftBodyBullet *body = soft_body_owner.get(p_body); + SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND(!body); return body->set_pose_matching_coefficient(p_pose_matching_coefficient); } real_t BulletPhysicsServer::soft_body_get_pose_matching_coefficient(RID p_body) { - SoftBodyBullet *body = soft_body_owner.get(p_body); + SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, 0.f); return body->get_pose_matching_coefficient(); } void BulletPhysicsServer::soft_body_set_damping_coefficient(RID p_body, real_t p_damping_coefficient) { - SoftBodyBullet *body = soft_body_owner.get(p_body); + SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_damping_coefficient(p_damping_coefficient); } real_t BulletPhysicsServer::soft_body_get_damping_coefficient(RID p_body) { - SoftBodyBullet *body = soft_body_owner.get(p_body); + SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, 0.f); return body->get_damping_coefficient(); } void BulletPhysicsServer::soft_body_set_drag_coefficient(RID p_body, real_t p_drag_coefficient) { - SoftBodyBullet *body = soft_body_owner.get(p_body); + SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_drag_coefficient(p_drag_coefficient); } real_t BulletPhysicsServer::soft_body_get_drag_coefficient(RID p_body) { - SoftBodyBullet *body = soft_body_owner.get(p_body); + SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, 0.f); return body->get_drag_coefficient(); } void BulletPhysicsServer::soft_body_move_point(RID p_body, int p_point_index, const Vector3 &p_global_position) { - SoftBodyBullet *body = soft_body_owner.get(p_body); + SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_node_position(p_point_index, p_global_position); } Vector3 BulletPhysicsServer::soft_body_get_point_global_position(RID p_body, int p_point_index) { - SoftBodyBullet *body = soft_body_owner.get(p_body); + SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, Vector3(0., 0., 0.)); Vector3 pos; body->get_node_position(p_point_index, pos); @@ -1154,7 +1154,7 @@ Vector3 BulletPhysicsServer::soft_body_get_point_global_position(RID p_body, int } Vector3 BulletPhysicsServer::soft_body_get_point_offset(RID p_body, int p_point_index) const { - SoftBodyBullet *body = soft_body_owner.get(p_body); + SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, Vector3()); Vector3 res; body->get_node_offset(p_point_index, res); @@ -1162,25 +1162,25 @@ Vector3 BulletPhysicsServer::soft_body_get_point_offset(RID p_body, int p_point_ } void BulletPhysicsServer::soft_body_remove_all_pinned_points(RID p_body) { - SoftBodyBullet *body = soft_body_owner.get(p_body); + SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->reset_all_node_mass(); } void BulletPhysicsServer::soft_body_pin_point(RID p_body, int p_point_index, bool p_pin) { - SoftBodyBullet *body = soft_body_owner.get(p_body); + SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND(!body); body->set_node_mass(p_point_index, p_pin ? 0 : 1); } bool BulletPhysicsServer::soft_body_is_point_pinned(RID p_body, int p_point_index) { - SoftBodyBullet *body = soft_body_owner.get(p_body); + SoftBodyBullet *body = soft_body_owner.getornull(p_body); ERR_FAIL_COND_V(!body, 0.f); return body->get_node_mass(p_point_index); } PhysicsServer::JointType BulletPhysicsServer::joint_get_type(RID p_joint) const { - JointBullet *joint = joint_owner.get(p_joint); + JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, JOINT_PIN); return joint->get_type(); } @@ -1195,28 +1195,28 @@ int BulletPhysicsServer::joint_get_solver_priority(RID p_joint) const { } void BulletPhysicsServer::joint_disable_collisions_between_bodies(RID p_joint, const bool p_disable) { - JointBullet *joint = joint_owner.get(p_joint); + JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); joint->disable_collisions_between_bodies(p_disable); } bool BulletPhysicsServer::joint_is_disabled_collisions_between_bodies(RID p_joint) const { - JointBullet *joint(joint_owner.get(p_joint)); + JointBullet *joint(joint_owner.getornull(p_joint)); ERR_FAIL_COND_V(!joint, false); return joint->is_disabled_collisions_between_bodies(); } RID BulletPhysicsServer::joint_create_pin(RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) { - RigidBodyBullet *body_A = rigid_body_owner.get(p_body_A); + RigidBodyBullet *body_A = rigid_body_owner.getornull(p_body_A); ERR_FAIL_COND_V(!body_A, RID()); JointAssertSpace(body_A, "A", RID()); RigidBodyBullet *body_B = NULL; if (p_body_B.is_valid()) { - body_B = rigid_body_owner.get(p_body_B); + body_B = rigid_body_owner.getornull(p_body_B); JointAssertSpace(body_B, "B", RID()); JointAssertSameSpace(body_A, body_B, RID()); } @@ -1230,7 +1230,7 @@ RID BulletPhysicsServer::joint_create_pin(RID p_body_A, const Vector3 &p_local_A } void BulletPhysicsServer::pin_joint_set_param(RID p_joint, PinJointParam p_param, float p_value) { - JointBullet *joint = joint_owner.get(p_joint); + JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_PIN); PinJointBullet *pin_joint = static_cast<PinJointBullet *>(joint); @@ -1238,7 +1238,7 @@ void BulletPhysicsServer::pin_joint_set_param(RID p_joint, PinJointParam p_param } float BulletPhysicsServer::pin_joint_get_param(RID p_joint, PinJointParam p_param) const { - JointBullet *joint = joint_owner.get(p_joint); + JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, 0); ERR_FAIL_COND_V(joint->get_type() != JOINT_PIN, 0); PinJointBullet *pin_joint = static_cast<PinJointBullet *>(joint); @@ -1246,7 +1246,7 @@ float BulletPhysicsServer::pin_joint_get_param(RID p_joint, PinJointParam p_para } void BulletPhysicsServer::pin_joint_set_local_a(RID p_joint, const Vector3 &p_A) { - JointBullet *joint = joint_owner.get(p_joint); + JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_PIN); PinJointBullet *pin_joint = static_cast<PinJointBullet *>(joint); @@ -1254,7 +1254,7 @@ void BulletPhysicsServer::pin_joint_set_local_a(RID p_joint, const Vector3 &p_A) } Vector3 BulletPhysicsServer::pin_joint_get_local_a(RID p_joint) const { - JointBullet *joint = joint_owner.get(p_joint); + JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, Vector3()); ERR_FAIL_COND_V(joint->get_type() != JOINT_PIN, Vector3()); PinJointBullet *pin_joint = static_cast<PinJointBullet *>(joint); @@ -1262,7 +1262,7 @@ Vector3 BulletPhysicsServer::pin_joint_get_local_a(RID p_joint) const { } void BulletPhysicsServer::pin_joint_set_local_b(RID p_joint, const Vector3 &p_B) { - JointBullet *joint = joint_owner.get(p_joint); + JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_PIN); PinJointBullet *pin_joint = static_cast<PinJointBullet *>(joint); @@ -1270,7 +1270,7 @@ void BulletPhysicsServer::pin_joint_set_local_b(RID p_joint, const Vector3 &p_B) } Vector3 BulletPhysicsServer::pin_joint_get_local_b(RID p_joint) const { - JointBullet *joint = joint_owner.get(p_joint); + JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, Vector3()); ERR_FAIL_COND_V(joint->get_type() != JOINT_PIN, Vector3()); PinJointBullet *pin_joint = static_cast<PinJointBullet *>(joint); @@ -1278,13 +1278,13 @@ Vector3 BulletPhysicsServer::pin_joint_get_local_b(RID p_joint) const { } RID BulletPhysicsServer::joint_create_hinge(RID p_body_A, const Transform &p_hinge_A, RID p_body_B, const Transform &p_hinge_B) { - RigidBodyBullet *body_A = rigid_body_owner.get(p_body_A); + RigidBodyBullet *body_A = rigid_body_owner.getornull(p_body_A); ERR_FAIL_COND_V(!body_A, RID()); JointAssertSpace(body_A, "A", RID()); RigidBodyBullet *body_B = NULL; if (p_body_B.is_valid()) { - body_B = rigid_body_owner.get(p_body_B); + body_B = rigid_body_owner.getornull(p_body_B); JointAssertSpace(body_B, "B", RID()); JointAssertSameSpace(body_A, body_B, RID()); } @@ -1298,13 +1298,13 @@ RID BulletPhysicsServer::joint_create_hinge(RID p_body_A, const Transform &p_hin } RID BulletPhysicsServer::joint_create_hinge_simple(RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) { - RigidBodyBullet *body_A = rigid_body_owner.get(p_body_A); + RigidBodyBullet *body_A = rigid_body_owner.getornull(p_body_A); ERR_FAIL_COND_V(!body_A, RID()); JointAssertSpace(body_A, "A", RID()); RigidBodyBullet *body_B = NULL; if (p_body_B.is_valid()) { - body_B = rigid_body_owner.get(p_body_B); + body_B = rigid_body_owner.getornull(p_body_B); JointAssertSpace(body_B, "B", RID()); JointAssertSameSpace(body_A, body_B, RID()); } @@ -1318,7 +1318,7 @@ RID BulletPhysicsServer::joint_create_hinge_simple(RID p_body_A, const Vector3 & } void BulletPhysicsServer::hinge_joint_set_param(RID p_joint, HingeJointParam p_param, float p_value) { - JointBullet *joint = joint_owner.get(p_joint); + JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_HINGE); HingeJointBullet *hinge_joint = static_cast<HingeJointBullet *>(joint); @@ -1326,7 +1326,7 @@ void BulletPhysicsServer::hinge_joint_set_param(RID p_joint, HingeJointParam p_p } float BulletPhysicsServer::hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const { - JointBullet *joint = joint_owner.get(p_joint); + JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, 0); ERR_FAIL_COND_V(joint->get_type() != JOINT_HINGE, 0); HingeJointBullet *hinge_joint = static_cast<HingeJointBullet *>(joint); @@ -1334,7 +1334,7 @@ float BulletPhysicsServer::hinge_joint_get_param(RID p_joint, HingeJointParam p_ } void BulletPhysicsServer::hinge_joint_set_flag(RID p_joint, HingeJointFlag p_flag, bool p_value) { - JointBullet *joint = joint_owner.get(p_joint); + JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_HINGE); HingeJointBullet *hinge_joint = static_cast<HingeJointBullet *>(joint); @@ -1342,7 +1342,7 @@ void BulletPhysicsServer::hinge_joint_set_flag(RID p_joint, HingeJointFlag p_fla } bool BulletPhysicsServer::hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag) const { - JointBullet *joint = joint_owner.get(p_joint); + JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, false); ERR_FAIL_COND_V(joint->get_type() != JOINT_HINGE, false); HingeJointBullet *hinge_joint = static_cast<HingeJointBullet *>(joint); @@ -1350,13 +1350,13 @@ bool BulletPhysicsServer::hinge_joint_get_flag(RID p_joint, HingeJointFlag p_fla } RID BulletPhysicsServer::joint_create_slider(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) { - RigidBodyBullet *body_A = rigid_body_owner.get(p_body_A); + RigidBodyBullet *body_A = rigid_body_owner.getornull(p_body_A); ERR_FAIL_COND_V(!body_A, RID()); JointAssertSpace(body_A, "A", RID()); RigidBodyBullet *body_B = NULL; if (p_body_B.is_valid()) { - body_B = rigid_body_owner.get(p_body_B); + body_B = rigid_body_owner.getornull(p_body_B); JointAssertSpace(body_B, "B", RID()); JointAssertSameSpace(body_A, body_B, RID()); } @@ -1370,7 +1370,7 @@ RID BulletPhysicsServer::joint_create_slider(RID p_body_A, const Transform &p_lo } void BulletPhysicsServer::slider_joint_set_param(RID p_joint, SliderJointParam p_param, float p_value) { - JointBullet *joint = joint_owner.get(p_joint); + JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_SLIDER); SliderJointBullet *slider_joint = static_cast<SliderJointBullet *>(joint); @@ -1378,7 +1378,7 @@ void BulletPhysicsServer::slider_joint_set_param(RID p_joint, SliderJointParam p } float BulletPhysicsServer::slider_joint_get_param(RID p_joint, SliderJointParam p_param) const { - JointBullet *joint = joint_owner.get(p_joint); + JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, 0); ERR_FAIL_COND_V(joint->get_type() != JOINT_SLIDER, 0); SliderJointBullet *slider_joint = static_cast<SliderJointBullet *>(joint); @@ -1386,13 +1386,13 @@ float BulletPhysicsServer::slider_joint_get_param(RID p_joint, SliderJointParam } RID BulletPhysicsServer::joint_create_cone_twist(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) { - RigidBodyBullet *body_A = rigid_body_owner.get(p_body_A); + RigidBodyBullet *body_A = rigid_body_owner.getornull(p_body_A); ERR_FAIL_COND_V(!body_A, RID()); JointAssertSpace(body_A, "A", RID()); RigidBodyBullet *body_B = NULL; if (p_body_B.is_valid()) { - body_B = rigid_body_owner.get(p_body_B); + body_B = rigid_body_owner.getornull(p_body_B); JointAssertSpace(body_B, "B", RID()); JointAssertSameSpace(body_A, body_B, RID()); } @@ -1404,7 +1404,7 @@ RID BulletPhysicsServer::joint_create_cone_twist(RID p_body_A, const Transform & } void BulletPhysicsServer::cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, float p_value) { - JointBullet *joint = joint_owner.get(p_joint); + JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_CONE_TWIST); ConeTwistJointBullet *coneTwist_joint = static_cast<ConeTwistJointBullet *>(joint); @@ -1412,7 +1412,7 @@ void BulletPhysicsServer::cone_twist_joint_set_param(RID p_joint, ConeTwistJoint } float BulletPhysicsServer::cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const { - JointBullet *joint = joint_owner.get(p_joint); + JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, 0.); ERR_FAIL_COND_V(joint->get_type() != JOINT_CONE_TWIST, 0.); ConeTwistJointBullet *coneTwist_joint = static_cast<ConeTwistJointBullet *>(joint); @@ -1420,13 +1420,13 @@ float BulletPhysicsServer::cone_twist_joint_get_param(RID p_joint, ConeTwistJoin } RID BulletPhysicsServer::joint_create_generic_6dof(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) { - RigidBodyBullet *body_A = rigid_body_owner.get(p_body_A); + RigidBodyBullet *body_A = rigid_body_owner.getornull(p_body_A); ERR_FAIL_COND_V(!body_A, RID()); JointAssertSpace(body_A, "A", RID()); RigidBodyBullet *body_B = NULL; if (p_body_B.is_valid()) { - body_B = rigid_body_owner.get(p_body_B); + body_B = rigid_body_owner.getornull(p_body_B); JointAssertSpace(body_B, "B", RID()); JointAssertSameSpace(body_A, body_B, RID()); } @@ -1440,7 +1440,7 @@ RID BulletPhysicsServer::joint_create_generic_6dof(RID p_body_A, const Transform } void BulletPhysicsServer::generic_6dof_joint_set_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param, float p_value) { - JointBullet *joint = joint_owner.get(p_joint); + JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_6DOF); Generic6DOFJointBullet *generic_6dof_joint = static_cast<Generic6DOFJointBullet *>(joint); @@ -1448,7 +1448,7 @@ void BulletPhysicsServer::generic_6dof_joint_set_param(RID p_joint, Vector3::Axi } float BulletPhysicsServer::generic_6dof_joint_get_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param) { - JointBullet *joint = joint_owner.get(p_joint); + JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, 0); ERR_FAIL_COND_V(joint->get_type() != JOINT_6DOF, 0); Generic6DOFJointBullet *generic_6dof_joint = static_cast<Generic6DOFJointBullet *>(joint); @@ -1456,7 +1456,7 @@ float BulletPhysicsServer::generic_6dof_joint_get_param(RID p_joint, Vector3::Ax } void BulletPhysicsServer::generic_6dof_joint_set_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag, bool p_enable) { - JointBullet *joint = joint_owner.get(p_joint); + JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_6DOF); Generic6DOFJointBullet *generic_6dof_joint = static_cast<Generic6DOFJointBullet *>(joint); @@ -1464,7 +1464,7 @@ void BulletPhysicsServer::generic_6dof_joint_set_flag(RID p_joint, Vector3::Axis } bool BulletPhysicsServer::generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag) { - JointBullet *joint = joint_owner.get(p_joint); + JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, false); ERR_FAIL_COND_V(joint->get_type() != JOINT_6DOF, false); Generic6DOFJointBullet *generic_6dof_joint = static_cast<Generic6DOFJointBullet *>(joint); @@ -1472,7 +1472,7 @@ bool BulletPhysicsServer::generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis } void BulletPhysicsServer::generic_6dof_joint_set_precision(RID p_joint, int p_precision) { - JointBullet *joint = joint_owner.get(p_joint); + JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND(!joint); ERR_FAIL_COND(joint->get_type() != JOINT_6DOF); Generic6DOFJointBullet *generic_6dof_joint = static_cast<Generic6DOFJointBullet *>(joint); @@ -1480,7 +1480,7 @@ void BulletPhysicsServer::generic_6dof_joint_set_precision(RID p_joint, int p_pr } int BulletPhysicsServer::generic_6dof_joint_get_precision(RID p_joint) { - JointBullet *joint = joint_owner.get(p_joint); + JointBullet *joint = joint_owner.getornull(p_joint); ERR_FAIL_COND_V(!joint, 0); ERR_FAIL_COND_V(joint->get_type() != JOINT_6DOF, 0); Generic6DOFJointBullet *generic_6dof_joint = static_cast<Generic6DOFJointBullet *>(joint); @@ -1490,7 +1490,7 @@ int BulletPhysicsServer::generic_6dof_joint_get_precision(RID p_joint) { void BulletPhysicsServer::free(RID p_rid) { if (shape_owner.owns(p_rid)) { - ShapeBullet *shape = shape_owner.get(p_rid); + ShapeBullet *shape = shape_owner.getornull(p_rid); // Notify the shape is configured for (Map<ShapeOwnerBullet *, int>::Element *element = shape->get_owners().front(); element; element = element->next()) { @@ -1501,7 +1501,7 @@ void BulletPhysicsServer::free(RID p_rid) { bulletdelete(shape); } else if (rigid_body_owner.owns(p_rid)) { - RigidBodyBullet *body = rigid_body_owner.get(p_rid); + RigidBodyBullet *body = rigid_body_owner.getornull(p_rid); body->set_space(NULL); @@ -1512,7 +1512,7 @@ void BulletPhysicsServer::free(RID p_rid) { } else if (soft_body_owner.owns(p_rid)) { - SoftBodyBullet *body = soft_body_owner.get(p_rid); + SoftBodyBullet *body = soft_body_owner.getornull(p_rid); body->set_space(NULL); @@ -1521,7 +1521,7 @@ void BulletPhysicsServer::free(RID p_rid) { } else if (area_owner.owns(p_rid)) { - AreaBullet *area = area_owner.get(p_rid); + AreaBullet *area = area_owner.getornull(p_rid); area->set_space(NULL); @@ -1532,14 +1532,14 @@ void BulletPhysicsServer::free(RID p_rid) { } else if (joint_owner.owns(p_rid)) { - JointBullet *joint = joint_owner.get(p_rid); + JointBullet *joint = joint_owner.getornull(p_rid); joint->destroy_internal_constraint(); joint_owner.free(p_rid); bulletdelete(joint); } else if (space_owner.owns(p_rid)) { - SpaceBullet *space = space_owner.get(p_rid); + SpaceBullet *space = space_owner.getornull(p_rid); space->remove_all_collision_objects(); diff --git a/modules/bullet/bullet_physics_server.h b/modules/bullet/bullet_physics_server.h index 4a3b4a2edc..6ea9a7a974 100644 --- a/modules/bullet/bullet_physics_server.h +++ b/modules/bullet/bullet_physics_server.h @@ -33,13 +33,13 @@ #include "area_bullet.h" #include "core/rid.h" +#include "core/rid_owner.h" #include "joint_bullet.h" #include "rigid_body_bullet.h" #include "servers/physics_server.h" #include "shape_bullet.h" #include "soft_body_bullet.h" #include "space_bullet.h" - /** @author AndreaCatania */ @@ -53,12 +53,12 @@ class BulletPhysicsServer : public PhysicsServer { char active_spaces_count; Vector<SpaceBullet *> active_spaces; - mutable RID_Owner<SpaceBullet> space_owner; - mutable RID_Owner<ShapeBullet> shape_owner; - mutable RID_Owner<AreaBullet> area_owner; - mutable RID_Owner<RigidBodyBullet> rigid_body_owner; - mutable RID_Owner<SoftBodyBullet> soft_body_owner; - mutable RID_Owner<JointBullet> joint_owner; + mutable RID_PtrOwner<SpaceBullet> space_owner; + mutable RID_PtrOwner<ShapeBullet> shape_owner; + mutable RID_PtrOwner<AreaBullet> area_owner; + mutable RID_PtrOwner<RigidBodyBullet> rigid_body_owner; + mutable RID_PtrOwner<SoftBodyBullet> soft_body_owner; + mutable RID_PtrOwner<JointBullet> joint_owner; protected: static void _bind_methods(); @@ -67,22 +67,22 @@ public: BulletPhysicsServer(); ~BulletPhysicsServer(); - _FORCE_INLINE_ RID_Owner<SpaceBullet> *get_space_owner() { + _FORCE_INLINE_ RID_PtrOwner<SpaceBullet> *get_space_owner() { return &space_owner; } - _FORCE_INLINE_ RID_Owner<ShapeBullet> *get_shape_owner() { + _FORCE_INLINE_ RID_PtrOwner<ShapeBullet> *get_shape_owner() { return &shape_owner; } - _FORCE_INLINE_ RID_Owner<AreaBullet> *get_area_owner() { + _FORCE_INLINE_ RID_PtrOwner<AreaBullet> *get_area_owner() { return &area_owner; } - _FORCE_INLINE_ RID_Owner<RigidBodyBullet> *get_rigid_body_owner() { + _FORCE_INLINE_ RID_PtrOwner<RigidBodyBullet> *get_rigid_body_owner() { return &rigid_body_owner; } - _FORCE_INLINE_ RID_Owner<SoftBodyBullet> *get_soft_body_owner() { + _FORCE_INLINE_ RID_PtrOwner<SoftBodyBullet> *get_soft_body_owner() { return &soft_body_owner; } - _FORCE_INLINE_ RID_Owner<JointBullet> *get_joint_owner() { + _FORCE_INLINE_ RID_PtrOwner<JointBullet> *get_joint_owner() { return &joint_owner; } @@ -189,8 +189,8 @@ public: virtual void body_clear_shapes(RID p_body); // Used for Rigid and Soft Bodies - virtual void body_attach_object_instance_id(RID p_body, uint32_t p_id); - virtual uint32_t body_get_object_instance_id(RID p_body) const; + virtual void body_attach_object_instance_id(RID p_body, ObjectID p_id); + virtual ObjectID body_get_object_instance_id(RID p_body) const; virtual void body_set_enable_continuous_collision_detection(RID p_body, bool p_enable); virtual bool body_is_continuous_collision_detection_enabled(RID p_body) const; diff --git a/modules/bullet/collision_object_bullet.cpp b/modules/bullet/collision_object_bullet.cpp index c916c65d2b..5b7e7281e4 100644 --- a/modules/bullet/collision_object_bullet.cpp +++ b/modules/bullet/collision_object_bullet.cpp @@ -90,7 +90,7 @@ void CollisionObjectBullet::ShapeWrapper::claim_bt_shape(const btVector3 &body_s CollisionObjectBullet::CollisionObjectBullet(Type p_type) : RIDBullet(), type(p_type), - instance_id(0), + instance_id(ObjectID()), collisionLayer(0), collisionMask(0), collisionsEnabled(true), diff --git a/modules/bullet/cone_twist_joint_bullet.cpp b/modules/bullet/cone_twist_joint_bullet.cpp index afeafcc356..23eb39fe7e 100644 --- a/modules/bullet/cone_twist_joint_bullet.cpp +++ b/modules/bullet/cone_twist_joint_bullet.cpp @@ -82,8 +82,8 @@ void ConeTwistJointBullet::set_param(PhysicsServer::ConeTwistJointParam p_param, case PhysicsServer::CONE_TWIST_JOINT_RELAXATION: coneConstraint->setLimit(coneConstraint->getSwingSpan1(), coneConstraint->getSwingSpan2(), coneConstraint->getTwistSpan(), coneConstraint->getLimitSoftness(), coneConstraint->getBiasFactor(), p_value); break; - default: - WARN_DEPRECATED_MSG("The parameter " + itos(p_param) + " is deprecated."); + case PhysicsServer::CONE_TWIST_MAX: + // Internal size value, nothing to do. break; } } @@ -100,8 +100,10 @@ real_t ConeTwistJointBullet::get_param(PhysicsServer::ConeTwistJointParam p_para return coneConstraint->getLimitSoftness(); case PhysicsServer::CONE_TWIST_JOINT_RELAXATION: return coneConstraint->getRelaxationFactor(); - default: - WARN_DEPRECATED_MSG("The parameter " + itos(p_param) + " is deprecated."); + case PhysicsServer::CONE_TWIST_MAX: + // Internal size value, nothing to do. return 0; } + // Compiler doesn't seem to notice that all code paths are fulfilled... + return 0; } diff --git a/modules/bullet/generic_6dof_joint_bullet.cpp b/modules/bullet/generic_6dof_joint_bullet.cpp index 86bedd6c45..45ab3d3bb2 100644 --- a/modules/bullet/generic_6dof_joint_bullet.cpp +++ b/modules/bullet/generic_6dof_joint_bullet.cpp @@ -173,6 +173,9 @@ void Generic6DOFJointBullet::set_param(Vector3::Axis p_axis, PhysicsServer::G6DO case PhysicsServer::G6DOF_JOINT_ANGULAR_SPRING_EQUILIBRIUM_POINT: sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_equilibriumPoint = p_value; break; + case PhysicsServer::G6DOF_JOINT_MAX: + // Internal size value, nothing to do. + break; default: WARN_DEPRECATED_MSG("The parameter " + itos(p_param) + " is deprecated."); break; @@ -214,6 +217,9 @@ real_t Generic6DOFJointBullet::get_param(Vector3::Axis p_axis, PhysicsServer::G6 return sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_springDamping; case PhysicsServer::G6DOF_JOINT_ANGULAR_SPRING_EQUILIBRIUM_POINT: return sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_equilibriumPoint; + case PhysicsServer::G6DOF_JOINT_MAX: + // Internal size value, nothing to do. + return 0; default: WARN_DEPRECATED_MSG("The parameter " + itos(p_param) + " is deprecated."); return 0; @@ -240,20 +246,20 @@ void Generic6DOFJointBullet::set_flag(Vector3::Axis p_axis, PhysicsServer::G6DOF sixDOFConstraint->setLimit(p_axis + 3, 0, -1); // Free } break; + case PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_SPRING: + sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_enableSpring = p_value; + break; + case PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_LINEAR_SPRING: + sixDOFConstraint->getTranslationalLimitMotor()->m_enableSpring[p_axis] = p_value; + break; case PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_MOTOR: sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_enableMotor = flags[p_axis][p_flag]; break; case PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_LINEAR_MOTOR: sixDOFConstraint->getTranslationalLimitMotor()->m_enableMotor[p_axis] = flags[p_axis][p_flag]; break; - case PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_LINEAR_SPRING: - sixDOFConstraint->getTranslationalLimitMotor()->m_enableSpring[p_axis] = p_value; - break; - case PhysicsServer::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_SPRING: - sixDOFConstraint->getRotationalLimitMotor(p_axis)->m_enableSpring = p_value; - break; - default: - WARN_DEPRECATED_MSG("The flag " + itos(p_flag) + " is deprecated."); + case PhysicsServer::G6DOF_JOINT_FLAG_MAX: + // Internal size value, nothing to do. break; } } diff --git a/modules/bullet/godot_result_callbacks.cpp b/modules/bullet/godot_result_callbacks.cpp index 6e54d10abf..20467e3ef3 100644 --- a/modules/bullet/godot_result_callbacks.cpp +++ b/modules/bullet/godot_result_callbacks.cpp @@ -112,7 +112,7 @@ btScalar GodotAllConvexResultCallback::addSingleResult(btCollisionWorld::LocalCo result.shape = convexResult.m_localShapeInfo->m_triangleIndex; // "m_triangleIndex" Is a odd name but contains the compound shape ID result.rid = gObj->get_self(); result.collider_id = gObj->get_instance_id(); - result.collider = 0 == result.collider_id ? NULL : ObjectDB::get_instance(result.collider_id); + result.collider = result.collider_id.is_null() ? NULL : ObjectDB::get_instance(result.collider_id); ++count; return 1; // not used by bullet @@ -220,7 +220,7 @@ btScalar GodotAllContactResultCallback::addSingleResult(btManifoldPoint &cp, con } result.collider_id = colObj->get_instance_id(); - result.collider = 0 == result.collider_id ? NULL : ObjectDB::get_instance(result.collider_id); + result.collider = result.collider_id.is_null() ? NULL : ObjectDB::get_instance(result.collider_id); result.rid = colObj->get_self(); ++m_count; } diff --git a/modules/bullet/hinge_joint_bullet.cpp b/modules/bullet/hinge_joint_bullet.cpp index 49e67bfbc1..970732688a 100644 --- a/modules/bullet/hinge_joint_bullet.cpp +++ b/modules/bullet/hinge_joint_bullet.cpp @@ -95,6 +95,9 @@ real_t HingeJointBullet::get_hinge_angle() { void HingeJointBullet::set_param(PhysicsServer::HingeJointParam p_param, real_t p_value) { switch (p_param) { + case PhysicsServer::HINGE_JOINT_BIAS: + WARN_DEPRECATED_MSG("The HingeJoint parameter \"bias\" is deprecated."); + break; case PhysicsServer::HINGE_JOINT_LIMIT_UPPER: hingeConstraint->setLimit(hingeConstraint->getLowerLimit(), p_value, hingeConstraint->getLimitSoftness(), hingeConstraint->getLimitBiasFactor(), hingeConstraint->getLimitRelaxationFactor()); break; @@ -116,8 +119,8 @@ void HingeJointBullet::set_param(PhysicsServer::HingeJointParam p_param, real_t case PhysicsServer::HINGE_JOINT_MOTOR_MAX_IMPULSE: hingeConstraint->setMaxMotorImpulse(p_value); break; - default: - WARN_DEPRECATED_MSG("The HingeJoint parameter " + itos(p_param) + " is deprecated."); + case PhysicsServer::HINGE_JOINT_MAX: + // Internal size value, nothing to do. break; } } @@ -125,8 +128,8 @@ void HingeJointBullet::set_param(PhysicsServer::HingeJointParam p_param, real_t real_t HingeJointBullet::get_param(PhysicsServer::HingeJointParam p_param) const { switch (p_param) { case PhysicsServer::HINGE_JOINT_BIAS: + WARN_DEPRECATED_MSG("The HingeJoint parameter \"bias\" is deprecated."); return 0; - break; case PhysicsServer::HINGE_JOINT_LIMIT_UPPER: return hingeConstraint->getUpperLimit(); case PhysicsServer::HINGE_JOINT_LIMIT_LOWER: @@ -141,10 +144,12 @@ real_t HingeJointBullet::get_param(PhysicsServer::HingeJointParam p_param) const return hingeConstraint->getMotorTargetVelocity(); case PhysicsServer::HINGE_JOINT_MOTOR_MAX_IMPULSE: return hingeConstraint->getMaxMotorImpulse(); - default: - WARN_DEPRECATED_MSG("The HingeJoint parameter " + itos(p_param) + " is deprecated."); + case PhysicsServer::HINGE_JOINT_MAX: + // Internal size value, nothing to do. return 0; } + // Compiler doesn't seem to notice that all code paths are fulfilled... + return 0; } void HingeJointBullet::set_flag(PhysicsServer::HingeJointFlag p_flag, bool p_value) { diff --git a/modules/bullet/pin_joint_bullet.cpp b/modules/bullet/pin_joint_bullet.cpp index 1c2e5e65cc..8d109f1866 100644 --- a/modules/bullet/pin_joint_bullet.cpp +++ b/modules/bullet/pin_joint_bullet.cpp @@ -84,10 +84,9 @@ real_t PinJointBullet::get_param(PhysicsServer::PinJointParam p_param) const { return p2pConstraint->m_setting.m_damping; case PhysicsServer::PIN_JOINT_IMPULSE_CLAMP: return p2pConstraint->m_setting.m_impulseClamp; - default: - WARN_DEPRECATED_MSG("The parameter " + itos(p_param) + " is deprecated."); - return 0; } + // Compiler doesn't seem to notice that all code paths are fulfilled... + return 0; } void PinJointBullet::setPivotInA(const Vector3 &p_pos) { diff --git a/modules/bullet/rid_bullet.h b/modules/bullet/rid_bullet.h index 28bcedb01a..b76641ca54 100644 --- a/modules/bullet/rid_bullet.h +++ b/modules/bullet/rid_bullet.h @@ -39,7 +39,7 @@ class BulletPhysicsServer; -class RIDBullet : public RID_Data { +class RIDBullet { RID self; BulletPhysicsServer *physicsServer; diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp index 16a8cf8ede..e5804fbde8 100644 --- a/modules/bullet/rigid_body_bullet.cpp +++ b/modules/bullet/rigid_body_bullet.cpp @@ -320,7 +320,7 @@ void RigidBodyBullet::destroy_kinematic_utilities() { } void RigidBodyBullet::main_shape_changed() { - CRASH_COND(!get_main_shape()) + CRASH_COND(!get_main_shape()); btBody->setCollisionShape(get_main_shape()); set_continuous_collision_detection(is_continuous_collision_detection_enabled()); // Reset } @@ -366,7 +366,7 @@ void RigidBodyBullet::dispatch_callbacks() { Object *obj = ObjectDB::get_instance(force_integration_callback->id); if (!obj) { // Remove integration callback - set_force_integration_callback(0, StringName()); + set_force_integration_callback(ObjectID(), StringName()); } else { const Variant *vp[2] = { &variantBodyDirect, &force_integration_callback->udata }; @@ -395,7 +395,7 @@ void RigidBodyBullet::set_force_integration_callback(ObjectID p_id, const String force_integration_callback = NULL; } - if (p_id != 0) { + if (p_id.is_valid()) { force_integration_callback = memnew(ForceIntegrationCallback); force_integration_callback->id = p_id; force_integration_callback->method = p_method; @@ -515,7 +515,7 @@ void RigidBodyBullet::set_param(PhysicsServer::BodyParameter p_param, real_t p_v scratch_space_override_modificator(); break; default: - WARN_PRINTS("Parameter " + itos(p_param) + " not supported by bullet. Value: " + itos(p_value)); + WARN_PRINT("Parameter " + itos(p_param) + " not supported by bullet. Value: " + itos(p_value)); } } @@ -536,7 +536,7 @@ real_t RigidBodyBullet::get_param(PhysicsServer::BodyParameter p_param) const { case PhysicsServer::BODY_PARAM_GRAVITY_SCALE: return gravity_scale; default: - WARN_PRINTS("Parameter " + itos(p_param) + " not supported by bullet"); + WARN_PRINT("Parameter " + itos(p_param) + " not supported by bullet"); return 0; } } @@ -619,7 +619,7 @@ Variant RigidBodyBullet::get_state(PhysicsServer::BodyState p_state) const { case PhysicsServer::BODY_STATE_CAN_SLEEP: return can_sleep; default: - WARN_PRINTS("This state " + itos(p_state) + " is not supported by Bullet"); + WARN_PRINT("This state " + itos(p_state) + " is not supported by Bullet"); return Variant(); } } diff --git a/modules/bullet/soft_body_bullet.cpp b/modules/bullet/soft_body_bullet.cpp index f4c0ffa6eb..a7988279c0 100644 --- a/modules/bullet/soft_body_bullet.cpp +++ b/modules/bullet/soft_body_bullet.cpp @@ -168,6 +168,7 @@ void SoftBodyBullet::set_node_position(int p_node_index, const Vector3 &p_global void SoftBodyBullet::set_node_position(int p_node_index, const btVector3 &p_global_position) { if (bt_soft_body) { + bt_soft_body->m_nodes[p_node_index].m_q = bt_soft_body->m_nodes[p_node_index].m_x; bt_soft_body->m_nodes[p_node_index].m_x = p_global_position; } } diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp index 0f50d31611..0e4c4b4731 100644 --- a/modules/bullet/space_bullet.cpp +++ b/modules/bullet/space_bullet.cpp @@ -108,9 +108,9 @@ bool BulletPhysicsDirectSpaceState::intersect_ray(const Vector3 &p_from, const V r_result.shape = btResult.m_shapeId; r_result.rid = gObj->get_self(); r_result.collider_id = gObj->get_instance_id(); - r_result.collider = 0 == r_result.collider_id ? NULL : ObjectDB::get_instance(r_result.collider_id); + r_result.collider = r_result.collider_id.is_null() ? NULL : ObjectDB::get_instance(r_result.collider_id); } else { - WARN_PRINTS("The raycast performed has hit a collision object that is not part of Godot scene, please check it."); + WARN_PRINT("The raycast performed has hit a collision object that is not part of Godot scene, please check it."); } return true; } else { @@ -122,12 +122,12 @@ int BulletPhysicsDirectSpaceState::intersect_shape(const RID &p_shape, const Tra if (p_result_max <= 0) return 0; - ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->get(p_shape); + ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->getornull(p_shape); btCollisionShape *btShape = shape->create_bt_shape(p_xform.basis.get_scale_abs(), p_margin); if (!btShape->isConvex()) { bulletdelete(btShape); - ERR_PRINTS("The shape is not a convex shape, then is not supported: shape type: " + itos(shape->get_type())); + ERR_PRINT("The shape is not a convex shape, then is not supported: shape type: " + itos(shape->get_type())); return 0; } btConvexShape *btConvex = static_cast<btConvexShape *>(btShape); @@ -152,12 +152,12 @@ int BulletPhysicsDirectSpaceState::intersect_shape(const RID &p_shape, const Tra } bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, float p_margin, float &r_closest_safe, float &r_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, ShapeRestInfo *r_info) { - ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->get(p_shape); + ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->getornull(p_shape); btCollisionShape *btShape = shape->create_bt_shape(p_xform.basis.get_scale(), p_margin); if (!btShape->isConvex()) { bulletdelete(btShape); - ERR_PRINTS("The shape is not a convex shape, then is not supported: shape type: " + itos(shape->get_type())); + ERR_PRINT("The shape is not a convex shape, then is not supported: shape type: " + itos(shape->get_type())); return false; } btConvexShape *bt_convex_shape = static_cast<btConvexShape *>(btShape); @@ -207,12 +207,12 @@ bool BulletPhysicsDirectSpaceState::collide_shape(RID p_shape, const Transform & if (p_result_max <= 0) return 0; - ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->get(p_shape); + ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->getornull(p_shape); btCollisionShape *btShape = shape->create_bt_shape(p_shape_xform.basis.get_scale_abs(), p_margin); if (!btShape->isConvex()) { bulletdelete(btShape); - ERR_PRINTS("The shape is not a convex shape, then is not supported: shape type: " + itos(shape->get_type())); + ERR_PRINT("The shape is not a convex shape, then is not supported: shape type: " + itos(shape->get_type())); return 0; } btConvexShape *btConvex = static_cast<btConvexShape *>(btShape); @@ -239,12 +239,12 @@ bool BulletPhysicsDirectSpaceState::collide_shape(RID p_shape, const Transform & bool BulletPhysicsDirectSpaceState::rest_info(RID p_shape, const Transform &p_shape_xform, float p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) { - ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->get(p_shape); + ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->getornull(p_shape); btCollisionShape *btShape = shape->create_bt_shape(p_shape_xform.basis.get_scale_abs(), p_margin); if (!btShape->isConvex()) { bulletdelete(btShape); - ERR_PRINTS("The shape is not a convex shape, then is not supported: shape type: " + itos(shape->get_type())); + ERR_PRINT("The shape is not a convex shape, then is not supported: shape type: " + itos(shape->get_type())); return 0; } btConvexShape *btConvex = static_cast<btConvexShape *>(btShape); @@ -389,7 +389,7 @@ void SpaceBullet::set_param(PhysicsServer::AreaParameter p_param, const Variant case PhysicsServer::AREA_PARAM_GRAVITY_POINT_ATTENUATION: break; default: - WARN_PRINTS("This set parameter (" + itos(p_param) + ") is ignored, the SpaceBullet doesn't support it."); + WARN_PRINT("This set parameter (" + itos(p_param) + ") is ignored, the SpaceBullet doesn't support it."); break; } } @@ -412,7 +412,7 @@ Variant SpaceBullet::get_param(PhysicsServer::AreaParameter p_param) { case PhysicsServer::AREA_PARAM_GRAVITY_POINT_ATTENUATION: return 0; default: - WARN_PRINTS("This get parameter (" + itos(p_param) + ") is ignored, the SpaceBullet doesn't support it."); + WARN_PRINT("This get parameter (" + itos(p_param) + ") is ignored, the SpaceBullet doesn't support it."); return Variant(); } } @@ -428,7 +428,7 @@ void SpaceBullet::set_param(PhysicsServer::SpaceParameter p_param, real_t p_valu case PhysicsServer::SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO: case PhysicsServer::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS: default: - WARN_PRINTS("This set parameter (" + itos(p_param) + ") is ignored, the SpaceBullet doesn't support it."); + WARN_PRINT("This set parameter (" + itos(p_param) + ") is ignored, the SpaceBullet doesn't support it."); break; } } @@ -444,7 +444,7 @@ real_t SpaceBullet::get_param(PhysicsServer::SpaceParameter p_param) { case PhysicsServer::SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO: case PhysicsServer::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS: default: - WARN_PRINTS("The SpaceBullet doesn't support this get parameter (" + itos(p_param) + "), 0 is returned."); + WARN_PRINT("The SpaceBullet doesn't support this get parameter (" + itos(p_param) + "), 0 is returned."); return 0.f; } } @@ -890,8 +890,8 @@ void SpaceBullet::update_gravity() { static ImmediateGeometry *motionVec(NULL); static ImmediateGeometry *normalLine(NULL); -static Ref<SpatialMaterial> red_mat; -static Ref<SpatialMaterial> blue_mat; +static Ref<StandardMaterial3D> red_mat; +static Ref<StandardMaterial3D> blue_mat; #endif bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, PhysicsServer::MotionResult *r_result, bool p_exclude_raycast_shapes) { @@ -908,21 +908,21 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f motionVec->set_as_toplevel(true); normalLine->set_as_toplevel(true); - red_mat = Ref<SpatialMaterial>(memnew(SpatialMaterial)); - red_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true); + red_mat = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); + red_mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); red_mat->set_line_width(20.0); - red_mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); - red_mat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); - red_mat->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true); + red_mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); + red_mat->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); + red_mat->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true); red_mat->set_albedo(Color(1, 0, 0, 1)); motionVec->set_material_override(red_mat); - blue_mat = Ref<SpatialMaterial>(memnew(SpatialMaterial)); - blue_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true); + blue_mat = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); + blue_mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); blue_mat->set_line_width(20.0); - blue_mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); - blue_mat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); - blue_mat->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true); + blue_mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); + blue_mat->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); + blue_mat->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true); blue_mat->set_albedo(Color(0, 0, 1, 1)); normalLine->set_material_override(blue_mat); } diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp index c8a72ff813..33e4e9748c 100644 --- a/modules/csg/csg_shape.cpp +++ b/modules/csg/csg_shape.cpp @@ -896,7 +896,7 @@ void CSGMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("get_material"), &CSGMesh::get_material); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "SpatialMaterial,ShaderMaterial"), "set_material", "get_material"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "StandardMaterial3D,ShaderMaterial"), "set_material", "get_material"); } void CSGMesh::set_mesh(const Ref<Mesh> &p_mesh) { @@ -1059,7 +1059,7 @@ void CSGSphere::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "radial_segments", PROPERTY_HINT_RANGE, "1,100,1"), "set_radial_segments", "get_radial_segments"); ADD_PROPERTY(PropertyInfo(Variant::INT, "rings", PROPERTY_HINT_RANGE, "1,100,1"), "set_rings", "get_rings"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smooth_faces"), "set_smooth_faces", "get_smooth_faces"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "SpatialMaterial,ShaderMaterial"), "set_material", "get_material"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "StandardMaterial3D,ShaderMaterial"), "set_material", "get_material"); } void CSGSphere::set_radius(const float p_radius) { @@ -1245,7 +1245,7 @@ void CSGBox::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "width", PROPERTY_HINT_EXP_RANGE, "0.001,1000.0,0.001,or_greater"), "set_width", "get_width"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "height", PROPERTY_HINT_EXP_RANGE, "0.001,1000.0,0.001,or_greater"), "set_height", "get_height"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "depth", PROPERTY_HINT_EXP_RANGE, "0.001,1000.0,0.001,or_greater"), "set_depth", "get_depth"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "SpatialMaterial,ShaderMaterial"), "set_material", "get_material"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "StandardMaterial3D,ShaderMaterial"), "set_material", "get_material"); } void CSGBox::set_width(const float p_width) { @@ -1462,7 +1462,7 @@ void CSGCylinder::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "sides", PROPERTY_HINT_RANGE, "3,64,1"), "set_sides", "get_sides"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cone"), "set_cone", "is_cone"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smooth_faces"), "set_smooth_faces", "get_smooth_faces"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "SpatialMaterial,ShaderMaterial"), "set_material", "get_material"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "StandardMaterial3D,ShaderMaterial"), "set_material", "get_material"); } void CSGCylinder::set_radius(const float p_radius) { @@ -1689,7 +1689,7 @@ void CSGTorus::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "sides", PROPERTY_HINT_RANGE, "3,64,1"), "set_sides", "get_sides"); ADD_PROPERTY(PropertyInfo(Variant::INT, "ring_sides", PROPERTY_HINT_RANGE, "3,64,1"), "set_ring_sides", "get_ring_sides"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smooth_faces"), "set_smooth_faces", "get_smooth_faces"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "SpatialMaterial,ShaderMaterial"), "set_material", "get_material"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "StandardMaterial3D,ShaderMaterial"), "set_material", "get_material"); } void CSGTorus::set_inner_radius(const float p_inner_radius) { @@ -2330,7 +2330,7 @@ void CSGPolygon::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "path_continuous_u"), "set_path_continuous_u", "is_path_continuous_u"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "path_joined"), "set_path_joined", "is_path_joined"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smooth_faces"), "set_smooth_faces", "get_smooth_faces"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "SpatialMaterial,ShaderMaterial"), "set_material", "get_material"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "StandardMaterial3D,ShaderMaterial"), "set_material", "get_material"); BIND_ENUM_CONSTANT(MODE_DEPTH); BIND_ENUM_CONSTANT(MODE_SPIN); diff --git a/modules/cvtt/image_compress_cvtt.cpp b/modules/cvtt/image_compress_cvtt.cpp index c261350e89..4d762b7a7b 100644 --- a/modules/cvtt/image_compress_cvtt.cpp +++ b/modules/cvtt/image_compress_cvtt.cpp @@ -136,7 +136,7 @@ static void _digest_job_queue(void *p_job_queue) { } } -void image_compress_cvtt(Image *p_image, float p_lossy_quality, Image::CompressSource p_source) { +void image_compress_cvtt(Image *p_image, float p_lossy_quality, Image::UsedChannels p_channels) { if (p_image->get_format() >= Image::FORMAT_BPTC_RGBA) return; //do not compress, already compressed @@ -167,7 +167,7 @@ void image_compress_cvtt(Image *p_image, float p_lossy_quality, Image::CompressS flags |= cvtt::Flags::BC7_RespectPunchThrough; - if (p_source == Image::COMPRESS_SOURCE_NORMAL) { + if (p_channels == Image::USED_CHANNELS_RG) { //guessing this is a normalmap flags |= cvtt::Flags::Uniform; } diff --git a/modules/cvtt/image_compress_cvtt.h b/modules/cvtt/image_compress_cvtt.h index ecb876ecc6..c1772199af 100644 --- a/modules/cvtt/image_compress_cvtt.h +++ b/modules/cvtt/image_compress_cvtt.h @@ -33,7 +33,7 @@ #include "core/image.h" -void image_compress_cvtt(Image *p_image, float p_lossy_quality, Image::CompressSource p_source); +void image_compress_cvtt(Image *p_image, float p_lossy_quality, Image::UsedChannels p_channels); void image_decompress_cvtt(Image *p_image); #endif // IMAGE_COMPRESS_CVTT_H diff --git a/modules/dds/texture_loader_dds.cpp b/modules/dds/texture_loader_dds.cpp index a7701329d8..5494744c48 100644 --- a/modules/dds/texture_loader_dds.cpp +++ b/modules/dds/texture_loader_dds.cpp @@ -457,7 +457,7 @@ void ResourceFormatDDS::get_recognized_extensions(List<String> *p_extensions) co bool ResourceFormatDDS::handles_type(const String &p_type) const { - return ClassDB::is_parent_class(p_type, "Texture"); + return ClassDB::is_parent_class(p_type, "Texture2D"); } String ResourceFormatDDS::get_resource_type(const String &p_path) const { diff --git a/modules/etc/image_etc.cpp b/modules/etc/image_etc.cpp index b80138c99d..24ee8e458e 100644 --- a/modules/etc/image_etc.cpp +++ b/modules/etc/image_etc.cpp @@ -36,18 +36,18 @@ #include "core/os/os.h" #include "core/print_string.h" -static Image::Format _get_etc2_mode(Image::DetectChannels format) { +static Image::Format _get_etc2_mode(Image::UsedChannels format) { switch (format) { - case Image::DETECTED_R: + case Image::USED_CHANNELS_R: return Image::FORMAT_ETC2_R11; - case Image::DETECTED_RG: + case Image::USED_CHANNELS_RG: return Image::FORMAT_ETC2_RG11; - case Image::DETECTED_RGB: + case Image::USED_CHANNELS_RGB: return Image::FORMAT_ETC2_RGB8; - case Image::DETECTED_RGBA: + case Image::USED_CHANNELS_RGBA: return Image::FORMAT_ETC2_RGBA8; // TODO: would be nice if we could use FORMAT_ETC2_RGB8A1 for FORMAT_RGBA5551 @@ -88,47 +88,8 @@ static Etc::Image::Format _image_format_to_etc2comp_format(Image::Format format) } } -static void _compress_etc(Image *p_img, float p_lossy_quality, bool force_etc1_format, Image::CompressSource p_source) { +static void _compress_etc(Image *p_img, float p_lossy_quality, bool force_etc1_format, Image::UsedChannels p_channels) { Image::Format img_format = p_img->get_format(); - Image::DetectChannels detected_channels = p_img->get_detected_channels(); - - if (p_source == Image::COMPRESS_SOURCE_LAYERED) { - //keep what comes in - switch (p_img->get_format()) { - case Image::FORMAT_L8: { - detected_channels = Image::DETECTED_L; - } break; - case Image::FORMAT_LA8: { - detected_channels = Image::DETECTED_LA; - } break; - case Image::FORMAT_R8: { - detected_channels = Image::DETECTED_R; - } break; - case Image::FORMAT_RG8: { - detected_channels = Image::DETECTED_RG; - } break; - case Image::FORMAT_RGB8: { - detected_channels = Image::DETECTED_RGB; - } break; - case Image::FORMAT_RGBA8: - case Image::FORMAT_RGBA4444: - case Image::FORMAT_RGBA5551: { - detected_channels = Image::DETECTED_RGBA; - } break; - default: { - } - } - } - - if (p_source == Image::COMPRESS_SOURCE_SRGB && (detected_channels == Image::DETECTED_R || detected_channels == Image::DETECTED_RG)) { - //R and RG do not support SRGB - detected_channels = Image::DETECTED_RGB; - } - - if (p_source == Image::COMPRESS_SOURCE_NORMAL) { - //use RG channels only for normal - detected_channels = Image::DETECTED_RG; - } if (img_format >= Image::FORMAT_DXT1) { return; //do not compress, already compressed @@ -139,21 +100,24 @@ static void _compress_etc(Image *p_img, float p_lossy_quality, bool force_etc1_f return; } + // FIXME: Commented out during Vulkan rebase. + /* if (force_etc1_format) { // If VRAM compression is using ETC, but image has alpha, convert to RGBA4444 or LA8 // This saves space while maintaining the alpha channel - if (detected_channels == Image::DETECTED_RGBA) { + if (detected_channels == Image::USED_CHANNELS_RGBA) { p_img->convert(Image::FORMAT_RGBA4444); return; - } else if (detected_channels == Image::DETECTED_LA) { + } else if (detected_channels == Image::USE_CHANNELS_LA) { p_img->convert(Image::FORMAT_LA8); return; } } + */ uint32_t imgw = p_img->get_width(), imgh = p_img->get_height(); - Image::Format etc_format = force_etc1_format ? Image::FORMAT_ETC : _get_etc2_mode(detected_channels); + Image::Format etc_format = force_etc1_format ? Image::FORMAT_ETC : _get_etc2_mode(p_channels); Ref<Image> img = p_img->duplicate(); @@ -241,11 +205,11 @@ static void _compress_etc(Image *p_img, float p_lossy_quality, bool force_etc1_f } static void _compress_etc1(Image *p_img, float p_lossy_quality) { - _compress_etc(p_img, p_lossy_quality, true, Image::COMPRESS_SOURCE_GENERIC); + _compress_etc(p_img, p_lossy_quality, true, Image::USED_CHANNELS_RGB); } -static void _compress_etc2(Image *p_img, float p_lossy_quality, Image::CompressSource p_source) { - _compress_etc(p_img, p_lossy_quality, false, p_source); +static void _compress_etc2(Image *p_img, float p_lossy_quality, Image::UsedChannels p_channels) { + _compress_etc(p_img, p_lossy_quality, false, p_channels); } void _register_etc_compress_func() { diff --git a/modules/etc/texture_loader_pkm.cpp b/modules/etc/texture_loader_pkm.cpp index 27c2358306..facdc2e473 100644 --- a/modules/etc/texture_loader_pkm.cpp +++ b/modules/etc/texture_loader_pkm.cpp @@ -103,7 +103,7 @@ void ResourceFormatPKM::get_recognized_extensions(List<String> *p_extensions) co bool ResourceFormatPKM::handles_type(const String &p_type) const { - return ClassDB::is_parent_class(p_type, "Texture"); + return ClassDB::is_parent_class(p_type, "Texture2D"); } String ResourceFormatPKM::get_resource_type(const String &p_path) const { diff --git a/modules/freetype/SCsub b/modules/freetype/SCsub index 8f4a8de895..7b66aa1c76 100644 --- a/modules/freetype/SCsub +++ b/modules/freetype/SCsub @@ -102,5 +102,3 @@ if env['builtin_freetype']: # Godot source files env_freetype.add_source_files(env.modules_sources, "*.cpp") -# Used in scene/, needs to be in main env -env.Append(CPPDEFINES=['FREETYPE_ENABLED']) diff --git a/modules/gdnative/arvr/arvr_interface_gdnative.cpp b/modules/gdnative/arvr/arvr_interface_gdnative.cpp index 5efa915f62..a033c2b7f9 100644 --- a/modules/gdnative/arvr/arvr_interface_gdnative.cpp +++ b/modules/gdnative/arvr/arvr_interface_gdnative.cpp @@ -277,7 +277,9 @@ godot_transform GDAPI godot_arvr_get_reference_frame() { void GDAPI godot_arvr_blit(godot_int p_eye, godot_rid *p_render_target, godot_rect2 *p_rect) { // blits out our texture as is, handy for preview display of one of the eyes that is already rendered with lens distortion on an external HMD ARVRInterface::Eyes eye = (ARVRInterface::Eyes)p_eye; +#if 0 RID *render_target = (RID *)p_render_target; +#endif Rect2 screen_rect = *(Rect2 *)p_rect; if (eye == ARVRInterface::EYE_LEFT) { @@ -286,18 +288,27 @@ void GDAPI godot_arvr_blit(godot_int p_eye, godot_rid *p_render_target, godot_re screen_rect.size.x /= 2.0; screen_rect.position.x += screen_rect.size.x; } - - VSG::rasterizer->set_current_render_target(RID()); +#ifndef _MSC_VER +#warning this needs to be redone +#endif +#if 0 VSG::rasterizer->blit_render_target_to_screen(*render_target, screen_rect, 0); +#endif } godot_int GDAPI godot_arvr_get_texid(godot_rid *p_render_target) { // In order to send off our textures to display on our hardware we need the opengl texture ID instead of the render target RID // This is a handy function to expose that. +#if 0 RID *render_target = (RID *)p_render_target; RID eye_texture = VSG::storage->render_target_get_texture(*render_target); - uint32_t texid = VS::get_singleton()->texture_get_texid(eye_texture); +#endif + +#ifndef _MSC_VER +#warning need to obtain this ID again +#endif + uint32_t texid = 0; //VS::get_singleton()->texture_get_texid(eye_texture); return texid; } diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp index d9dc256ac0..1571b821a5 100644 --- a/modules/gdnative/gdnative.cpp +++ b/modules/gdnative/gdnative.cpp @@ -339,7 +339,7 @@ bool GDNative::initialize() { if (err || !library_init) { OS::get_singleton()->close_dynamic_library(native_handle); native_handle = NULL; - ERR_PRINTS("Failed to obtain " + library->get_symbol_prefix() + "gdnative_init symbol"); + ERR_PRINT("Failed to obtain " + library->get_symbol_prefix() + "gdnative_init symbol"); return false; } diff --git a/modules/gdnative/gdnative/color.cpp b/modules/gdnative/gdnative/color.cpp index 24587ce4a1..914d5b03f4 100644 --- a/modules/gdnative/gdnative/color.cpp +++ b/modules/gdnative/gdnative/color.cpp @@ -141,11 +141,6 @@ godot_int GDAPI godot_color_to_argb32(const godot_color *p_self) { return self->to_argb32(); } -godot_real GDAPI godot_color_gray(const godot_color *p_self) { - const Color *self = (const Color *)p_self; - return self->gray(); -} - godot_color GDAPI godot_color_inverted(const godot_color *p_self) { godot_color dest; const Color *self = (const Color *)p_self; diff --git a/modules/gdnative/gdnative/gdnative.cpp b/modules/gdnative/gdnative/gdnative.cpp index 06334556d9..018a613724 100644 --- a/modules/gdnative/gdnative/gdnative.cpp +++ b/modules/gdnative/gdnative/gdnative.cpp @@ -166,12 +166,8 @@ void _gdnative_report_loading_error(const godot_object *p_library, const char *p _err_print_error("gdnative_init", library->get_current_library_path().utf8().ptr(), 0, message.utf8().ptr()); } -bool GDAPI godot_is_instance_valid(const godot_object *p_object) { - return ObjectDB::instance_validate((Object *)p_object); -} - godot_object GDAPI *godot_instance_from_id(godot_int p_instance_id) { - return (godot_object *)ObjectDB::get_instance((ObjectID)p_instance_id); + return (godot_object *)ObjectDB::get_instance(ObjectID(p_instance_id)); } void *godot_get_class_tag(const godot_string_name *p_class) { diff --git a/modules/gdnative/gdnative/string.cpp b/modules/gdnative/gdnative/string.cpp index 414b9b9eaf..59901f6139 100644 --- a/modules/gdnative/gdnative/string.cpp +++ b/modules/gdnative/gdnative/string.cpp @@ -250,7 +250,12 @@ godot_int GDAPI godot_string_findmk_from_in_place(const godot_string *p_self, co keys.write[i] = (*keys_proxy)[i]; } - return self->findmk(keys, p_from, r_key); + int key; + int ret = self->findmk(keys, p_from, &key); + if (r_key) { + *r_key = key; + } + return ret; } godot_int GDAPI godot_string_findn(const godot_string *p_self, godot_string p_what) { diff --git a/modules/gdnative/gdnative/variant.cpp b/modules/gdnative/gdnative/variant.cpp index 11b6448e34..33b378d9cc 100644 --- a/modules/gdnative/gdnative/variant.cpp +++ b/modules/gdnative/gdnative/variant.cpp @@ -178,7 +178,7 @@ void GDAPI godot_variant_new_object(godot_variant *r_dest, const godot_object *p ref = REF(reference); } if (!ref.is_null()) { - memnew_placement_custom(dest, Variant, Variant(ref.get_ref_ptr())); + memnew_placement_custom(dest, Variant, Variant(ref)); } else { #if defined(DEBUG_METHODS_ENABLED) if (reference) { diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json index 8ccb8d2286..6004b07965 100644 --- a/modules/gdnative/gdnative_api.json +++ b/modules/gdnative/gdnative_api.json @@ -404,13 +404,6 @@ ] }, { - "name": "godot_is_instance_valid", - "return_type": "bool", - "arguments": [ - ["const godot_object *", "p_object"] - ] - }, - { "name": "godot_quat_new_with_basis", "return_type": "void", "arguments": [ @@ -579,13 +572,6 @@ ] }, { - "name": "godot_color_gray", - "return_type": "godot_real", - "arguments": [ - ["const godot_color *", "p_self"] - ] - }, - { "name": "godot_color_inverted", "return_type": "godot_color", "arguments": [ @@ -6482,7 +6468,7 @@ "name": "godot_arvr_blit", "return_type": "void", "arguments": [ - ["int", "p_eye"], + ["godot_int", "p_eye"], ["godot_rid *", "p_render_target"], ["godot_rect2 *", "p_screen_rect"] ] diff --git a/modules/gdnative/include/gdnative/color.h b/modules/gdnative/include/gdnative/color.h index 3f046b7f08..47c01dbb20 100644 --- a/modules/gdnative/include/gdnative/color.h +++ b/modules/gdnative/include/gdnative/color.h @@ -91,8 +91,6 @@ godot_int GDAPI godot_color_to_rgba64(const godot_color *p_self); godot_int GDAPI godot_color_to_argb32(const godot_color *p_self); -godot_real GDAPI godot_color_gray(const godot_color *p_self); - godot_color GDAPI godot_color_inverted(const godot_color *p_self); godot_color GDAPI godot_color_contrasted(const godot_color *p_self); diff --git a/modules/gdnative/include/gdnative/gdnative.h b/modules/gdnative/include/gdnative/gdnative.h index e19a2ec149..6fdca30122 100644 --- a/modules/gdnative/include/gdnative/gdnative.h +++ b/modules/gdnative/include/gdnative/gdnative.h @@ -127,7 +127,7 @@ typedef bool godot_bool; /////// int -typedef int godot_int; +typedef int64_t godot_int; /////// real @@ -282,9 +282,7 @@ void GDAPI godot_print_error(const char *p_description, const char *p_function, void GDAPI godot_print_warning(const char *p_description, const char *p_function, const char *p_file, int p_line); void GDAPI godot_print(const godot_string *p_message); -// GDNATIVE CORE 1.0.1 - -bool GDAPI godot_is_instance_valid(const godot_object *p_object); +// GDNATIVE CORE 1.0.2? //tags used for safe dynamic casting void GDAPI *godot_get_class_tag(const godot_string_name *p_class); diff --git a/modules/gdnative/include/nativescript/godot_nativescript.h b/modules/gdnative/include/nativescript/godot_nativescript.h index d2ed4fb3e5..1b131c8cf0 100644 --- a/modules/gdnative/include/nativescript/godot_nativescript.h +++ b/modules/gdnative/include/nativescript/godot_nativescript.h @@ -42,9 +42,7 @@ typedef enum { GODOT_METHOD_RPC_MODE_REMOTE, GODOT_METHOD_RPC_MODE_MASTER, GODOT_METHOD_RPC_MODE_PUPPET, - GODOT_METHOD_RPC_MODE_SLAVE = GODOT_METHOD_RPC_MODE_PUPPET, GODOT_METHOD_RPC_MODE_REMOTESYNC, - GODOT_METHOD_RPC_MODE_SYNC = GODOT_METHOD_RPC_MODE_REMOTESYNC, GODOT_METHOD_RPC_MODE_MASTERSYNC, GODOT_METHOD_RPC_MODE_PUPPETSYNC, } godot_method_rpc_mode; diff --git a/modules/gdnative/include/pluginscript/godot_pluginscript.h b/modules/gdnative/include/pluginscript/godot_pluginscript.h index e8822fc1ec..210d3f7756 100644 --- a/modules/gdnative/include/pluginscript/godot_pluginscript.h +++ b/modules/gdnative/include/pluginscript/godot_pluginscript.h @@ -44,13 +44,12 @@ typedef void godot_pluginscript_language_data; // --- Instance --- -// TODO: use godot_string_name for faster lookup ? typedef struct { godot_pluginscript_instance_data *(*init)(godot_pluginscript_script_data *p_data, godot_object *p_owner); void (*finish)(godot_pluginscript_instance_data *p_data); - godot_bool (*set_prop)(godot_pluginscript_instance_data *p_data, const godot_string *p_name, const godot_variant *p_value); - godot_bool (*get_prop)(godot_pluginscript_instance_data *p_data, const godot_string *p_name, godot_variant *r_ret); + godot_bool (*set_prop)(godot_pluginscript_instance_data *p_data, const godot_string_name *p_name, const godot_variant *p_value); + godot_bool (*get_prop)(godot_pluginscript_instance_data *p_data, const godot_string_name *p_name, godot_variant *r_ret); godot_variant (*call_method)(godot_pluginscript_instance_data *p_data, const godot_string_name *p_method, const godot_variant **p_args, @@ -136,7 +135,7 @@ typedef struct { godot_error (*complete_code)(godot_pluginscript_language_data *p_data, const godot_string *p_code, const godot_string *p_path, godot_object *p_owner, godot_array *r_options, godot_bool *r_force, godot_string *r_call_hint); void (*auto_indent_code)(godot_pluginscript_language_data *p_data, godot_string *p_code, int p_from_line, int p_to_line); - void (*add_global_constant)(godot_pluginscript_language_data *p_data, const godot_string *p_variable, const godot_variant *p_value); + void (*add_global_constant)(godot_pluginscript_language_data *p_data, const godot_string_name *p_variable, const godot_variant *p_value); godot_string (*debug_get_error)(godot_pluginscript_language_data *p_data); int (*debug_get_stack_level_count)(godot_pluginscript_language_data *p_data); int (*debug_get_stack_level_line)(godot_pluginscript_language_data *p_data, int p_level); diff --git a/modules/gdnative/nativescript/godot_nativescript.cpp b/modules/gdnative/nativescript/godot_nativescript.cpp index e19e675344..f953206a34 100644 --- a/modules/gdnative/nativescript/godot_nativescript.cpp +++ b/modules/gdnative/nativescript/godot_nativescript.cpp @@ -36,6 +36,7 @@ #include "core/project_settings.h" #include "core/variant.h" #include "gdnative/gdnative.h" +#include <stdint.h> #include "nativescript.h" @@ -67,6 +68,14 @@ void GDAPI godot_nativescript_register_class(void *p_gdnative_handle, const char if (classes->has(p_base)) { desc.base_data = &(*classes)[p_base]; desc.base_native_type = desc.base_data->base_native_type; + + const NativeScriptDesc *b = desc.base_data; + while (b) { + desc.rpc_count += b->rpc_count; + desc.rset_count += b->rset_count; + b = b->base_data; + } + } else { desc.base_data = NULL; desc.base_native_type = p_base; @@ -87,10 +96,20 @@ void GDAPI godot_nativescript_register_tool_class(void *p_gdnative_handle, const desc.destroy_func = p_destroy_func; desc.is_tool = true; desc.base = p_base; + desc.rpc_count = 0; + desc.rset_count = 0; if (classes->has(p_base)) { desc.base_data = &(*classes)[p_base]; desc.base_native_type = desc.base_data->base_native_type; + + const NativeScriptDesc *b = desc.base_data; + while (b) { + desc.rpc_count += b->rpc_count; + desc.rset_count += b->rset_count; + b = b->base_data; + } + } else { desc.base_data = NULL; desc.base_native_type = p_base; @@ -109,6 +128,11 @@ void GDAPI godot_nativescript_register_method(void *p_gdnative_handle, const cha NativeScriptDesc::Method method; method.method = p_method; method.rpc_mode = p_attr.rpc_type; + method.rpc_method_id = UINT16_MAX; + if (p_attr.rpc_type != GODOT_METHOD_RPC_MODE_DISABLED) { + method.rpc_method_id = E->get().rpc_count; + E->get().rpc_count += 1; + } method.info = MethodInfo(p_function_name); E->get().methods.insert(p_function_name, method); @@ -125,6 +149,10 @@ void GDAPI godot_nativescript_register_property(void *p_gdnative_handle, const c property.default_value = *(Variant *)&p_attr->default_value; property.getter = p_get_func; property.rset_mode = p_attr->rset_type; + if (p_attr->rset_type != GODOT_METHOD_RPC_MODE_DISABLED) { + property.rset_property_id = E->get().rset_count; + E->get().rset_count += 1; + } property.setter = p_set_func; property.info = PropertyInfo((Variant::Type)p_attr->type, p_path, diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp index 7a5a7bbc3a..df85155ff5 100644 --- a/modules/gdnative/nativescript/nativescript.cpp +++ b/modules/gdnative/nativescript/nativescript.cpp @@ -30,6 +30,8 @@ #include "nativescript.h" +#include <stdint.h> + #include "gdnative/gdnative.h" #include "core/core_string_names.h" @@ -402,6 +404,262 @@ void NativeScript::get_script_property_list(List<PropertyInfo> *p_list) const { } } +Vector<ScriptNetData> NativeScript::get_rpc_methods() const { + + Vector<ScriptNetData> v; + + NativeScriptDesc *script_data = get_script_desc(); + + while (script_data) { + + for (Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.front(); E; E = E->next()) { + if (E->get().rpc_mode != GODOT_METHOD_RPC_MODE_DISABLED) { + ScriptNetData nd; + nd.name = E->key(); + nd.mode = MultiplayerAPI::RPCMode(E->get().rpc_mode); + v.push_back(nd); + } + } + + script_data = script_data->base_data; + } + + return v; +} + +uint16_t NativeScript::get_rpc_method_id(const StringName &p_method) const { + NativeScriptDesc *script_data = get_script_desc(); + + while (script_data) { + + Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.find(p_method); + if (E) { + return E->get().rpc_method_id; + } + + script_data = script_data->base_data; + } + + return UINT16_MAX; +} + +StringName NativeScript::get_rpc_method(uint16_t p_id) const { + ERR_FAIL_COND_V(p_id == UINT16_MAX, StringName()); + + NativeScriptDesc *script_data = get_script_desc(); + + while (script_data) { + + for (Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.front(); E; E = E->next()) { + if (E->get().rpc_method_id == p_id) { + return E->key(); + } + } + + script_data = script_data->base_data; + } + + return StringName(); +} + +MultiplayerAPI::RPCMode NativeScript::get_rpc_mode_by_id(uint16_t p_id) const { + + ERR_FAIL_COND_V(p_id == UINT16_MAX, MultiplayerAPI::RPC_MODE_DISABLED); + + NativeScriptDesc *script_data = get_script_desc(); + + while (script_data) { + + for (Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.front(); E; E = E->next()) { + if (E->get().rpc_method_id == p_id) { + switch (E->get().rpc_mode) { + case GODOT_METHOD_RPC_MODE_DISABLED: + return MultiplayerAPI::RPC_MODE_DISABLED; + case GODOT_METHOD_RPC_MODE_REMOTE: + return MultiplayerAPI::RPC_MODE_REMOTE; + case GODOT_METHOD_RPC_MODE_MASTER: + return MultiplayerAPI::RPC_MODE_MASTER; + case GODOT_METHOD_RPC_MODE_PUPPET: + return MultiplayerAPI::RPC_MODE_PUPPET; + case GODOT_METHOD_RPC_MODE_REMOTESYNC: + return MultiplayerAPI::RPC_MODE_REMOTESYNC; + case GODOT_METHOD_RPC_MODE_MASTERSYNC: + return MultiplayerAPI::RPC_MODE_MASTERSYNC; + case GODOT_METHOD_RPC_MODE_PUPPETSYNC: + return MultiplayerAPI::RPC_MODE_PUPPETSYNC; + default: + return MultiplayerAPI::RPC_MODE_DISABLED; + } + } + } + + script_data = script_data->base_data; + } + + return MultiplayerAPI::RPC_MODE_DISABLED; +} + +MultiplayerAPI::RPCMode NativeScript::get_rpc_mode(const StringName &p_method) const { + + NativeScriptDesc *script_data = get_script_desc(); + + while (script_data) { + + Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.find(p_method); + if (E) { + switch (E->get().rpc_mode) { + case GODOT_METHOD_RPC_MODE_DISABLED: + return MultiplayerAPI::RPC_MODE_DISABLED; + case GODOT_METHOD_RPC_MODE_REMOTE: + return MultiplayerAPI::RPC_MODE_REMOTE; + case GODOT_METHOD_RPC_MODE_MASTER: + return MultiplayerAPI::RPC_MODE_MASTER; + case GODOT_METHOD_RPC_MODE_PUPPET: + return MultiplayerAPI::RPC_MODE_PUPPET; + case GODOT_METHOD_RPC_MODE_REMOTESYNC: + return MultiplayerAPI::RPC_MODE_REMOTESYNC; + case GODOT_METHOD_RPC_MODE_MASTERSYNC: + return MultiplayerAPI::RPC_MODE_MASTERSYNC; + case GODOT_METHOD_RPC_MODE_PUPPETSYNC: + return MultiplayerAPI::RPC_MODE_PUPPETSYNC; + default: + return MultiplayerAPI::RPC_MODE_DISABLED; + } + } + + script_data = script_data->base_data; + } + + return MultiplayerAPI::RPC_MODE_DISABLED; +} + +Vector<ScriptNetData> NativeScript::get_rset_properties() const { + Vector<ScriptNetData> v; + + NativeScriptDesc *script_data = get_script_desc(); + + while (script_data) { + + for (OrderedHashMap<StringName, NativeScriptDesc::Property>::Element E = script_data->properties.front(); E; E = E.next()) { + if (E.get().rset_mode != GODOT_METHOD_RPC_MODE_DISABLED) { + ScriptNetData nd; + nd.name = E.key(); + nd.mode = MultiplayerAPI::RPCMode(E.get().rset_mode); + v.push_back(nd); + } + } + script_data = script_data->base_data; + } + + return v; +} + +uint16_t NativeScript::get_rset_property_id(const StringName &p_variable) const { + NativeScriptDesc *script_data = get_script_desc(); + + while (script_data) { + + OrderedHashMap<StringName, NativeScriptDesc::Property>::Element E = script_data->properties.find(p_variable); + if (E) { + return E.get().rset_property_id; + } + + script_data = script_data->base_data; + } + + return UINT16_MAX; +} + +StringName NativeScript::get_rset_property(uint16_t p_id) const { + ERR_FAIL_COND_V(p_id == UINT16_MAX, StringName()); + + NativeScriptDesc *script_data = get_script_desc(); + + while (script_data) { + + for (OrderedHashMap<StringName, NativeScriptDesc::Property>::Element E = script_data->properties.front(); E; E = E.next()) { + if (E.get().rset_property_id == p_id) { + return E.key(); + } + } + + script_data = script_data->base_data; + } + + return StringName(); +} + +MultiplayerAPI::RPCMode NativeScript::get_rset_mode_by_id(uint16_t p_id) const { + + ERR_FAIL_COND_V(p_id == UINT16_MAX, MultiplayerAPI::RPC_MODE_DISABLED); + + NativeScriptDesc *script_data = get_script_desc(); + + while (script_data) { + + for (OrderedHashMap<StringName, NativeScriptDesc::Property>::Element E = script_data->properties.front(); E; E = E.next()) { + if (E.get().rset_property_id == p_id) { + switch (E.get().rset_mode) { + case GODOT_METHOD_RPC_MODE_DISABLED: + return MultiplayerAPI::RPC_MODE_DISABLED; + case GODOT_METHOD_RPC_MODE_REMOTE: + return MultiplayerAPI::RPC_MODE_REMOTE; + case GODOT_METHOD_RPC_MODE_MASTER: + return MultiplayerAPI::RPC_MODE_MASTER; + case GODOT_METHOD_RPC_MODE_PUPPET: + return MultiplayerAPI::RPC_MODE_PUPPET; + case GODOT_METHOD_RPC_MODE_REMOTESYNC: + return MultiplayerAPI::RPC_MODE_REMOTESYNC; + case GODOT_METHOD_RPC_MODE_MASTERSYNC: + return MultiplayerAPI::RPC_MODE_MASTERSYNC; + case GODOT_METHOD_RPC_MODE_PUPPETSYNC: + return MultiplayerAPI::RPC_MODE_PUPPETSYNC; + default: + return MultiplayerAPI::RPC_MODE_DISABLED; + } + } + } + + script_data = script_data->base_data; + } + + return MultiplayerAPI::RPC_MODE_DISABLED; +} + +MultiplayerAPI::RPCMode NativeScript::get_rset_mode(const StringName &p_variable) const { + + NativeScriptDesc *script_data = get_script_desc(); + + while (script_data) { + + OrderedHashMap<StringName, NativeScriptDesc::Property>::Element E = script_data->properties.find(p_variable); + if (E) { + switch (E.get().rset_mode) { + case GODOT_METHOD_RPC_MODE_DISABLED: + return MultiplayerAPI::RPC_MODE_DISABLED; + case GODOT_METHOD_RPC_MODE_REMOTE: + return MultiplayerAPI::RPC_MODE_REMOTE; + case GODOT_METHOD_RPC_MODE_MASTER: + return MultiplayerAPI::RPC_MODE_MASTER; + case GODOT_METHOD_RPC_MODE_PUPPET: + return MultiplayerAPI::RPC_MODE_PUPPET; + case GODOT_METHOD_RPC_MODE_REMOTESYNC: + return MultiplayerAPI::RPC_MODE_REMOTESYNC; + case GODOT_METHOD_RPC_MODE_MASTERSYNC: + return MultiplayerAPI::RPC_MODE_MASTERSYNC; + case GODOT_METHOD_RPC_MODE_PUPPETSYNC: + return MultiplayerAPI::RPC_MODE_PUPPETSYNC; + default: + return MultiplayerAPI::RPC_MODE_DISABLED; + } + } + + script_data = script_data->base_data; + } + + return MultiplayerAPI::RPC_MODE_DISABLED; +} + String NativeScript::get_class_documentation() const { NativeScriptDesc *script_data = get_script_desc(); @@ -746,7 +1004,7 @@ void NativeScriptInstance::notification(int p_notification) { #ifdef DEBUG_ENABLED if (p_notification == MainLoop::NOTIFICATION_CRASH) { if (current_method_call != StringName("")) { - ERR_PRINTS("NativeScriptInstance detected crash on method: " + current_method_call); + ERR_PRINT("NativeScriptInstance detected crash on method: " + current_method_call); current_method_call = ""; } } @@ -803,72 +1061,44 @@ Ref<Script> NativeScriptInstance::get_script() const { return script; } -MultiplayerAPI::RPCMode NativeScriptInstance::get_rpc_mode(const StringName &p_method) const { - - NativeScriptDesc *script_data = GET_SCRIPT_DESC(); - - while (script_data) { +Vector<ScriptNetData> NativeScriptInstance::get_rpc_methods() const { + return script->get_rpc_methods(); +} - Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.find(p_method); - if (E) { - switch (E->get().rpc_mode) { - case GODOT_METHOD_RPC_MODE_DISABLED: - return MultiplayerAPI::RPC_MODE_DISABLED; - case GODOT_METHOD_RPC_MODE_REMOTE: - return MultiplayerAPI::RPC_MODE_REMOTE; - case GODOT_METHOD_RPC_MODE_MASTER: - return MultiplayerAPI::RPC_MODE_MASTER; - case GODOT_METHOD_RPC_MODE_PUPPET: - return MultiplayerAPI::RPC_MODE_PUPPET; - case GODOT_METHOD_RPC_MODE_REMOTESYNC: - return MultiplayerAPI::RPC_MODE_REMOTESYNC; - case GODOT_METHOD_RPC_MODE_MASTERSYNC: - return MultiplayerAPI::RPC_MODE_MASTERSYNC; - case GODOT_METHOD_RPC_MODE_PUPPETSYNC: - return MultiplayerAPI::RPC_MODE_PUPPETSYNC; - default: - return MultiplayerAPI::RPC_MODE_DISABLED; - } - } +uint16_t NativeScriptInstance::get_rpc_method_id(const StringName &p_method) const { + return script->get_rpc_method_id(p_method); +} - script_data = script_data->base_data; - } +StringName NativeScriptInstance::get_rpc_method(uint16_t p_id) const { + return script->get_rpc_method(p_id); +} - return MultiplayerAPI::RPC_MODE_DISABLED; +MultiplayerAPI::RPCMode NativeScriptInstance::get_rpc_mode_by_id(uint16_t p_id) const { + return script->get_rpc_mode_by_id(p_id); } -MultiplayerAPI::RPCMode NativeScriptInstance::get_rset_mode(const StringName &p_variable) const { +MultiplayerAPI::RPCMode NativeScriptInstance::get_rpc_mode(const StringName &p_method) const { + return script->get_rpc_mode(p_method); +} - NativeScriptDesc *script_data = GET_SCRIPT_DESC(); +Vector<ScriptNetData> NativeScriptInstance::get_rset_properties() const { + return script->get_rset_properties(); +} - while (script_data) { +uint16_t NativeScriptInstance::get_rset_property_id(const StringName &p_variable) const { + return script->get_rset_property_id(p_variable); +} - OrderedHashMap<StringName, NativeScriptDesc::Property>::Element E = script_data->properties.find(p_variable); - if (E) { - switch (E.get().rset_mode) { - case GODOT_METHOD_RPC_MODE_DISABLED: - return MultiplayerAPI::RPC_MODE_DISABLED; - case GODOT_METHOD_RPC_MODE_REMOTE: - return MultiplayerAPI::RPC_MODE_REMOTE; - case GODOT_METHOD_RPC_MODE_MASTER: - return MultiplayerAPI::RPC_MODE_MASTER; - case GODOT_METHOD_RPC_MODE_PUPPET: - return MultiplayerAPI::RPC_MODE_PUPPET; - case GODOT_METHOD_RPC_MODE_REMOTESYNC: - return MultiplayerAPI::RPC_MODE_REMOTESYNC; - case GODOT_METHOD_RPC_MODE_MASTERSYNC: - return MultiplayerAPI::RPC_MODE_MASTERSYNC; - case GODOT_METHOD_RPC_MODE_PUPPETSYNC: - return MultiplayerAPI::RPC_MODE_PUPPETSYNC; - default: - return MultiplayerAPI::RPC_MODE_DISABLED; - } - } +StringName NativeScriptInstance::get_rset_property(uint16_t p_id) const { + return script->get_rset_property(p_id); +} - script_data = script_data->base_data; - } +MultiplayerAPI::RPCMode NativeScriptInstance::get_rset_mode_by_id(uint16_t p_id) const { + return script->get_rset_mode_by_id(p_id); +} - return MultiplayerAPI::RPC_MODE_DISABLED; +MultiplayerAPI::RPCMode NativeScriptInstance::get_rset_mode(const StringName &p_variable) const { + return script->get_rset_mode(p_variable); } ScriptLanguage *NativeScriptInstance::get_language() { diff --git a/modules/gdnative/nativescript/nativescript.h b/modules/gdnative/nativescript/nativescript.h index cf787e1f6a..2ff08e32cd 100644 --- a/modules/gdnative/nativescript/nativescript.h +++ b/modules/gdnative/nativescript/nativescript.h @@ -54,6 +54,7 @@ struct NativeScriptDesc { godot_instance_method method; MethodInfo info; int rpc_mode; + uint16_t rpc_method_id; String documentation; }; struct Property { @@ -62,6 +63,7 @@ struct NativeScriptDesc { PropertyInfo info; Variant default_value; int rset_mode; + uint16_t rset_property_id; String documentation; }; @@ -70,7 +72,9 @@ struct NativeScriptDesc { String documentation; }; + uint16_t rpc_count; Map<StringName, Method> methods; + uint16_t rset_count; OrderedHashMap<StringName, Property> properties; Map<StringName, Signal> signals_; // QtCreator doesn't like the name signals StringName base; @@ -86,7 +90,9 @@ struct NativeScriptDesc { bool is_tool; inline NativeScriptDesc() : + rpc_count(0), methods(), + rset_count(0), properties(), signals_(), base(), @@ -174,6 +180,18 @@ public: virtual void get_script_method_list(List<MethodInfo> *p_list) const; virtual void get_script_property_list(List<PropertyInfo> *p_list) const; + virtual Vector<ScriptNetData> get_rpc_methods() const; + virtual uint16_t get_rpc_method_id(const StringName &p_method) const; + virtual StringName get_rpc_method(uint16_t p_id) const; + virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(uint16_t p_id) const; + virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const; + + virtual Vector<ScriptNetData> get_rset_properties() const; + virtual uint16_t get_rset_property_id(const StringName &p_variable) const; + virtual StringName get_rset_property(uint16_t p_id) const; + virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(uint16_t p_id) const; + virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const; + String get_class_documentation() const; String get_method_documentation(const StringName &p_method) const; String get_signal_documentation(const StringName &p_signal_name) const; @@ -210,8 +228,19 @@ public: virtual void notification(int p_notification); String to_string(bool *r_valid); virtual Ref<Script> get_script() const; + + virtual Vector<ScriptNetData> get_rpc_methods() const; + virtual uint16_t get_rpc_method_id(const StringName &p_method) const; + virtual StringName get_rpc_method(uint16_t p_id) const; + virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(uint16_t p_id) const; virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const; + + virtual Vector<ScriptNetData> get_rset_properties() const; + virtual uint16_t get_rset_property_id(const StringName &p_variable) const; + virtual StringName get_rset_property(uint16_t p_id) const; + virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(uint16_t p_id) const; virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const; + virtual ScriptLanguage *get_language(); virtual void call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount); diff --git a/modules/gdnative/pluginscript/pluginscript_instance.cpp b/modules/gdnative/pluginscript/pluginscript_instance.cpp index c64a00a4d9..26a1d5f47a 100644 --- a/modules/gdnative/pluginscript/pluginscript_instance.cpp +++ b/modules/gdnative/pluginscript/pluginscript_instance.cpp @@ -39,13 +39,11 @@ #include "pluginscript_script.h" bool PluginScriptInstance::set(const StringName &p_name, const Variant &p_value) { - String name = String(p_name); - return _desc->set_prop(_data, (const godot_string *)&name, (const godot_variant *)&p_value); + return _desc->set_prop(_data, (const godot_string_name *)&p_name, (const godot_variant *)&p_value); } bool PluginScriptInstance::get(const StringName &p_name, Variant &r_ret) const { - String name = String(p_name); - return _desc->get_prop(_data, (const godot_string *)&name, (godot_variant *)&r_ret); + return _desc->get_prop(_data, (const godot_string_name *)&p_name, (godot_variant *)&r_ret); } Ref<Script> PluginScriptInstance::get_script() const { @@ -95,10 +93,42 @@ void PluginScriptInstance::notification(int p_notification) { _desc->notification(_data, p_notification); } +Vector<ScriptNetData> PluginScriptInstance::get_rpc_methods() const { + return _script->get_rpc_methods(); +} + +uint16_t PluginScriptInstance::get_rpc_method_id(const StringName &p_variable) const { + return _script->get_rpc_method_id(p_variable); +} + +StringName PluginScriptInstance::get_rpc_method(uint16_t p_id) const { + return _script->get_rpc_method(p_id); +} + +MultiplayerAPI::RPCMode PluginScriptInstance::get_rpc_mode_by_id(uint16_t p_id) const { + return _script->get_rpc_mode_by_id(p_id); +} + MultiplayerAPI::RPCMode PluginScriptInstance::get_rpc_mode(const StringName &p_method) const { return _script->get_rpc_mode(p_method); } +Vector<ScriptNetData> PluginScriptInstance::get_rset_properties() const { + return _script->get_rset_properties(); +} + +uint16_t PluginScriptInstance::get_rset_property_id(const StringName &p_variable) const { + return _script->get_rset_property_id(p_variable); +} + +StringName PluginScriptInstance::get_rset_property(uint16_t p_id) const { + return _script->get_rset_property(p_id); +} + +MultiplayerAPI::RPCMode PluginScriptInstance::get_rset_mode_by_id(uint16_t p_id) const { + return _script->get_rset_mode_by_id(p_id); +} + MultiplayerAPI::RPCMode PluginScriptInstance::get_rset_mode(const StringName &p_variable) const { return _script->get_rset_mode(p_variable); } diff --git a/modules/gdnative/pluginscript/pluginscript_instance.h b/modules/gdnative/pluginscript/pluginscript_instance.h index dc1229a44d..154bebd72a 100644 --- a/modules/gdnative/pluginscript/pluginscript_instance.h +++ b/modules/gdnative/pluginscript/pluginscript_instance.h @@ -76,7 +76,16 @@ public: void set_path(const String &p_path); + virtual Vector<ScriptNetData> get_rpc_methods() const; + virtual uint16_t get_rpc_method_id(const StringName &p_method) const; + virtual StringName get_rpc_method(uint16_t p_id) const; + virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(uint16_t p_id) const; virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const; + + virtual Vector<ScriptNetData> get_rset_properties() const; + virtual uint16_t get_rset_property_id(const StringName &p_variable) const; + virtual StringName get_rset_property(uint16_t p_id) const; + virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(uint16_t p_id) const; virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const; virtual void refcount_incremented(); diff --git a/modules/gdnative/pluginscript/pluginscript_language.cpp b/modules/gdnative/pluginscript/pluginscript_language.cpp index 41f0e34243..421d6e0a89 100644 --- a/modules/gdnative/pluginscript/pluginscript_language.cpp +++ b/modules/gdnative/pluginscript/pluginscript_language.cpp @@ -187,8 +187,7 @@ void PluginScriptLanguage::auto_indent_code(String &p_code, int p_from_line, int } void PluginScriptLanguage::add_global_constant(const StringName &p_variable, const Variant &p_value) { - const String variable = String(p_variable); - _desc.add_global_constant(_data, (godot_string *)&variable, (godot_variant *)&p_value); + _desc.add_global_constant(_data, (godot_string_name *)&p_variable, (godot_variant *)&p_value); } /* LOADER FUNCTIONS */ diff --git a/modules/gdnative/pluginscript/pluginscript_script.cpp b/modules/gdnative/pluginscript/pluginscript_script.cpp index cc5bdee0a1..c370062262 100644 --- a/modules/gdnative/pluginscript/pluginscript_script.cpp +++ b/modules/gdnative/pluginscript/pluginscript_script.cpp @@ -34,6 +34,8 @@ #include "pluginscript_instance.h" #include "pluginscript_script.h" +#include <stdint.h> + #ifdef DEBUG_ENABLED #define __ASSERT_SCRIPT_REASON "Cannot retrieve PluginScript class for this script, is your code correct?" #define ASSERT_SCRIPT_VALID() \ @@ -298,18 +300,31 @@ Error PluginScript::reload(bool p_keep_state) { _member_lines[*key] = (*members)[*key]; } Array *methods = (Array *)&manifest.methods; + _rpc_methods.clear(); + _rpc_variables.clear(); + if (_ref_base_parent.is_valid()) { + _rpc_methods = _ref_base_parent->get_rpc_methods(); + _rpc_variables = _ref_base_parent->get_rset_properties(); + } for (int i = 0; i < methods->size(); ++i) { Dictionary v = (*methods)[i]; MethodInfo mi = MethodInfo::from_dict(v); _methods_info[mi.name] = mi; // rpc_mode is passed as an optional field and is not part of MethodInfo Variant var = v["rpc_mode"]; - if (var == Variant()) { - _methods_rpc_mode[mi.name] = MultiplayerAPI::RPC_MODE_DISABLED; - } else { - _methods_rpc_mode[mi.name] = MultiplayerAPI::RPCMode(int(var)); + if (var != Variant()) { + ScriptNetData nd; + nd.name = mi.name; + nd.mode = MultiplayerAPI::RPCMode(int(var)); + if (_rpc_methods.find(nd) == -1) { + _rpc_methods.push_back(nd); + } } } + + // Sort so we are 100% that they are always the same. + _rpc_methods.sort_custom<SortNetData>(); + Array *signals = (Array *)&manifest.signals; for (int i = 0; i < signals->size(); ++i) { Variant v = (*signals)[i]; @@ -324,13 +339,19 @@ Error PluginScript::reload(bool p_keep_state) { _properties_default_values[pi.name] = v["default_value"]; // rset_mode is passed as an optional field and is not part of PropertyInfo Variant var = v["rset_mode"]; - if (var == Variant()) { - _methods_rpc_mode[pi.name] = MultiplayerAPI::RPC_MODE_DISABLED; - } else { - _methods_rpc_mode[pi.name] = MultiplayerAPI::RPCMode(int(var)); + if (var != Variant()) { + ScriptNetData nd; + nd.name = pi.name; + nd.mode = MultiplayerAPI::RPCMode(int(var)); + if (_rpc_variables.find(nd) == -1) { + _rpc_variables.push_back(nd); + } } } + // Sort so we are 100% that they are always the same. + _rpc_variables.sort_custom<SortNetData>(); + #ifdef TOOLS_ENABLED /*for (Set<PlaceHolderScriptInstance*>::Element *E=placeholders.front();E;E=E->next()) { @@ -455,24 +476,70 @@ int PluginScript::get_member_line(const StringName &p_member) const { return -1; } -MultiplayerAPI::RPCMode PluginScript::get_rpc_mode(const StringName &p_method) const { +Vector<ScriptNetData> PluginScript::get_rpc_methods() const { + return _rpc_methods; +} + +uint16_t PluginScript::get_rpc_method_id(const StringName &p_method) const { + ASSERT_SCRIPT_VALID_V(UINT16_MAX); + for (int i = 0; i < _rpc_methods.size(); i++) { + if (_rpc_methods[i].name == p_method) { + return i; + } + } + return UINT16_MAX; +} + +StringName PluginScript::get_rpc_method(const uint16_t p_rpc_method_id) const { + ASSERT_SCRIPT_VALID_V(StringName()); + if (p_rpc_method_id >= _rpc_methods.size()) + return StringName(); + return _rpc_methods[p_rpc_method_id].name; +} + +MultiplayerAPI::RPCMode PluginScript::get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const { ASSERT_SCRIPT_VALID_V(MultiplayerAPI::RPC_MODE_DISABLED); - const Map<StringName, MultiplayerAPI::RPCMode>::Element *e = _methods_rpc_mode.find(p_method); - if (e != NULL) { - return e->get(); - } else { + if (p_rpc_method_id >= _rpc_methods.size()) return MultiplayerAPI::RPC_MODE_DISABLED; + return _rpc_methods[p_rpc_method_id].mode; +} + +MultiplayerAPI::RPCMode PluginScript::get_rpc_mode(const StringName &p_method) const { + ASSERT_SCRIPT_VALID_V(MultiplayerAPI::RPC_MODE_DISABLED); + return get_rpc_mode_by_id(get_rpc_method_id(p_method)); +} + +Vector<ScriptNetData> PluginScript::get_rset_properties() const { + return _rpc_variables; +} + +uint16_t PluginScript::get_rset_property_id(const StringName &p_property) const { + ASSERT_SCRIPT_VALID_V(UINT16_MAX); + for (int i = 0; i < _rpc_variables.size(); i++) { + if (_rpc_variables[i].name == p_property) { + return i; + } } + return UINT16_MAX; } -MultiplayerAPI::RPCMode PluginScript::get_rset_mode(const StringName &p_variable) const { +StringName PluginScript::get_rset_property(const uint16_t p_rset_property_id) const { + ASSERT_SCRIPT_VALID_V(StringName()); + if (p_rset_property_id >= _rpc_variables.size()) + return StringName(); + return _rpc_variables[p_rset_property_id].name; +} + +MultiplayerAPI::RPCMode PluginScript::get_rset_mode_by_id(const uint16_t p_rset_property_id) const { ASSERT_SCRIPT_VALID_V(MultiplayerAPI::RPC_MODE_DISABLED); - const Map<StringName, MultiplayerAPI::RPCMode>::Element *e = _variables_rset_mode.find(p_variable); - if (e != NULL) { - return e->get(); - } else { + if (p_rset_property_id >= _rpc_variables.size()) return MultiplayerAPI::RPC_MODE_DISABLED; - } + return _rpc_variables[p_rset_property_id].mode; +} + +MultiplayerAPI::RPCMode PluginScript::get_rset_mode(const StringName &p_variable) const { + ASSERT_SCRIPT_VALID_V(MultiplayerAPI::RPC_MODE_DISABLED); + return get_rset_mode_by_id(get_rset_property_id(p_variable)); } PluginScript::PluginScript() : diff --git a/modules/gdnative/pluginscript/pluginscript_script.h b/modules/gdnative/pluginscript/pluginscript_script.h index f67c88c794..f6bca8a9cb 100644 --- a/modules/gdnative/pluginscript/pluginscript_script.h +++ b/modules/gdnative/pluginscript/pluginscript_script.h @@ -60,8 +60,8 @@ private: Map<StringName, PropertyInfo> _properties_info; Map<StringName, MethodInfo> _signals_info; Map<StringName, MethodInfo> _methods_info; - Map<StringName, MultiplayerAPI::RPCMode> _variables_rset_mode; - Map<StringName, MultiplayerAPI::RPCMode> _methods_rpc_mode; + Vector<ScriptNetData> _rpc_methods; + Vector<ScriptNetData> _rpc_variables; Set<Object *> _instances; //exported members @@ -118,8 +118,17 @@ public: virtual int get_member_line(const StringName &p_member) const; - MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const; - MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const; + virtual Vector<ScriptNetData> get_rpc_methods() const; + virtual uint16_t get_rpc_method_id(const StringName &p_method) const; + virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const; + virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const; + virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const; + + virtual Vector<ScriptNetData> get_rset_properties() const; + virtual uint16_t get_rset_property_id(const StringName &p_property) const; + virtual StringName get_rset_property(const uint16_t p_rset_property_id) const; + virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_rpc_method_id) const; + virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const; PluginScript(); void init(PluginScriptLanguage *language); diff --git a/modules/gdnative/register_types.cpp b/modules/gdnative/register_types.cpp index cb84c23e7a..4142f60ba6 100644 --- a/modules/gdnative/register_types.cpp +++ b/modules/gdnative/register_types.cpp @@ -278,7 +278,7 @@ void register_gdnative_types() { proc_ptr); if (err != OK) { - ERR_PRINTS("No " + lib->get_symbol_prefix() + "gdnative_singleton in \"" + singleton->get_library()->get_current_library_path() + "\" found"); + ERR_PRINT("No " + lib->get_symbol_prefix() + "gdnative_singleton in \"" + singleton->get_library()->get_current_library_path() + "\" found"); } else { singleton_gdnatives.push_back(singleton); ((void (*)())proc_ptr)(); diff --git a/modules/gdnative/videodecoder/video_stream_gdnative.cpp b/modules/gdnative/videodecoder/video_stream_gdnative.cpp index dbe00cdf71..8dcafc1987 100644 --- a/modules/gdnative/videodecoder/video_stream_gdnative.cpp +++ b/modules/gdnative/videodecoder/video_stream_gdnative.cpp @@ -132,7 +132,11 @@ bool VideoStreamPlaybackGDNative::open_file(const String &p_file) { pcm_write_idx = -1; samples_decoded = 0; - texture->create((int)texture_size.width, (int)texture_size.height, Image::FORMAT_RGBA8, Texture::FLAG_FILTER | Texture::FLAG_VIDEO_SURFACE); + Ref<Image> img; + img.instance(); + img->create((int)texture_size.width, false, (int)texture_size.height, Image::FORMAT_RGBA8); + + texture->create_from_image(img); } return file_opened; @@ -192,7 +196,7 @@ void VideoStreamPlaybackGDNative::update_texture() { Ref<Image> img = memnew(Image(texture_size.width, texture_size.height, 0, Image::FORMAT_RGBA8, *pba)); - texture->set_data(img); + texture->update(img, true); } // ctor and dtor @@ -283,7 +287,7 @@ void VideoStreamPlaybackGDNative::set_paused(bool p_paused) { paused = p_paused; } -Ref<Texture> VideoStreamPlaybackGDNative::get_texture() const { +Ref<Texture2D> VideoStreamPlaybackGDNative::get_texture() const { return texture; } diff --git a/modules/gdnative/videodecoder/video_stream_gdnative.h b/modules/gdnative/videodecoder/video_stream_gdnative.h index bb0346efb4..024cdec196 100644 --- a/modules/gdnative/videodecoder/video_stream_gdnative.h +++ b/modules/gdnative/videodecoder/video_stream_gdnative.h @@ -168,7 +168,7 @@ public: //virtual int mix(int16_t* p_buffer,int p_frames)=0; - virtual Ref<Texture> get_texture() const; + virtual Ref<Texture2D> get_texture() const; virtual void update(float p_delta); virtual void set_mix_callback(AudioMixCallback p_callback, void *p_userdata); diff --git a/modules/gdnavigation/SCsub b/modules/gdnavigation/SCsub new file mode 100644 index 0000000000..9d462f92a7 --- /dev/null +++ b/modules/gdnavigation/SCsub @@ -0,0 +1,50 @@ +#!/usr/bin/env python + +Import('env') +Import('env_modules') + +env_navigation = env_modules.Clone() + +# Recast Thirdparty source files +if env['builtin_recast']: + thirdparty_dir = "#thirdparty/recastnavigation/Recast/" + thirdparty_sources = [ + "Source/Recast.cpp", + "Source/RecastAlloc.cpp", + "Source/RecastArea.cpp", + "Source/RecastAssert.cpp", + "Source/RecastContour.cpp", + "Source/RecastFilter.cpp", + "Source/RecastLayers.cpp", + "Source/RecastMesh.cpp", + "Source/RecastMeshDetail.cpp", + "Source/RecastRasterization.cpp", + "Source/RecastRegion.cpp", + ] + thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] + + env_navigation.Prepend(CPPPATH=[thirdparty_dir + "/Include"]) + + env_thirdparty = env_navigation.Clone() + env_thirdparty.disable_warnings() + env_thirdparty.add_source_files(env.modules_sources, thirdparty_sources) + + +# RVO Thirdparty source files +if env['builtin_rvo2']: + thirdparty_dir = "#thirdparty/rvo2" + thirdparty_sources = [ + "/src/Agent.cpp", + "/src/KdTree.cpp", + ] + thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] + + env_navigation.Prepend(CPPPATH=[thirdparty_dir + "/src"]) + + env_thirdparty = env_navigation.Clone() + env_thirdparty.disable_warnings() + env_thirdparty.add_source_files(env.modules_sources, thirdparty_sources) + + +# Godot source files +env_navigation.add_source_files(env.modules_sources, "*.cpp") diff --git a/modules/gdnavigation/config.py b/modules/gdnavigation/config.py new file mode 100644 index 0000000000..1c8cd12a2d --- /dev/null +++ b/modules/gdnavigation/config.py @@ -0,0 +1,5 @@ +def can_build(env, platform): + return True + +def configure(env): + pass diff --git a/modules/gdnavigation/gd_navigation_server.cpp b/modules/gdnavigation/gd_navigation_server.cpp new file mode 100644 index 0000000000..5bafa5507c --- /dev/null +++ b/modules/gdnavigation/gd_navigation_server.cpp @@ -0,0 +1,475 @@ +/*************************************************************************/ +/* gd_navigation_server.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 "gd_navigation_server.h" + +#include "core/os/mutex.h" + +#ifndef _3D_DISABLED +#include "navigation_mesh_generator.h" +#endif + +/** + @author AndreaCatania +*/ + +/// Creates a struct for each function and a function that once called creates +/// an instance of that struct with the submited parameters. +/// Then, that struct is stored in an array; the `sync` function consume that array. + +#define COMMAND_1(F_NAME, T_0, D_0) \ + struct MERGE(F_NAME, _command) : public SetCommand { \ + T_0 d_0; \ + MERGE(F_NAME, _command) \ + (T_0 p_d_0) : \ + d_0(p_d_0) {} \ + virtual void exec(GdNavigationServer *server) { \ + server->MERGE(_cmd_, F_NAME)(d_0); \ + } \ + }; \ + void GdNavigationServer::F_NAME(T_0 D_0) const { \ + auto cmd = memnew(MERGE(F_NAME, _command)( \ + D_0)); \ + add_command(cmd); \ + } \ + void GdNavigationServer::MERGE(_cmd_, F_NAME)(T_0 D_0) + +#define COMMAND_2(F_NAME, T_0, D_0, T_1, D_1) \ + struct MERGE(F_NAME, _command) : public SetCommand { \ + T_0 d_0; \ + T_1 d_1; \ + MERGE(F_NAME, _command) \ + ( \ + T_0 p_d_0, \ + T_1 p_d_1) : \ + d_0(p_d_0), \ + d_1(p_d_1) {} \ + virtual void exec(GdNavigationServer *server) { \ + server->MERGE(_cmd_, F_NAME)(d_0, d_1); \ + } \ + }; \ + void GdNavigationServer::F_NAME(T_0 D_0, T_1 D_1) const { \ + auto cmd = memnew(MERGE(F_NAME, _command)( \ + D_0, \ + D_1)); \ + add_command(cmd); \ + } \ + void GdNavigationServer::MERGE(_cmd_, F_NAME)(T_0 D_0, T_1 D_1) + +#define COMMAND_4(F_NAME, T_0, D_0, T_1, D_1, T_2, D_2, T_3, D_3) \ + struct MERGE(F_NAME, _command) : public SetCommand { \ + T_0 d_0; \ + T_1 d_1; \ + T_2 d_2; \ + T_3 d_3; \ + MERGE(F_NAME, _command) \ + ( \ + T_0 p_d_0, \ + T_1 p_d_1, \ + T_2 p_d_2, \ + T_3 p_d_3) : \ + d_0(p_d_0), \ + d_1(p_d_1), \ + d_2(p_d_2), \ + d_3(p_d_3) {} \ + virtual void exec(GdNavigationServer *server) { \ + server->MERGE(_cmd_, F_NAME)(d_0, d_1, d_2, d_3); \ + } \ + }; \ + void GdNavigationServer::F_NAME(T_0 D_0, T_1 D_1, T_2 D_2, T_3 D_3) const { \ + auto cmd = memnew(MERGE(F_NAME, _command)( \ + D_0, \ + D_1, \ + D_2, \ + D_3)); \ + add_command(cmd); \ + } \ + void GdNavigationServer::MERGE(_cmd_, F_NAME)(T_0 D_0, T_1 D_1, T_2 D_2, T_3 D_3) + +GdNavigationServer::GdNavigationServer() : + NavigationServer(), + commands_mutex(Mutex::create()), + operations_mutex(Mutex::create()), + active(true) { +} + +GdNavigationServer::~GdNavigationServer() { + 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(); +} + +RID GdNavigationServer::map_create() const { + auto mut_this = const_cast<GdNavigationServer *>(this); + mut_this->operations_mutex->lock(); + NavMap *space = memnew(NavMap); + RID rid = map_owner.make_rid(space); + space->set_self(rid); + mut_this->operations_mutex->unlock(); + return rid; +} + +COMMAND_2(map_set_active, RID, p_map, bool, p_active) { + NavMap *map = map_owner.getornull(p_map); + ERR_FAIL_COND(map == NULL); + + if (p_active) { + if (!map_is_active(p_map)) { + active_maps.push_back(map); + } + } else { + active_maps.erase(map); + } +} + +bool GdNavigationServer::map_is_active(RID p_map) const { + NavMap *map = map_owner.getornull(p_map); + ERR_FAIL_COND_V(map == NULL, false); + + return active_maps.find(map) >= 0; +} + +COMMAND_2(map_set_up, RID, p_map, Vector3, p_up) { + NavMap *map = map_owner.getornull(p_map); + ERR_FAIL_COND(map == NULL); + + map->set_up(p_up); +} + +Vector3 GdNavigationServer::map_get_up(RID p_map) const { + NavMap *map = map_owner.getornull(p_map); + ERR_FAIL_COND_V(map == NULL, Vector3()); + + return map->get_up(); +} + +COMMAND_2(map_set_cell_size, RID, p_map, real_t, p_cell_size) { + NavMap *map = map_owner.getornull(p_map); + ERR_FAIL_COND(map == NULL); + + map->set_cell_size(p_cell_size); +} + +real_t GdNavigationServer::map_get_cell_size(RID p_map) const { + NavMap *map = map_owner.getornull(p_map); + ERR_FAIL_COND_V(map == NULL, 0); + + return map->get_cell_size(); +} + +COMMAND_2(map_set_edge_connection_margin, RID, p_map, real_t, p_connection_margin) { + NavMap *map = map_owner.getornull(p_map); + ERR_FAIL_COND(map == NULL); + + map->set_edge_connection_margin(p_connection_margin); +} + +real_t GdNavigationServer::map_get_edge_connection_margin(RID p_map) const { + NavMap *map = map_owner.getornull(p_map); + ERR_FAIL_COND_V(map == NULL, 0); + + return map->get_edge_connection_margin(); +} + +Vector<Vector3> GdNavigationServer::map_get_path(RID p_map, Vector3 p_origin, Vector3 p_destination, bool p_optimize) const { + NavMap *map = map_owner.getornull(p_map); + ERR_FAIL_COND_V(map == NULL, Vector<Vector3>()); + + return map->get_path(p_origin, p_destination, p_optimize); +} + +RID GdNavigationServer::region_create() const { + auto mut_this = const_cast<GdNavigationServer *>(this); + mut_this->operations_mutex->lock(); + NavRegion *reg = memnew(NavRegion); + RID rid = region_owner.make_rid(reg); + reg->set_self(rid); + mut_this->operations_mutex->unlock(); + return rid; +} + +COMMAND_2(region_set_map, RID, p_region, RID, p_map) { + NavRegion *region = region_owner.getornull(p_region); + ERR_FAIL_COND(region == NULL); + + if (region->get_map() != NULL) { + + if (region->get_map()->get_self() == p_map) + return; // Pointless + + region->get_map()->remove_region(region); + region->set_map(NULL); + } + + if (p_map.is_valid()) { + NavMap *map = map_owner.getornull(p_map); + ERR_FAIL_COND(map == NULL); + + map->add_region(region); + region->set_map(map); + } +} + +COMMAND_2(region_set_transform, RID, p_region, Transform, p_transform) { + NavRegion *region = region_owner.getornull(p_region); + ERR_FAIL_COND(region == NULL); + + region->set_transform(p_transform); +} + +COMMAND_2(region_set_navmesh, RID, p_region, Ref<NavigationMesh>, p_nav_mesh) { + NavRegion *region = region_owner.getornull(p_region); + ERR_FAIL_COND(region == NULL); + + region->set_mesh(p_nav_mesh); +} + +void GdNavigationServer::region_bake_navmesh(Ref<NavigationMesh> r_mesh, Node *p_node) const { + ERR_FAIL_COND(r_mesh.is_null()); + ERR_FAIL_COND(p_node == NULL); + +#ifndef _3D_DISABLED + NavigationMeshGenerator::get_singleton()->clear(r_mesh); + NavigationMeshGenerator::get_singleton()->bake(r_mesh, p_node); +#endif +} + +RID GdNavigationServer::agent_create() const { + auto mut_this = const_cast<GdNavigationServer *>(this); + mut_this->operations_mutex->lock(); + RvoAgent *agent = memnew(RvoAgent()); + RID rid = agent_owner.make_rid(agent); + agent->set_self(rid); + mut_this->operations_mutex->unlock(); + return rid; +} + +COMMAND_2(agent_set_map, RID, p_agent, RID, p_map) { + RvoAgent *agent = agent_owner.getornull(p_agent); + ERR_FAIL_COND(agent == NULL); + + if (agent->get_map()) { + if (agent->get_map()->get_self() == p_map) + return; // Pointless + + agent->get_map()->remove_agent(agent); + } + + agent->set_map(NULL); + + if (p_map.is_valid()) { + NavMap *map = map_owner.getornull(p_map); + ERR_FAIL_COND(map == NULL); + + agent->set_map(map); + map->add_agent(agent); + + if (agent->has_callback()) { + map->set_agent_as_controlled(agent); + } + } +} + +COMMAND_2(agent_set_neighbor_dist, RID, p_agent, real_t, p_dist) { + RvoAgent *agent = agent_owner.getornull(p_agent); + ERR_FAIL_COND(agent == NULL); + + agent->get_agent()->neighborDist_ = p_dist; +} + +COMMAND_2(agent_set_max_neighbors, RID, p_agent, int, p_count) { + RvoAgent *agent = agent_owner.getornull(p_agent); + ERR_FAIL_COND(agent == NULL); + + agent->get_agent()->maxNeighbors_ = p_count; +} + +COMMAND_2(agent_set_time_horizon, RID, p_agent, real_t, p_time) { + RvoAgent *agent = agent_owner.getornull(p_agent); + ERR_FAIL_COND(agent == NULL); + + agent->get_agent()->timeHorizon_ = p_time; +} + +COMMAND_2(agent_set_radius, RID, p_agent, real_t, p_radius) { + RvoAgent *agent = agent_owner.getornull(p_agent); + ERR_FAIL_COND(agent == NULL); + + agent->get_agent()->radius_ = p_radius; +} + +COMMAND_2(agent_set_max_speed, RID, p_agent, real_t, p_max_speed) { + RvoAgent *agent = agent_owner.getornull(p_agent); + ERR_FAIL_COND(agent == NULL); + + agent->get_agent()->maxSpeed_ = p_max_speed; +} + +COMMAND_2(agent_set_velocity, RID, p_agent, Vector3, p_velocity) { + RvoAgent *agent = agent_owner.getornull(p_agent); + ERR_FAIL_COND(agent == NULL); + + agent->get_agent()->velocity_ = RVO::Vector3(p_velocity.x, p_velocity.y, p_velocity.z); +} + +COMMAND_2(agent_set_target_velocity, RID, p_agent, Vector3, p_velocity) { + RvoAgent *agent = agent_owner.getornull(p_agent); + ERR_FAIL_COND(agent == NULL); + + agent->get_agent()->prefVelocity_ = RVO::Vector3(p_velocity.x, p_velocity.y, p_velocity.z); +} + +COMMAND_2(agent_set_position, RID, p_agent, Vector3, p_position) { + RvoAgent *agent = agent_owner.getornull(p_agent); + ERR_FAIL_COND(agent == NULL); + + agent->get_agent()->position_ = RVO::Vector3(p_position.x, p_position.y, p_position.z); +} + +COMMAND_2(agent_set_ignore_y, RID, p_agent, bool, p_ignore) { + RvoAgent *agent = agent_owner.getornull(p_agent); + ERR_FAIL_COND(agent == NULL); + + agent->get_agent()->ignore_y_ = p_ignore; +} + +bool GdNavigationServer::agent_is_map_changed(RID p_agent) const { + RvoAgent *agent = agent_owner.getornull(p_agent); + ERR_FAIL_COND_V(agent == NULL, false); + + return agent->is_map_changed(); +} + +COMMAND_4(agent_set_callback, RID, p_agent, Object *, p_receiver, StringName, p_method, Variant, p_udata) { + RvoAgent *agent = agent_owner.getornull(p_agent); + ERR_FAIL_COND(agent == NULL); + + agent->set_callback(p_receiver == NULL ? ObjectID() : p_receiver->get_instance_id(), p_method, p_udata); + + if (agent->get_map()) { + if (p_receiver == NULL) { + agent->get_map()->remove_agent_as_controlled(agent); + } else { + agent->get_map()->set_agent_as_controlled(agent); + } + } +} + +COMMAND_1(free, RID, p_object) { + if (map_owner.owns(p_object)) { + NavMap *map = map_owner.getornull(p_object); + + // Removes any assigned region + std::vector<NavRegion *> regions = map->get_regions(); + for (size_t i(0); i < regions.size(); i++) { + map->remove_region(regions[i]); + regions[i]->set_map(NULL); + } + + // Remove any assigned agent + std::vector<RvoAgent *> agents = map->get_agents(); + for (size_t i(0); i < agents.size(); i++) { + map->remove_agent(agents[i]); + agents[i]->set_map(NULL); + } + + active_maps.erase(map); + map_owner.free(p_object); + memdelete(map); + + } else if (region_owner.owns(p_object)) { + NavRegion *region = region_owner.getornull(p_object); + + // Removes this region from the map if assigned + if (region->get_map() != NULL) { + region->get_map()->remove_region(region); + region->set_map(NULL); + } + + region_owner.free(p_object); + memdelete(region); + + } else if (agent_owner.owns(p_object)) { + RvoAgent *agent = agent_owner.getornull(p_object); + + // Removes this agent from the map if assigned + if (agent->get_map() != NULL) { + agent->get_map()->remove_agent(agent); + agent->set_map(NULL); + } + + agent_owner.free(p_object); + memdelete(agent); + + } else { + ERR_FAIL_COND("Invalid ID."); + } +} + +void GdNavigationServer::set_active(bool p_active) const { + auto mut_this = const_cast<GdNavigationServer *>(this); + mut_this->operations_mutex->lock(); + mut_this->active = p_active; + mut_this->operations_mutex->unlock(); +} + +void GdNavigationServer::step(real_t p_delta_time) { + if (!active) { + return; + } + + // With c++ we can't be 100% sure this is called in single thread so use the mutex. + commands_mutex->lock(); + operations_mutex->lock(); + for (size_t i(0); i < commands.size(); i++) { + commands[i]->exec(this); + memdelete(commands[i]); + } + commands.clear(); + operations_mutex->unlock(); + commands_mutex->unlock(); + + // These are internal operations so don't need to be shielded. + 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(); + } +} + +#undef COMMAND_1 +#undef COMMAND_2 +#undef COMMAND_4 diff --git a/modules/gdnavigation/gd_navigation_server.h b/modules/gdnavigation/gd_navigation_server.h new file mode 100644 index 0000000000..564e9870a0 --- /dev/null +++ b/modules/gdnavigation/gd_navigation_server.h @@ -0,0 +1,136 @@ +/*************************************************************************/ +/* gd_navigation_server.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 GD_NAVIGATION_SERVER_H +#define GD_NAVIGATION_SERVER_H + +#include "core/rid.h" +#include "core/rid_owner.h" +#include "servers/navigation_server.h" + +#include "nav_map.h" +#include "nav_region.h" +#include "rvo_agent.h" + +/** + @author AndreaCatania +*/ + +/// The commands are functions executed during the `sync` phase. + +#define MERGE_INTERNAL(A, B) A##B +#define MERGE(A, B) MERGE_INTERNAL(A, B) + +#define COMMAND_1(F_NAME, T_0, D_0) \ + virtual void F_NAME(T_0 D_0) const; \ + void MERGE(_cmd_, F_NAME)(T_0 D_0) + +#define COMMAND_2(F_NAME, T_0, D_0, T_1, D_1) \ + virtual void F_NAME(T_0 D_0, T_1 D_1) const; \ + void MERGE(_cmd_, F_NAME)(T_0 D_0, T_1 D_1) + +#define COMMAND_4_DEF(F_NAME, T_0, D_0, T_1, D_1, T_2, D_2, T_3, D_3, D_3_DEF) \ + virtual void F_NAME(T_0 D_0, T_1 D_1, T_2 D_2, T_3 D_3 = D_3_DEF) const; \ + 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() {} + virtual void exec(GdNavigationServer *server) = 0; +}; + +class GdNavigationServer : public NavigationServer { + Mutex *commands_mutex; + /// Mutex used to make any operation threadsafe. + Mutex *operations_mutex; + + std::vector<SetCommand *> commands; + + mutable RID_PtrOwner<NavMap> map_owner; + mutable RID_PtrOwner<NavRegion> region_owner; + mutable RID_PtrOwner<RvoAgent> agent_owner; + + bool active; + Vector<NavMap *> active_maps; + +public: + GdNavigationServer(); + virtual ~GdNavigationServer(); + + void add_command(SetCommand *command) const; + + virtual RID map_create() const; + COMMAND_2(map_set_active, RID, p_map, bool, p_active); + virtual bool map_is_active(RID p_map) const; + + COMMAND_2(map_set_up, RID, p_map, Vector3, p_up); + virtual Vector3 map_get_up(RID p_map) const; + + COMMAND_2(map_set_cell_size, RID, p_map, real_t, p_cell_size); + virtual real_t map_get_cell_size(RID p_map) const; + + COMMAND_2(map_set_edge_connection_margin, RID, p_map, real_t, p_connection_margin); + virtual real_t map_get_edge_connection_margin(RID p_map) const; + + virtual Vector<Vector3> map_get_path(RID p_map, Vector3 p_origin, Vector3 p_destination, bool p_optimize) const; + + virtual RID region_create() const; + COMMAND_2(region_set_map, RID, p_region, RID, p_map); + COMMAND_2(region_set_transform, RID, p_region, Transform, p_transform); + COMMAND_2(region_set_navmesh, RID, p_region, Ref<NavigationMesh>, p_nav_mesh); + virtual void region_bake_navmesh(Ref<NavigationMesh> r_mesh, Node *p_node) const; + + virtual RID agent_create() const; + COMMAND_2(agent_set_map, RID, p_agent, RID, p_map); + COMMAND_2(agent_set_neighbor_dist, RID, p_agent, real_t, p_dist); + COMMAND_2(agent_set_max_neighbors, RID, p_agent, int, p_count); + COMMAND_2(agent_set_time_horizon, RID, p_agent, real_t, p_time); + COMMAND_2(agent_set_radius, RID, p_agent, real_t, p_radius); + COMMAND_2(agent_set_max_speed, RID, p_agent, real_t, p_max_speed); + COMMAND_2(agent_set_velocity, RID, p_agent, Vector3, p_velocity); + COMMAND_2(agent_set_target_velocity, RID, p_agent, Vector3, p_velocity); + COMMAND_2(agent_set_position, RID, p_agent, Vector3, p_position); + COMMAND_2(agent_set_ignore_y, RID, p_agent, bool, p_ignore); + virtual bool agent_is_map_changed(RID p_agent) const; + COMMAND_4_DEF(agent_set_callback, RID, p_agent, Object *, p_receiver, StringName, p_method, Variant, p_udata, Variant()); + + COMMAND_1(free, RID, p_object); + + virtual void set_active(bool p_active) const; + virtual void step(real_t p_delta_time); +}; + +#undef COMMAND_1 +#undef COMMAND_2 +#undef COMMAND_4_DEF + +#endif // GD_NAVIGATION_SERVER_H diff --git a/modules/gdnavigation/nav_map.cpp b/modules/gdnavigation/nav_map.cpp new file mode 100644 index 0000000000..d1765f4da9 --- /dev/null +++ b/modules/gdnavigation/nav_map.cpp @@ -0,0 +1,665 @@ +/*************************************************************************/ +/* nav_map.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 "nav_map.h" + +#include "core/os/threaded_array_processor.h" +#include "nav_region.h" +#include "rvo_agent.h" +#include <algorithm> + +/** + @author AndreaCatania +*/ + +#define USE_ENTRY_POINT + +NavMap::NavMap() : + up(0, 1, 0), + cell_size(0.3), + edge_connection_margin(5.0), + regenerate_polygons(true), + regenerate_links(true), + agents_dirty(false), + deltatime(0.0), + map_update_id(0) {} + +void NavMap::set_up(Vector3 p_up) { + up = p_up; + regenerate_polygons = true; +} + +void NavMap::set_cell_size(float p_cell_size) { + cell_size = p_cell_size; + regenerate_polygons = true; +} + +void NavMap::set_edge_connection_margin(float p_edge_connection_margin) { + edge_connection_margin = p_edge_connection_margin; + regenerate_links = true; +} + +gd::PointKey NavMap::get_point_key(const Vector3 &p_pos) const { + const int x = int(Math::floor(p_pos.x / cell_size)); + const int y = int(Math::floor(p_pos.y / cell_size)); + const int z = int(Math::floor(p_pos.z / cell_size)); + + gd::PointKey p; + p.key = 0; + p.x = x; + p.y = y; + p.z = z; + return p; +} + +Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p_optimize) const { + + const gd::Polygon *begin_poly = NULL; + const gd::Polygon *end_poly = NULL; + Vector3 begin_point; + Vector3 end_point; + float begin_d = 1e20; + float end_d = 1e20; + + // Find the initial poly and the end poly on this map. + for (size_t i(0); i < polygons.size(); i++) { + const gd::Polygon &p = polygons[i]; + + // For each point cast a face and check the distance between the origin/destination + for (size_t point_id = 2; point_id < p.points.size(); point_id++) { + + Face3 f(p.points[point_id - 2].pos, p.points[point_id - 1].pos, p.points[point_id].pos); + Vector3 spoint = f.get_closest_point_to(p_origin); + float dpoint = spoint.distance_to(p_origin); + if (dpoint < begin_d) { + begin_d = dpoint; + begin_poly = &p; + begin_point = spoint; + } + + spoint = f.get_closest_point_to(p_destination); + dpoint = spoint.distance_to(p_destination); + if (dpoint < end_d) { + end_d = dpoint; + end_poly = &p; + end_point = spoint; + } + } + } + + if (!begin_poly || !end_poly) { + // No path + return Vector<Vector3>(); + } + + if (begin_poly == end_poly) { + + Vector<Vector3> path; + path.resize(2); + path.write[0] = begin_point; + path.write[1] = end_point; + return path; + } + + std::vector<gd::NavigationPoly> navigation_polys; + navigation_polys.reserve(polygons.size() * 0.75); + + // The elements indices in the `navigation_polys`. + int least_cost_id(-1); + List<uint32_t> open_list; + bool found_route = false; + + navigation_polys.push_back(gd::NavigationPoly(begin_poly)); + { + least_cost_id = 0; + gd::NavigationPoly *least_cost_poly = &navigation_polys[least_cost_id]; + least_cost_poly->self_id = least_cost_id; + least_cost_poly->entry = begin_point; + } + + open_list.push_back(0); + + const gd::Polygon *reachable_end = NULL; + float reachable_d = 1e30; + bool is_reachable = true; + + while (found_route == false) { + + { + // Takes the current least_cost_poly neighbors and compute the traveled_distance of each + for (size_t i = 0; i < navigation_polys[least_cost_id].poly->edges.size(); i++) { + gd::NavigationPoly *least_cost_poly = &navigation_polys[least_cost_id]; + + const gd::Edge &edge = least_cost_poly->poly->edges[i]; + if (!edge.other_polygon) + continue; + +#ifdef USE_ENTRY_POINT + Vector3 edge_line[2] = { + least_cost_poly->poly->points[i].pos, + least_cost_poly->poly->points[(i + 1) % least_cost_poly->poly->points.size()].pos + }; + + const Vector3 new_entry = Geometry::get_closest_point_to_segment(least_cost_poly->entry, edge_line); + const float new_distance = least_cost_poly->entry.distance_to(new_entry) + least_cost_poly->traveled_distance; +#else + const float new_distance = least_cost_poly->poly->center.distance_to(edge.other_polygon->center) + least_cost_poly->traveled_distance; +#endif + + auto it = std::find( + navigation_polys.begin(), + navigation_polys.end(), + gd::NavigationPoly(edge.other_polygon)); + + if (it != navigation_polys.end()) { + // Oh this was visited already, can we win the cost? + if (it->traveled_distance > new_distance) { + + it->prev_navigation_poly_id = least_cost_id; + it->back_navigation_edge = edge.other_edge; + it->traveled_distance = new_distance; +#ifdef USE_ENTRY_POINT + it->entry = new_entry; +#endif + } + } else { + // Add to open neighbours + + navigation_polys.push_back(gd::NavigationPoly(edge.other_polygon)); + gd::NavigationPoly *np = &navigation_polys[navigation_polys.size() - 1]; + + np->self_id = navigation_polys.size() - 1; + np->prev_navigation_poly_id = least_cost_id; + np->back_navigation_edge = edge.other_edge; + np->traveled_distance = new_distance; +#ifdef USE_ENTRY_POINT + np->entry = new_entry; +#endif + open_list.push_back(navigation_polys.size() - 1); + } + } + } + + // Removes the least cost polygon from the open list so we can advance. + open_list.erase(least_cost_id); + + if (open_list.size() == 0) { + // When the open list is empty at this point the End Polygon is not reachable + // so use the further reachable polygon + ERR_BREAK_MSG(is_reachable == false, "It's not expect to not find the most reachable polygons"); + is_reachable = false; + if (reachable_end == NULL) { + // The path is not found and there is not a way out. + break; + } + + // Set as end point the furthest reachable point. + end_poly = reachable_end; + end_d = 1e20; + for (size_t point_id = 2; point_id < end_poly->points.size(); point_id++) { + Face3 f(end_poly->points[point_id - 2].pos, end_poly->points[point_id - 1].pos, end_poly->points[point_id].pos); + Vector3 spoint = f.get_closest_point_to(p_destination); + float dpoint = spoint.distance_to(p_destination); + if (dpoint < end_d) { + end_point = spoint; + end_d = dpoint; + } + } + + // Reset open and navigation_polys + gd::NavigationPoly np = navigation_polys[0]; + navigation_polys.clear(); + navigation_polys.push_back(np); + open_list.clear(); + open_list.push_back(0); + + reachable_end = NULL; + + continue; + } + + // Now take the new least_cost_poly from the open list. + least_cost_id = -1; + float least_cost = 1e30; + + for (auto element = open_list.front(); element != NULL; element = element->next()) { + gd::NavigationPoly *np = &navigation_polys[element->get()]; + float cost = np->traveled_distance; +#ifdef USE_ENTRY_POINT + cost += np->entry.distance_to(end_point); +#else + cost += np->poly->center.distance_to(end_point); +#endif + if (cost < least_cost) { + least_cost_id = np->self_id; + least_cost = cost; + } + } + + // Stores the further reachable end polygon, in case our goal is not reachable. + if (is_reachable) { + float d = navigation_polys[least_cost_id].entry.distance_to(p_destination); + if (reachable_d > d) { + reachable_d = d; + reachable_end = navigation_polys[least_cost_id].poly; + } + } + + ERR_BREAK(least_cost_id == -1); + + // Check if we reached the end + if (navigation_polys[least_cost_id].poly == end_poly) { + // Yep, done!! + found_route = true; + break; + } + } + + if (found_route) { + + Vector<Vector3> path; + if (p_optimize) { + + // String pulling + + gd::NavigationPoly *apex_poly = &navigation_polys[least_cost_id]; + Vector3 apex_point = end_point; + Vector3 portal_left = apex_point; + Vector3 portal_right = apex_point; + gd::NavigationPoly *left_poly = apex_poly; + gd::NavigationPoly *right_poly = apex_poly; + gd::NavigationPoly *p = apex_poly; + + path.push_back(end_point); + + while (p) { + + Vector3 left; + Vector3 right; + +#define CLOCK_TANGENT(m_a, m_b, m_c) (((m_a) - (m_c)).cross((m_a) - (m_b))) + + if (p->poly == begin_poly) { + left = begin_point; + right = begin_point; + } else { + int prev = p->back_navigation_edge; + int prev_n = (p->back_navigation_edge + 1) % p->poly->points.size(); + left = p->poly->points[prev].pos; + right = p->poly->points[prev_n].pos; + + //if (CLOCK_TANGENT(apex_point,left,(left+right)*0.5).dot(up) < 0){ + if (p->poly->clockwise) { + SWAP(left, right); + } + } + + bool skip = false; + + if (CLOCK_TANGENT(apex_point, portal_left, left).dot(up) >= 0) { + //process + if (portal_left == apex_point || CLOCK_TANGENT(apex_point, left, portal_right).dot(up) > 0) { + left_poly = p; + portal_left = left; + } else { + + clip_path(navigation_polys, path, apex_poly, portal_right, right_poly); + + apex_point = portal_right; + p = right_poly; + left_poly = p; + apex_poly = p; + portal_left = apex_point; + portal_right = apex_point; + path.push_back(apex_point); + skip = true; + } + } + + if (!skip && CLOCK_TANGENT(apex_point, portal_right, right).dot(up) <= 0) { + //process + if (portal_right == apex_point || CLOCK_TANGENT(apex_point, right, portal_left).dot(up) < 0) { + right_poly = p; + portal_right = right; + } else { + + clip_path(navigation_polys, path, apex_poly, portal_left, left_poly); + + apex_point = portal_left; + p = left_poly; + right_poly = p; + apex_poly = p; + portal_right = apex_point; + portal_left = apex_point; + path.push_back(apex_point); + } + } + + if (p->prev_navigation_poly_id != -1) + p = &navigation_polys[p->prev_navigation_poly_id]; + else + // The end + p = NULL; + } + + if (path[path.size() - 1] != begin_point) + path.push_back(begin_point); + + path.invert(); + + } else { + path.push_back(end_point); + + // Add mid points + int np_id = least_cost_id; + while (np_id != -1) { + +#ifdef USE_ENTRY_POINT + Vector3 point = navigation_polys[np_id].entry; +#else + int prev = navigation_polys[np_id].back_navigation_edge; + int prev_n = (navigation_polys[np_id].back_navigation_edge + 1) % navigation_polys[np_id].poly->points.size(); + Vector3 point = (navigation_polys[np_id].poly->points[prev].pos + navigation_polys[np_id].poly->points[prev_n].pos) * 0.5; +#endif + + path.push_back(point); + np_id = navigation_polys[np_id].prev_navigation_poly_id; + } + + path.invert(); + } + + return path; + } + return Vector<Vector3>(); +} + +void NavMap::add_region(NavRegion *p_region) { + regions.push_back(p_region); + regenerate_links = true; +} + +void NavMap::remove_region(NavRegion *p_region) { + regions.push_back(p_region); + regenerate_links = true; +} + +bool NavMap::has_agent(RvoAgent *agent) const { + return std::find(agents.begin(), agents.end(), agent) != agents.end(); +} + +void NavMap::add_agent(RvoAgent *agent) { + if (!has_agent(agent)) { + agents.push_back(agent); + agents_dirty = true; + } +} + +void NavMap::remove_agent(RvoAgent *agent) { + remove_agent_as_controlled(agent); + auto it = std::find(agents.begin(), agents.end(), agent); + if (it != agents.end()) { + agents.erase(it); + agents_dirty = true; + } +} + +void NavMap::set_agent_as_controlled(RvoAgent *agent) { + const bool exist = std::find(controlled_agents.begin(), controlled_agents.end(), agent) != controlled_agents.end(); + if (!exist) { + ERR_FAIL_COND(!has_agent(agent)); + controlled_agents.push_back(agent); + } +} + +void NavMap::remove_agent_as_controlled(RvoAgent *agent) { + auto it = std::find(controlled_agents.begin(), controlled_agents.end(), agent); + if (it != controlled_agents.end()) { + controlled_agents.erase(it); + } +} + +void NavMap::sync() { + + if (regenerate_polygons) { + for (size_t r(0); r < regions.size(); r++) { + regions[r]->scratch_polygons(); + } + regenerate_links = true; + } + + for (size_t r(0); r < regions.size(); r++) { + if (regions[r]->sync()) { + regenerate_links = true; + } + } + + if (regenerate_links) { + // Copy all region polygons in the map. + int count = 0; + for (size_t r(0); r < regions.size(); r++) { + count += regions[r]->get_polygons().size(); + } + + polygons.resize(count); + count = 0; + + for (size_t r(0); r < regions.size(); r++) { + std::copy( + regions[r]->get_polygons().data(), + regions[r]->get_polygons().data() + regions[r]->get_polygons().size(), + polygons.begin() + count); + + count += regions[r]->get_polygons().size(); + } + + // Connects the `Edges` of all the `Polygons` of all `Regions` each other. + Map<gd::EdgeKey, gd::Connection> connections; + + for (size_t poly_id(0); poly_id < polygons.size(); poly_id++) { + gd::Polygon &poly(polygons[poly_id]); + + for (size_t p(0); p < poly.points.size(); p++) { + int next_point = (p + 1) % poly.points.size(); + gd::EdgeKey ek(poly.points[p].key, poly.points[next_point].key); + + Map<gd::EdgeKey, gd::Connection>::Element *connection = connections.find(ek); + if (!connection) { + // Nothing yet + gd::Connection c; + c.A = &poly; + c.A_edge = p; + c.B = NULL; + c.B_edge = -1; + connections[ek] = c; + + } else if (connection->get().B == NULL) { + CRASH_COND(connection->get().A == NULL); // Unreachable + + // Connect the two Polygons by this edge + connection->get().B = &poly; + connection->get().B_edge = p; + + connection->get().A->edges[connection->get().A_edge].this_edge = connection->get().A_edge; + connection->get().A->edges[connection->get().A_edge].other_polygon = connection->get().B; + connection->get().A->edges[connection->get().A_edge].other_edge = connection->get().B_edge; + + connection->get().B->edges[connection->get().B_edge].this_edge = connection->get().B_edge; + connection->get().B->edges[connection->get().B_edge].other_polygon = connection->get().A; + connection->get().B->edges[connection->get().B_edge].other_edge = connection->get().A_edge; + } else { + // The edge is already connected with another edge, skip. + } + } + } + + // Takes all the free edges. + std::vector<gd::FreeEdge> free_edges; + free_edges.reserve(connections.size()); + + for (auto connection_element = connections.front(); connection_element; connection_element = connection_element->next()) { + if (connection_element->get().B == NULL) { + CRASH_COND(connection_element->get().A == NULL); // Unreachable + CRASH_COND(connection_element->get().A_edge < 0); // Unreachable + + // This is a free edge + uint32_t id(free_edges.size()); + free_edges.push_back(gd::FreeEdge()); + free_edges[id].is_free = true; + free_edges[id].poly = connection_element->get().A; + free_edges[id].edge_id = connection_element->get().A_edge; + uint32_t point_0(free_edges[id].edge_id); + uint32_t point_1((free_edges[id].edge_id + 1) % free_edges[id].poly->points.size()); + Vector3 pos_0 = free_edges[id].poly->points[point_0].pos; + Vector3 pos_1 = free_edges[id].poly->points[point_1].pos; + Vector3 relative = pos_1 - pos_0; + free_edges[id].edge_center = (pos_0 + pos_1) / 2.0; + free_edges[id].edge_dir = relative.normalized(); + free_edges[id].edge_len_squared = relative.length_squared(); + } + } + + const float ecm_squared(edge_connection_margin * edge_connection_margin); +#define LEN_TOLLERANCE 0.1 +#define DIR_TOLLERANCE 0.9 + // In front of tollerance +#define IFO_TOLLERANCE 0.5 + + // Find the compatible near edges. + // + // Note: + // Considering that the edges must be compatible (for obvious reasons) + // to be connected, create new polygons to remove that small gap is + // not really useful and would result in wasteful computation during + // connection, integration and path finding. + for (size_t i(0); i < free_edges.size(); i++) { + if (!free_edges[i].is_free) { + continue; + } + gd::FreeEdge &edge = free_edges[i]; + for (size_t y(0); y < free_edges.size(); y++) { + gd::FreeEdge &other_edge = free_edges[y]; + if (i == y || !other_edge.is_free || edge.poly->owner == other_edge.poly->owner) { + continue; + } + + Vector3 rel_centers = other_edge.edge_center - edge.edge_center; + if (ecm_squared > rel_centers.length_squared() // Are enough closer? + && ABS(edge.edge_len_squared - other_edge.edge_len_squared) < LEN_TOLLERANCE // Are the same length? + && ABS(edge.edge_dir.dot(other_edge.edge_dir)) > DIR_TOLLERANCE // Are alligned? + && ABS(rel_centers.normalized().dot(edge.edge_dir)) < IFO_TOLLERANCE // Are one in front the other? + ) { + // The edges can be connected + edge.is_free = false; + other_edge.is_free = false; + + edge.poly->edges[edge.edge_id].this_edge = edge.edge_id; + edge.poly->edges[edge.edge_id].other_edge = other_edge.edge_id; + edge.poly->edges[edge.edge_id].other_polygon = other_edge.poly; + + other_edge.poly->edges[other_edge.edge_id].this_edge = other_edge.edge_id; + other_edge.poly->edges[other_edge.edge_id].other_edge = edge.edge_id; + other_edge.poly->edges[other_edge.edge_id].other_polygon = edge.poly; + } + } + } + } + + if (regenerate_links) { + map_update_id = map_update_id + 1 % 9999999; + } + + if (agents_dirty) { + std::vector<RVO::Agent *> raw_agents; + raw_agents.reserve(agents.size()); + for (size_t i(0); i < agents.size(); i++) + raw_agents.push_back(agents[i]->get_agent()); + rvo.buildAgentTree(raw_agents); + } + + regenerate_polygons = false; + regenerate_links = false; + agents_dirty = false; +} + +void NavMap::compute_single_step(uint32_t index, RvoAgent **agent) { + (*(agent + index))->get_agent()->computeNeighbors(&rvo); + (*(agent + index))->get_agent()->computeNewVelocity(deltatime); +} + +void NavMap::step(real_t p_deltatime) { + deltatime = p_deltatime; + if (controlled_agents.size() > 0) { + thread_process_array( + controlled_agents.size(), + this, + &NavMap::compute_single_step, + controlled_agents.data()); + } +} + +void NavMap::dispatch_callbacks() { + for (int i(0); i < static_cast<int>(controlled_agents.size()); i++) { + controlled_agents[i]->dispatch_callback(); + } +} + +void NavMap::clip_path(const std::vector<gd::NavigationPoly> &p_navigation_polys, Vector<Vector3> &path, const gd::NavigationPoly *from_poly, const Vector3 &p_to_point, const gd::NavigationPoly *p_to_poly) const { + Vector3 from = path[path.size() - 1]; + + if (from.distance_to(p_to_point) < CMP_EPSILON) + return; + Plane cut_plane; + cut_plane.normal = (from - p_to_point).cross(up); + if (cut_plane.normal == Vector3()) + return; + cut_plane.normal.normalize(); + cut_plane.d = cut_plane.normal.dot(from); + + while (from_poly != p_to_poly) { + + int back_nav_edge = from_poly->back_navigation_edge; + Vector3 a = from_poly->poly->points[back_nav_edge].pos; + Vector3 b = from_poly->poly->points[(back_nav_edge + 1) % from_poly->poly->points.size()].pos; + + ERR_FAIL_COND(from_poly->prev_navigation_poly_id == -1); + from_poly = &p_navigation_polys[from_poly->prev_navigation_poly_id]; + + if (a.distance_to(b) > CMP_EPSILON) { + + Vector3 inters; + if (cut_plane.intersects_segment(a, b, &inters)) { + if (inters.distance_to(p_to_point) > CMP_EPSILON && inters.distance_to(path[path.size() - 1]) > CMP_EPSILON) { + path.push_back(inters); + } + } + } + } +} diff --git a/modules/gdnavigation/nav_map.h b/modules/gdnavigation/nav_map.h new file mode 100644 index 0000000000..128a82580c --- /dev/null +++ b/modules/gdnavigation/nav_map.h @@ -0,0 +1,137 @@ +/*************************************************************************/ +/* nav_map.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 RVO_SPACE_H +#define RVO_SPACE_H + +#include "nav_rid.h" + +#include "core/math/math_defs.h" +#include "nav_utils.h" +#include <KdTree.h> + +/** + @author AndreaCatania +*/ + +class NavRegion; +class RvoAgent; +class NavRegion; + +class NavMap : public NavRid { + + /// Map Up + Vector3 up; + + /// To find the polygons edges the vertices are displaced in a grid where + /// each cell has the following cell_size. + real_t cell_size; + + /// This value is used to detect the near edges to connect. + real_t edge_connection_margin; + + bool regenerate_polygons; + bool regenerate_links; + + std::vector<NavRegion *> regions; + + /// Map polygons + std::vector<gd::Polygon> polygons; + + /// Rvo world + RVO::KdTree rvo; + + /// Is agent array modified? + bool agents_dirty; + + /// All the Agents (even the controlled one) + std::vector<RvoAgent *> agents; + + /// Controlled agents + std::vector<RvoAgent *> controlled_agents; + + /// Physics delta time + real_t deltatime; + + /// Change the id each time the map is updated. + uint32_t map_update_id; + +public: + NavMap(); + + void set_up(Vector3 p_up); + Vector3 get_up() const { + return up; + } + + void set_cell_size(float p_cell_size); + float get_cell_size() const { + return cell_size; + } + + void set_edge_connection_margin(float p_edge_connection_margin); + float get_edge_connection_margin() const { + return edge_connection_margin; + } + + gd::PointKey get_point_key(const Vector3 &p_pos) const; + + Vector<Vector3> get_path(Vector3 p_origin, Vector3 p_destination, bool p_optimize) const; + + void add_region(NavRegion *p_region); + void remove_region(NavRegion *p_region); + const std::vector<NavRegion *> &get_regions() const { + return regions; + } + + bool has_agent(RvoAgent *agent) const; + void add_agent(RvoAgent *agent); + void remove_agent(RvoAgent *agent); + const std::vector<RvoAgent *> &get_agents() const { + return agents; + } + + void set_agent_as_controlled(RvoAgent *agent); + void remove_agent_as_controlled(RvoAgent *agent); + + uint32_t get_map_update_id() const { + return map_update_id; + } + + void sync(); + void step(real_t p_deltatime); + void dispatch_callbacks(); + +private: + void compute_single_step(uint32_t index, RvoAgent **agent); + void clip_path(const std::vector<gd::NavigationPoly> &p_navigation_polys, Vector<Vector3> &path, const gd::NavigationPoly *from_poly, const Vector3 &p_to_point, const gd::NavigationPoly *p_to_poly) const; +}; + +#endif // RVO_SPACE_H diff --git a/modules/gdnavigation/nav_region.cpp b/modules/gdnavigation/nav_region.cpp new file mode 100644 index 0000000000..d2d9d8b517 --- /dev/null +++ b/modules/gdnavigation/nav_region.cpp @@ -0,0 +1,136 @@ +/*************************************************************************/ +/* nav_region.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 "nav_region.h" + +#include "nav_map.h" + +/** + @author AndreaCatania +*/ + +NavRegion::NavRegion() : + map(NULL), + polygons_dirty(true) { +} + +void NavRegion::set_map(NavMap *p_map) { + map = p_map; + polygons_dirty = true; +} + +void NavRegion::set_transform(Transform p_transform) { + transform = p_transform; + polygons_dirty = true; +} + +void NavRegion::set_mesh(Ref<NavigationMesh> p_mesh) { + mesh = p_mesh; + polygons_dirty = true; +} + +bool NavRegion::sync() { + bool something_changed = polygons_dirty /* || something_dirty? */; + + update_polygons(); + + return something_changed; +} + +void NavRegion::update_polygons() { + if (!polygons_dirty) { + return; + } + polygons.clear(); + polygons_dirty = false; + + if (map == NULL) { + return; + } + + if (mesh.is_null()) + return; + + PoolVector<Vector3> vertices = mesh->get_vertices(); + int len = vertices.size(); + if (len == 0) + return; + + PoolVector<Vector3>::Read vertices_r = vertices.read(); + + polygons.resize(mesh->get_polygon_count()); + + // Build + for (size_t i(0); i < polygons.size(); i++) { + + gd::Polygon &p = polygons[i]; + p.owner = this; + + Vector<int> mesh_poly = mesh->get_polygon(i); + const int *indices = mesh_poly.ptr(); + bool valid(true); + p.points.resize(mesh_poly.size()); + p.edges.resize(mesh_poly.size()); + + Vector3 center; + float sum(0); + + for (int j(0); j < mesh_poly.size(); j++) { + + int idx = indices[j]; + if (idx < 0 || idx >= len) { + valid = false; + break; + } + + Vector3 point_position = transform.xform(vertices_r[idx]); + p.points[j].pos = point_position; + p.points[j].key = map->get_point_key(point_position); + + center += point_position; // Composing the center of the polygon + + if (j >= 2) { + Vector3 epa = transform.xform(vertices_r[indices[j - 2]]); + Vector3 epb = transform.xform(vertices_r[indices[j - 1]]); + + sum += map->get_up().dot((epb - epa).cross(point_position - epa)); + } + } + + if (!valid) { + ERR_BREAK_MSG(!valid, "The navigation mesh set in this region is not valid!"); + } + + p.clockwise = sum > 0; + if (mesh_poly.size() != 0) { + p.center = center / float(mesh_poly.size()); + } + } +} diff --git a/modules/gdnavigation/nav_region.h b/modules/gdnavigation/nav_region.h new file mode 100644 index 0000000000..d99254d1ad --- /dev/null +++ b/modules/gdnavigation/nav_region.h @@ -0,0 +1,89 @@ +/*************************************************************************/ +/* nav_region.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 NAV_REGION_H +#define NAV_REGION_H + +#include "nav_rid.h" + +#include "nav_utils.h" +#include "scene/3d/navigation.h" +#include <vector> + +/** + @author AndreaCatania +*/ + +class NavMap; +class NavRegion; + +class NavRegion : public NavRid { + NavMap *map; + Transform transform; + Ref<NavigationMesh> mesh; + + bool polygons_dirty; + + /// Cache + std::vector<gd::Polygon> polygons; + +public: + NavRegion(); + + void scratch_polygons() { + polygons_dirty = true; + } + + void set_map(NavMap *p_map); + NavMap *get_map() const { + return map; + } + + void set_transform(Transform transform); + const Transform &get_transform() const { + return transform; + } + + void set_mesh(Ref<NavigationMesh> p_mesh); + const Ref<NavigationMesh> get_mesh() const { + return mesh; + } + + std::vector<gd::Polygon> const &get_polygons() const { + return polygons; + } + + bool sync(); + +private: + void update_polygons(); +}; + +#endif // NAV_REGION_H diff --git a/modules/gdnavigation/nav_rid.h b/modules/gdnavigation/nav_rid.h new file mode 100644 index 0000000000..c119ecc5e0 --- /dev/null +++ b/modules/gdnavigation/nav_rid.h @@ -0,0 +1,48 @@ +/*************************************************************************/ +/* nav_rid.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 NAV_RID_H +#define NAV_RID_H + +#include "core/rid.h" + +/** + @author AndreaCatania +*/ + +class NavRid { + RID self; + +public: + _FORCE_INLINE_ void set_self(const RID &p_self) { self = p_self; } + _FORCE_INLINE_ RID get_self() const { return self; } +}; + +#endif // NAV_RID_H diff --git a/modules/gdnavigation/nav_utils.h b/modules/gdnavigation/nav_utils.h new file mode 100644 index 0000000000..bdf9eb34a8 --- /dev/null +++ b/modules/gdnavigation/nav_utils.h @@ -0,0 +1,169 @@ +/*************************************************************************/ +/* nav_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 NAV_UTILS_H +#define NAV_UTILS_H + +#include "core/math/vector3.h" +#include <vector> + +/** + @author AndreaCatania +*/ + +class NavRegion; + +namespace gd { +struct Polygon; + +union PointKey { + + struct { + int64_t x : 21; + int64_t y : 22; + int64_t z : 21; + }; + + uint64_t key; + bool operator<(const PointKey &p_key) const { return key < p_key.key; } +}; + +struct EdgeKey { + + PointKey a; + PointKey b; + + bool operator<(const EdgeKey &p_key) const { + return (a.key == p_key.a.key) ? (b.key < p_key.b.key) : (a.key < p_key.a.key); + } + + EdgeKey(const PointKey &p_a = PointKey(), const PointKey &p_b = PointKey()) : + a(p_a), + b(p_b) { + if (a.key > b.key) { + SWAP(a, b); + } + } +}; + +struct Point { + Vector3 pos; + PointKey key; +}; + +struct Edge { + /// This edge ID + int this_edge; + + /// Other Polygon + Polygon *other_polygon; + + /// The other `Polygon` at this edge id has this `Polygon`. + int other_edge; + + Edge() { + this_edge = -1; + other_polygon = NULL; + other_edge = -1; + } +}; + +struct Polygon { + NavRegion *owner; + + /// The points of this `Polygon` + std::vector<Point> points; + + /// Are the points clockwise ? + bool clockwise; + + /// The edges of this `Polygon` + std::vector<Edge> edges; + + /// The center of this `Polygon` + Vector3 center; +}; + +struct Connection { + + Polygon *A; + int A_edge; + Polygon *B; + int B_edge; + + Connection() { + A = NULL; + B = NULL; + A_edge = -1; + B_edge = -1; + } +}; + +struct NavigationPoly { + uint32_t self_id; + /// This poly. + const Polygon *poly; + /// The previous navigation poly (id in the `navigation_poly` array). + int prev_navigation_poly_id; + /// The edge id in this `Poly` to reach the `prev_navigation_poly_id`. + uint32_t back_navigation_edge; + /// The entry location of this poly. + Vector3 entry; + /// The distance to the destination. + float traveled_distance; + + NavigationPoly(const Polygon *p_poly) : + self_id(0), + poly(p_poly), + prev_navigation_poly_id(-1), + back_navigation_edge(0), + traveled_distance(0.0) { + } + + bool operator==(const NavigationPoly &other) const { + return this->poly == other.poly; + } + + bool operator!=(const NavigationPoly &other) const { + return !operator==(other); + } +}; + +struct FreeEdge { + bool is_free; + Polygon *poly; + uint32_t edge_id; + Vector3 edge_center; + Vector3 edge_dir; + float edge_len_squared; +}; +} // namespace gd + +#endif // NAV_UTILS_H diff --git a/modules/recast/navigation_mesh_editor_plugin.cpp b/modules/gdnavigation/navigation_mesh_editor_plugin.cpp index 6e68dba8ee..13c74d5706 100644 --- a/modules/recast/navigation_mesh_editor_plugin.cpp +++ b/modules/gdnavigation/navigation_mesh_editor_plugin.cpp @@ -28,10 +28,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#ifdef TOOLS_ENABLED #include "navigation_mesh_editor_plugin.h" #include "core/io/marshalls.h" #include "core/io/resource_saver.h" +#include "navigation_mesh_generator.h" #include "scene/3d/mesh_instance.h" #include "scene/gui/box_container.h" @@ -57,15 +59,14 @@ void NavigationMeshEditor::_bake_pressed() { button_bake->set_pressed(false); ERR_FAIL_COND(!node); - const String conf_warning = node->get_configuration_warning(); - if (!conf_warning.empty()) { - err_dialog->set_text(conf_warning); + if (!node->get_navigation_mesh().is_valid()) { + err_dialog->set_text(TTR("A NavigationMesh resource must be set or created for this node to work.")); err_dialog->popup_centered_minsize(); return; } - EditorNavigationMeshGenerator::get_singleton()->clear(node->get_navigation_mesh()); - EditorNavigationMeshGenerator::get_singleton()->bake(node->get_navigation_mesh(), node); + NavigationMeshGenerator::get_singleton()->clear(node->get_navigation_mesh()); + NavigationMeshGenerator::get_singleton()->bake(node->get_navigation_mesh(), node); node->update_gizmo(); } @@ -73,7 +74,7 @@ void NavigationMeshEditor::_bake_pressed() { void NavigationMeshEditor::_clear_pressed() { if (node) - EditorNavigationMeshGenerator::get_singleton()->clear(node->get_navigation_mesh()); + NavigationMeshGenerator::get_singleton()->clear(node->get_navigation_mesh()); button_bake->set_pressed(false); bake_info->set_text(""); @@ -160,3 +161,5 @@ NavigationMeshEditorPlugin::NavigationMeshEditorPlugin(EditorNode *p_node) { NavigationMeshEditorPlugin::~NavigationMeshEditorPlugin() { } + +#endif diff --git a/modules/recast/navigation_mesh_editor_plugin.h b/modules/gdnavigation/navigation_mesh_editor_plugin.h index 09c8673b43..f5833f3d7f 100644 --- a/modules/recast/navigation_mesh_editor_plugin.h +++ b/modules/gdnavigation/navigation_mesh_editor_plugin.h @@ -28,12 +28,15 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef NAVIGATION_MESH_GENERATOR_PLUGIN_H -#define NAVIGATION_MESH_GENERATOR_PLUGIN_H +#ifndef NAVIGATION_MESH_EDITOR_PLUGIN_H +#define NAVIGATION_MESH_EDITOR_PLUGIN_H + +#ifdef TOOLS_ENABLED #include "editor/editor_node.h" #include "editor/editor_plugin.h" -#include "navigation_mesh_generator.h" + +class NavigationMeshInstance; class NavigationMeshEditor : public Control { friend class NavigationMeshEditorPlugin; @@ -81,4 +84,6 @@ public: ~NavigationMeshEditorPlugin(); }; -#endif // NAVIGATION_MESH_GENERATOR_PLUGIN_H +#endif + +#endif diff --git a/modules/recast/navigation_mesh_generator.cpp b/modules/gdnavigation/navigation_mesh_generator.cpp index c67136b814..04b86fabc5 100644 --- a/modules/recast/navigation_mesh_generator.cpp +++ b/modules/gdnavigation/navigation_mesh_generator.cpp @@ -28,10 +28,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#ifndef _3D_DISABLED + #include "navigation_mesh_generator.h" + #include "core/math/quick_hull.h" #include "core/os/thread.h" -#include "editor/editor_settings.h" #include "scene/3d/collision_shape.h" #include "scene/3d/mesh_instance.h" #include "scene/3d/physics_body.h" @@ -45,23 +47,28 @@ #include "scene/resources/shape.h" #include "scene/resources/sphere_shape.h" +#include "modules/modules_enabled.gen.h" +#ifdef TOOLS_ENABLED +#include "editor/editor_node.h" +#include "editor/editor_settings.h" +#endif + #ifdef MODULE_CSG_ENABLED #include "modules/csg/csg_shape.h" #endif - #ifdef MODULE_GRIDMAP_ENABLED #include "modules/gridmap/grid_map.h" #endif -EditorNavigationMeshGenerator *EditorNavigationMeshGenerator::singleton = NULL; +NavigationMeshGenerator *NavigationMeshGenerator::singleton = NULL; -void EditorNavigationMeshGenerator::_add_vertex(const Vector3 &p_vec3, Vector<float> &p_verticies) { +void NavigationMeshGenerator::_add_vertex(const Vector3 &p_vec3, Vector<float> &p_verticies) { p_verticies.push_back(p_vec3.x); p_verticies.push_back(p_vec3.y); p_verticies.push_back(p_vec3.z); } -void EditorNavigationMeshGenerator::_add_mesh(const Ref<Mesh> &p_mesh, const Transform &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices) { +void NavigationMeshGenerator::_add_mesh(const Ref<Mesh> &p_mesh, const Transform &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices) { int current_vertex_count; for (int i = 0; i < p_mesh->get_surface_count(); i++) { @@ -116,7 +123,7 @@ void EditorNavigationMeshGenerator::_add_mesh(const Ref<Mesh> &p_mesh, const Tra } } -void EditorNavigationMeshGenerator::_add_faces(const PoolVector3Array &p_faces, const Transform &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices) { +void NavigationMeshGenerator::_add_faces(const PoolVector3Array &p_faces, const Transform &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices) { int face_count = p_faces.size() / 3; int current_vertex_count = p_verticies.size() / 3; @@ -131,7 +138,7 @@ void EditorNavigationMeshGenerator::_add_faces(const PoolVector3Array &p_faces, } } -void EditorNavigationMeshGenerator::_parse_geometry(Transform p_accumulated_transform, Node *p_node, Vector<float> &p_verticies, Vector<int> &p_indices, int p_generate_from, uint32_t p_collision_mask, bool p_recurse_children) { +void NavigationMeshGenerator::_parse_geometry(Transform p_accumulated_transform, Node *p_node, Vector<float> &p_verticies, Vector<int> &p_indices, int p_generate_from, uint32_t p_collision_mask, bool p_recurse_children) { if (Object::cast_to<MeshInstance>(p_node) && p_generate_from != NavigationMesh::PARSED_GEOMETRY_STATIC_COLLIDERS) { @@ -270,7 +277,7 @@ void EditorNavigationMeshGenerator::_parse_geometry(Transform p_accumulated_tran } } -void EditorNavigationMeshGenerator::_convert_detail_mesh_to_native_navigation_mesh(const rcPolyMeshDetail *p_detail_mesh, Ref<NavigationMesh> p_nav_mesh) { +void NavigationMeshGenerator::_convert_detail_mesh_to_native_navigation_mesh(const rcPolyMeshDetail *p_detail_mesh, Ref<NavigationMesh> p_nav_mesh) { PoolVector<Vector3> nav_vertices; @@ -298,11 +305,24 @@ void EditorNavigationMeshGenerator::_convert_detail_mesh_to_native_navigation_me } } -void EditorNavigationMeshGenerator::_build_recast_navigation_mesh(Ref<NavigationMesh> p_nav_mesh, EditorProgress *ep, - rcHeightfield *hf, rcCompactHeightfield *chf, rcContourSet *cset, rcPolyMesh *poly_mesh, rcPolyMeshDetail *detail_mesh, - Vector<float> &vertices, Vector<int> &indices) { +void NavigationMeshGenerator::_build_recast_navigation_mesh( + Ref<NavigationMesh> p_nav_mesh, +#ifdef TOOLS_ENABLED + EditorProgress *ep, +#endif + rcHeightfield *hf, + rcCompactHeightfield *chf, + rcContourSet *cset, + rcPolyMesh *poly_mesh, + rcPolyMeshDetail *detail_mesh, + Vector<float> &vertices, + Vector<int> &indices) { rcContext ctx; - ep->step(TTR("Setting up Configuration..."), 1); + +#ifdef TOOLS_ENABLED + if (ep) + ep->step(TTR("Setting up Configuration..."), 1); +#endif const float *verts = vertices.ptr(); const int nverts = vertices.size() / 3; @@ -336,16 +356,25 @@ void EditorNavigationMeshGenerator::_build_recast_navigation_mesh(Ref<Navigation cfg.bmax[1] = bmax[1]; cfg.bmax[2] = bmax[2]; - ep->step(TTR("Calculating grid size..."), 2); +#ifdef TOOLS_ENABLED + if (ep) + ep->step(TTR("Calculating grid size..."), 2); +#endif rcCalcGridSize(cfg.bmin, cfg.bmax, cfg.cs, &cfg.width, &cfg.height); - ep->step(TTR("Creating heightfield..."), 3); +#ifdef TOOLS_ENABLED + if (ep) + ep->step(TTR("Creating heightfield..."), 3); +#endif hf = rcAllocHeightfield(); ERR_FAIL_COND(!hf); ERR_FAIL_COND(!rcCreateHeightfield(&ctx, *hf, cfg.width, cfg.height, cfg.bmin, cfg.bmax, cfg.cs, cfg.ch)); - ep->step(TTR("Marking walkable triangles..."), 4); +#ifdef TOOLS_ENABLED + if (ep) + ep->step(TTR("Marking walkable triangles..."), 4); +#endif { Vector<unsigned char> tri_areas; tri_areas.resize(ntris); @@ -365,7 +394,10 @@ void EditorNavigationMeshGenerator::_build_recast_navigation_mesh(Ref<Navigation if (p_nav_mesh->get_filter_walkable_low_height_spans()) rcFilterWalkableLowHeightSpans(&ctx, cfg.walkableHeight, *hf); - ep->step(TTR("Constructing compact heightfield..."), 5); +#ifdef TOOLS_ENABLED + if (ep) + ep->step(TTR("Constructing compact heightfield..."), 5); +#endif chf = rcAllocCompactHeightfield(); @@ -375,10 +407,18 @@ void EditorNavigationMeshGenerator::_build_recast_navigation_mesh(Ref<Navigation rcFreeHeightField(hf); hf = 0; - ep->step(TTR("Eroding walkable area..."), 6); +#ifdef TOOLS_ENABLED + if (ep) + ep->step(TTR("Eroding walkable area..."), 6); +#endif + ERR_FAIL_COND(!rcErodeWalkableArea(&ctx, cfg.walkableRadius, *chf)); - ep->step(TTR("Partitioning..."), 7); +#ifdef TOOLS_ENABLED + if (ep) + ep->step(TTR("Partitioning..."), 7); +#endif + if (p_nav_mesh->get_sample_partition_type() == NavigationMesh::SAMPLE_PARTITION_WATERSHED) { ERR_FAIL_COND(!rcBuildDistanceField(&ctx, *chf)); ERR_FAIL_COND(!rcBuildRegions(&ctx, *chf, 0, cfg.minRegionArea, cfg.mergeRegionArea)); @@ -388,14 +428,20 @@ void EditorNavigationMeshGenerator::_build_recast_navigation_mesh(Ref<Navigation ERR_FAIL_COND(!rcBuildLayerRegions(&ctx, *chf, 0, cfg.minRegionArea)); } - ep->step(TTR("Creating contours..."), 8); +#ifdef TOOLS_ENABLED + if (ep) + ep->step(TTR("Creating contours..."), 8); +#endif cset = rcAllocContourSet(); ERR_FAIL_COND(!cset); ERR_FAIL_COND(!rcBuildContours(&ctx, *chf, cfg.maxSimplificationError, cfg.maxEdgeLen, *cset)); - ep->step(TTR("Creating polymesh..."), 9); +#ifdef TOOLS_ENABLED + if (ep) + ep->step(TTR("Creating polymesh..."), 9); +#endif poly_mesh = rcAllocPolyMesh(); ERR_FAIL_COND(!poly_mesh); @@ -410,7 +456,10 @@ void EditorNavigationMeshGenerator::_build_recast_navigation_mesh(Ref<Navigation rcFreeContourSet(cset); cset = 0; - ep->step(TTR("Converting to native navigation mesh..."), 10); +#ifdef TOOLS_ENABLED + if (ep) + ep->step(TTR("Converting to native navigation mesh..."), 10); +#endif _convert_detail_mesh_to_native_navigation_mesh(detail_mesh, p_nav_mesh); @@ -420,23 +469,30 @@ void EditorNavigationMeshGenerator::_build_recast_navigation_mesh(Ref<Navigation detail_mesh = 0; } -EditorNavigationMeshGenerator *EditorNavigationMeshGenerator::get_singleton() { +NavigationMeshGenerator *NavigationMeshGenerator::get_singleton() { return singleton; } -EditorNavigationMeshGenerator::EditorNavigationMeshGenerator() { +NavigationMeshGenerator::NavigationMeshGenerator() { singleton = this; } -EditorNavigationMeshGenerator::~EditorNavigationMeshGenerator() { +NavigationMeshGenerator::~NavigationMeshGenerator() { } -void EditorNavigationMeshGenerator::bake(Ref<NavigationMesh> p_nav_mesh, Node *p_node) { +void NavigationMeshGenerator::bake(Ref<NavigationMesh> p_nav_mesh, Node *p_node) { ERR_FAIL_COND(!p_nav_mesh.is_valid()); - EditorProgress ep("bake", TTR("Navigation Mesh Generator Setup:"), 11); - ep.step(TTR("Parsing Geometry..."), 0); +#ifdef TOOLS_ENABLED + EditorProgress *ep(NULL); + if (Engine::get_singleton()->is_editor_hint()) { + ep = memnew(EditorProgress("bake", TTR("Navigation Mesh Generator Setup:"), 11)); + } + + if (ep) + ep->step(TTR("Parsing Geometry..."), 0); +#endif Vector<float> vertices; Vector<int> indices; @@ -465,7 +521,18 @@ void EditorNavigationMeshGenerator::bake(Ref<NavigationMesh> p_nav_mesh, Node *p rcPolyMesh *poly_mesh = NULL; rcPolyMeshDetail *detail_mesh = NULL; - _build_recast_navigation_mesh(p_nav_mesh, &ep, hf, chf, cset, poly_mesh, detail_mesh, vertices, indices); + _build_recast_navigation_mesh( + p_nav_mesh, +#ifdef TOOLS_ENABLED + ep, +#endif + hf, + chf, + cset, + poly_mesh, + detail_mesh, + vertices, + indices); rcFreeHeightField(hf); hf = 0; @@ -482,17 +549,26 @@ void EditorNavigationMeshGenerator::bake(Ref<NavigationMesh> p_nav_mesh, Node *p rcFreePolyMeshDetail(detail_mesh); detail_mesh = 0; } - ep.step(TTR("Done!"), 11); + +#ifdef TOOLS_ENABLED + if (ep) + ep->step(TTR("Done!"), 11); + + if (ep) + memdelete(ep); +#endif } -void EditorNavigationMeshGenerator::clear(Ref<NavigationMesh> p_nav_mesh) { +void NavigationMeshGenerator::clear(Ref<NavigationMesh> p_nav_mesh) { if (p_nav_mesh.is_valid()) { p_nav_mesh->clear_polygons(); p_nav_mesh->set_vertices(PoolVector<Vector3>()); } } -void EditorNavigationMeshGenerator::_bind_methods() { - ClassDB::bind_method(D_METHOD("bake", "nav_mesh", "root_node"), &EditorNavigationMeshGenerator::bake); - ClassDB::bind_method(D_METHOD("clear", "nav_mesh"), &EditorNavigationMeshGenerator::clear); +void NavigationMeshGenerator::_bind_methods() { + ClassDB::bind_method(D_METHOD("bake", "nav_mesh", "root_node"), &NavigationMeshGenerator::bake); + ClassDB::bind_method(D_METHOD("clear", "nav_mesh"), &NavigationMeshGenerator::clear); } + +#endif diff --git a/modules/recast/navigation_mesh_generator.h b/modules/gdnavigation/navigation_mesh_generator.h index 8c7ca8b62c..107dee75e2 100644 --- a/modules/recast/navigation_mesh_generator.h +++ b/modules/gdnavigation/navigation_mesh_generator.h @@ -31,15 +31,20 @@ #ifndef NAVIGATION_MESH_GENERATOR_H #define NAVIGATION_MESH_GENERATOR_H -#include "editor/editor_node.h" -#include "scene/3d/navigation_mesh.h" +#ifndef _3D_DISABLED + +#include "scene/3d/navigation_mesh_instance.h" #include <Recast.h> -class EditorNavigationMeshGenerator : public Object { - GDCLASS(EditorNavigationMeshGenerator, Object); +#ifdef TOOLS_ENABLED +struct EditorProgress; +#endif + +class NavigationMeshGenerator : public Object { + GDCLASS(NavigationMeshGenerator, Object); - static EditorNavigationMeshGenerator *singleton; + static NavigationMeshGenerator *singleton; protected: static void _bind_methods(); @@ -50,18 +55,29 @@ protected: static void _parse_geometry(Transform p_accumulated_transform, Node *p_node, Vector<float> &p_verticies, Vector<int> &p_indices, int p_generate_from, uint32_t p_collision_mask, bool p_recurse_children); static void _convert_detail_mesh_to_native_navigation_mesh(const rcPolyMeshDetail *p_detail_mesh, Ref<NavigationMesh> p_nav_mesh); - static void _build_recast_navigation_mesh(Ref<NavigationMesh> p_nav_mesh, EditorProgress *ep, - rcHeightfield *hf, rcCompactHeightfield *chf, rcContourSet *cset, rcPolyMesh *poly_mesh, - rcPolyMeshDetail *detail_mesh, Vector<float> &vertices, Vector<int> &indices); + static void _build_recast_navigation_mesh( + Ref<NavigationMesh> p_nav_mesh, +#ifdef TOOLS_ENABLED + EditorProgress *ep, +#endif + rcHeightfield *hf, + rcCompactHeightfield *chf, + rcContourSet *cset, + rcPolyMesh *poly_mesh, + rcPolyMeshDetail *detail_mesh, + Vector<float> &vertices, + Vector<int> &indices); public: - static EditorNavigationMeshGenerator *get_singleton(); + static NavigationMeshGenerator *get_singleton(); - EditorNavigationMeshGenerator(); - ~EditorNavigationMeshGenerator(); + NavigationMeshGenerator(); + ~NavigationMeshGenerator(); void bake(Ref<NavigationMesh> p_nav_mesh, Node *p_node); void clear(Ref<NavigationMesh> p_nav_mesh); }; +#endif + #endif // NAVIGATION_MESH_GENERATOR_H diff --git a/modules/recast/register_types.cpp b/modules/gdnavigation/register_types.cpp index ea0ab00771..d717733787 100644 --- a/modules/recast/register_types.cpp +++ b/modules/gdnavigation/register_types.cpp @@ -30,30 +30,51 @@ #include "register_types.h" -#include "navigation_mesh_editor_plugin.h" +#include "core/engine.h" +#include "gd_navigation_server.h" +#include "servers/navigation_server.h" -#ifdef TOOLS_ENABLED -EditorNavigationMeshGenerator *_nav_mesh_generator = NULL; +#ifndef _3D_DISABLED +#include "navigation_mesh_generator.h" #endif -void register_recast_types() { #ifdef TOOLS_ENABLED - ClassDB::APIType prev_api = ClassDB::get_current_api(); - ClassDB::set_current_api(ClassDB::API_EDITOR); +#include "navigation_mesh_editor_plugin.h" +#endif - EditorPlugins::add_by_type<NavigationMeshEditorPlugin>(); - _nav_mesh_generator = memnew(EditorNavigationMeshGenerator); +/** + @author AndreaCatania +*/ - ClassDB::register_class<EditorNavigationMeshGenerator>(); +#ifndef _3D_DISABLED +NavigationMeshGenerator *_nav_mesh_generator = NULL; +#endif + +NavigationServer *new_server() { + return memnew(GdNavigationServer); +} - Engine::get_singleton()->add_singleton(Engine::Singleton("NavigationMeshGenerator", EditorNavigationMeshGenerator::get_singleton())); +void register_gdnavigation_types() { + NavigationServerManager::set_default_server(new_server); + +#ifndef _3D_DISABLED + _nav_mesh_generator = memnew(NavigationMeshGenerator); + ClassDB::register_class<NavigationMeshGenerator>(); + Engine::get_singleton()->add_singleton(Engine::Singleton("NavigationMeshGenerator", NavigationMeshGenerator::get_singleton())); +#endif + +#ifdef TOOLS_ENABLED + EditorPlugins::add_by_type<NavigationMeshEditorPlugin>(); + + ClassDB::APIType prev_api = ClassDB::get_current_api(); + ClassDB::set_current_api(ClassDB::API_EDITOR); ClassDB::set_current_api(prev_api); #endif } -void unregister_recast_types() { -#ifdef TOOLS_ENABLED +void unregister_gdnavigation_types() { +#ifndef _3D_DISABLED if (_nav_mesh_generator) { memdelete(_nav_mesh_generator); } diff --git a/modules/gdnavigation/register_types.h b/modules/gdnavigation/register_types.h new file mode 100644 index 0000000000..bd15eaaada --- /dev/null +++ b/modules/gdnavigation/register_types.h @@ -0,0 +1,36 @@ +/*************************************************************************/ +/* register_types.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. */ +/*************************************************************************/ + +/** + @author AndreaCatania +*/ + +void register_gdnavigation_types(); +void unregister_gdnavigation_types(); diff --git a/modules/gdnavigation/rvo_agent.cpp b/modules/gdnavigation/rvo_agent.cpp new file mode 100644 index 0000000000..4d19bc15af --- /dev/null +++ b/modules/gdnavigation/rvo_agent.cpp @@ -0,0 +1,84 @@ +/*************************************************************************/ +/* rvo_agent.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 "rvo_agent.h" + +#include "nav_map.h" + +/** + @author AndreaCatania +*/ + +RvoAgent::RvoAgent() : + map(NULL) { + callback.id = ObjectID(); +} + +void RvoAgent::set_map(NavMap *p_map) { + map = p_map; +} + +bool RvoAgent::is_map_changed() { + if (map) { + bool is_changed = map->get_map_update_id() != map_update_id; + map_update_id = map->get_map_update_id(); + return is_changed; + } else { + return false; + } +} + +void RvoAgent::set_callback(ObjectID p_id, const StringName p_method, const Variant p_udata) { + callback.id = p_id; + callback.method = p_method; + callback.udata = p_udata; +} + +bool RvoAgent::has_callback() const { + return callback.id.is_valid(); +} + +void RvoAgent::dispatch_callback() { + if (callback.id.is_null()) { + return; + } + Object *obj = ObjectDB::get_instance(callback.id); + if (obj == NULL) { + callback.id = ObjectID(); + } + + Variant::CallError responseCallError; + + callback.new_velocity = Vector3(agent.newVelocity_.x(), agent.newVelocity_.y(), agent.newVelocity_.z()); + + const Variant *vp[2] = { &callback.new_velocity, &callback.udata }; + int argc = (callback.udata.get_type() == Variant::NIL) ? 1 : 2; + obj->call(callback.method, vp, argc, responseCallError); +} diff --git a/modules/gdnavigation/rvo_agent.h b/modules/gdnavigation/rvo_agent.h new file mode 100644 index 0000000000..914cbaa7d9 --- /dev/null +++ b/modules/gdnavigation/rvo_agent.h @@ -0,0 +1,77 @@ +/*************************************************************************/ +/* rvo_agent.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 RVO_AGENT_H +#define RVO_AGENT_H + +#include "core/object.h" +#include "nav_rid.h" +#include <Agent.h> + +/** + @author AndreaCatania +*/ + +class NavMap; + +class RvoAgent : public NavRid { + struct AvoidanceComputedCallback { + ObjectID id; + StringName method; + Variant udata; + Variant new_velocity; + }; + + NavMap *map; + RVO::Agent agent; + AvoidanceComputedCallback callback; + uint32_t map_update_id; + +public: + RvoAgent(); + + void set_map(NavMap *p_map); + NavMap *get_map() { + return map; + } + + RVO::Agent *get_agent() { + return &agent; + } + + bool is_map_changed(); + + void set_callback(ObjectID p_id, const StringName p_method, const Variant p_udata = Variant()); + bool has_callback() const; + + void dispatch_callback(); +}; + +#endif // RVO_AGENT_H diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml index b947d95fac..9fc8ad5573 100644 --- a/modules/gdscript/doc_classes/@GDScript.xml +++ b/modules/gdscript/doc_classes/@GDScript.xml @@ -256,15 +256,6 @@ Converts from decibels to linear energy (audio). </description> </method> - <method name="decimals"> - <return type="int"> - </return> - <argument index="0" name="step" type="float"> - </argument> - <description> - Deprecated alias for [method step_decimals]. - </description> - </method> <method name="dectime"> <return type="float"> </return> diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index a255b92257..07c74a2e26 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -30,6 +30,8 @@ #include "gdscript.h" +#include <stdint.h> + #include "core/core_string_names.h" #include "core/engine.h" #include "core/global_constants.h" @@ -91,6 +93,7 @@ GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argco instance->members.resize(member_indices.size()); instance->script = Ref<GDScript>(this); instance->owner = p_owner; + instance->owner_id = p_owner->get_instance_id(); #ifdef DEBUG_ENABLED //needed for hot reloading for (Map<StringName, MemberInfo>::Element *E = member_indices.front(); E; E = E->next()) { @@ -610,6 +613,53 @@ Error GDScript::reload(bool p_keep_state) { _set_subclass_path(E->get(), path); } + // Copy the base rpc methods so we don't mask their IDs. + rpc_functions.clear(); + rpc_variables.clear(); + if (base.is_valid()) { + rpc_functions = base->rpc_functions; + rpc_variables = base->rpc_variables; + } + + GDScript *cscript = this; + Map<StringName, Ref<GDScript> >::Element *sub_E = subclasses.front(); + while (cscript) { + // RPC Methods + for (Map<StringName, GDScriptFunction *>::Element *E = cscript->member_functions.front(); E; E = E->next()) { + if (E->get()->get_rpc_mode() != MultiplayerAPI::RPC_MODE_DISABLED) { + ScriptNetData nd; + nd.name = E->key(); + nd.mode = E->get()->get_rpc_mode(); + if (-1 == rpc_functions.find(nd)) { + rpc_functions.push_back(nd); + } + } + } + // RSet + for (Map<StringName, MemberInfo>::Element *E = cscript->member_indices.front(); E; E = E->next()) { + if (E->get().rpc_mode != MultiplayerAPI::RPC_MODE_DISABLED) { + ScriptNetData nd; + nd.name = E->key(); + nd.mode = E->get().rpc_mode; + if (-1 == rpc_variables.find(nd)) { + rpc_variables.push_back(nd); + } + } + } + + if (cscript != this) + sub_E = sub_E->next(); + + if (sub_E) + cscript = sub_E->get().ptr(); + else + cscript = NULL; + } + + // Sort so we are 100% that they are always the same. + rpc_functions.sort_custom<SortNetData>(); + rpc_variables.sort_custom<SortNetData>(); + return OK; } @@ -635,6 +685,60 @@ void GDScript::get_members(Set<StringName> *p_members) { } } +Vector<ScriptNetData> GDScript::get_rpc_methods() const { + return rpc_functions; +} + +uint16_t GDScript::get_rpc_method_id(const StringName &p_method) const { + for (int i = 0; i < rpc_functions.size(); i++) { + if (rpc_functions[i].name == p_method) { + return i; + } + } + return UINT16_MAX; +} + +StringName GDScript::get_rpc_method(const uint16_t p_rpc_method_id) const { + ERR_FAIL_COND_V(p_rpc_method_id >= rpc_functions.size(), StringName()); + return rpc_functions[p_rpc_method_id].name; +} + +MultiplayerAPI::RPCMode GDScript::get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const { + ERR_FAIL_COND_V(p_rpc_method_id >= rpc_functions.size(), MultiplayerAPI::RPC_MODE_DISABLED); + return rpc_functions[p_rpc_method_id].mode; +} + +MultiplayerAPI::RPCMode GDScript::get_rpc_mode(const StringName &p_method) const { + return get_rpc_mode_by_id(get_rpc_method_id(p_method)); +} + +Vector<ScriptNetData> GDScript::get_rset_properties() const { + return rpc_variables; +} + +uint16_t GDScript::get_rset_property_id(const StringName &p_variable) const { + for (int i = 0; i < rpc_variables.size(); i++) { + if (rpc_variables[i].name == p_variable) { + return i; + } + } + return UINT16_MAX; +} + +StringName GDScript::get_rset_property(const uint16_t p_rset_member_id) const { + ERR_FAIL_COND_V(p_rset_member_id >= rpc_variables.size(), StringName()); + return rpc_variables[p_rset_member_id].name; +} + +MultiplayerAPI::RPCMode GDScript::get_rset_mode_by_id(const uint16_t p_rset_member_id) const { + ERR_FAIL_COND_V(p_rset_member_id >= rpc_functions.size(), MultiplayerAPI::RPC_MODE_DISABLED); + return rpc_functions[p_rset_member_id].mode; +} + +MultiplayerAPI::RPCMode GDScript::get_rset_mode(const StringName &p_variable) const { + return get_rset_mode_by_id(get_rset_property_id(p_variable)); +} + Variant GDScript::call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) { GDScript *top = this; @@ -1291,40 +1395,44 @@ ScriptLanguage *GDScriptInstance::get_language() { return GDScriptLanguage::get_singleton(); } -MultiplayerAPI::RPCMode GDScriptInstance::get_rpc_mode(const StringName &p_method) const { +Vector<ScriptNetData> GDScriptInstance::get_rpc_methods() const { + return script->get_rpc_methods(); +} - const GDScript *cscript = script.ptr(); +uint16_t GDScriptInstance::get_rpc_method_id(const StringName &p_method) const { + return script->get_rpc_method_id(p_method); +} - while (cscript) { - const Map<StringName, GDScriptFunction *>::Element *E = cscript->member_functions.find(p_method); - if (E) { +StringName GDScriptInstance::get_rpc_method(const uint16_t p_rpc_method_id) const { + return script->get_rpc_method(p_rpc_method_id); +} - if (E->get()->get_rpc_mode() != MultiplayerAPI::RPC_MODE_DISABLED) { - return E->get()->get_rpc_mode(); - } - } - cscript = cscript->_base; - } +MultiplayerAPI::RPCMode GDScriptInstance::get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const { + return script->get_rpc_mode_by_id(p_rpc_method_id); +} - return MultiplayerAPI::RPC_MODE_DISABLED; +MultiplayerAPI::RPCMode GDScriptInstance::get_rpc_mode(const StringName &p_method) const { + return script->get_rpc_mode(p_method); } -MultiplayerAPI::RPCMode GDScriptInstance::get_rset_mode(const StringName &p_variable) const { +Vector<ScriptNetData> GDScriptInstance::get_rset_properties() const { + return script->get_rset_properties(); +} - const GDScript *cscript = script.ptr(); +uint16_t GDScriptInstance::get_rset_property_id(const StringName &p_variable) const { + return script->get_rset_property_id(p_variable); +} - while (cscript) { - const Map<StringName, GDScript::MemberInfo>::Element *E = cscript->member_indices.find(p_variable); - if (E) { +StringName GDScriptInstance::get_rset_property(const uint16_t p_rset_member_id) const { + return script->get_rset_property(p_rset_member_id); +} - if (E->get().rpc_mode) { - return E->get().rpc_mode; - } - } - cscript = cscript->_base; - } +MultiplayerAPI::RPCMode GDScriptInstance::get_rset_mode_by_id(const uint16_t p_rset_member_id) const { + return script->get_rset_mode_by_id(p_rset_member_id); +} - return MultiplayerAPI::RPC_MODE_DISABLED; +MultiplayerAPI::RPCMode GDScriptInstance::get_rset_mode(const StringName &p_variable) const { + return script->get_rset_mode(p_variable); } void GDScriptInstance::reload_members() { @@ -1685,7 +1793,7 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so obj->get_script_instance()->get_property_state(state); map[obj->get_instance_id()] = state; - obj->set_script(RefPtr()); + obj->set_script(Variant()); } } @@ -1701,7 +1809,7 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so map.insert(obj->get_instance_id(), List<Pair<StringName, Variant> >()); List<Pair<StringName, Variant> > &state = map[obj->get_instance_id()]; obj->get_script_instance()->get_property_state(state); - obj->set_script(RefPtr()); + obj->set_script(Variant()); } else { // no instance found. Let's remove it so we don't loop forever E->get()->placeholders.erase(E->get()->placeholders.front()->get()); @@ -1732,9 +1840,9 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so if (!p_soft_reload) { //clear it just in case (may be a pending reload state) - obj->set_script(RefPtr()); + obj->set_script(Variant()); } - obj->set_script(scr.get_ref_ptr()); + obj->set_script(scr); ScriptInstance *script_instance = obj->get_script_instance(); @@ -1850,10 +1958,8 @@ void GDScriptLanguage::get_reserved_words(List<String> *p_words) const { "match", "while", "remote", - "sync", "master", "puppet", - "slave", "remotesync", "mastersync", "puppetsync", diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index 4ae52238ce..3d24f9b3f5 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -85,6 +85,8 @@ class GDScript : public Script { Map<StringName, MemberInfo> member_indices; //members are just indices to the instanced script. Map<StringName, Ref<GDScript> > subclasses; Map<StringName, Vector<StringName> > _signals; + Vector<ScriptNetData> rpc_functions; + Vector<ScriptNetData> rpc_variables; #ifdef TOOLS_ENABLED @@ -213,6 +215,18 @@ public: virtual void get_constants(Map<StringName, Variant> *p_constants); virtual void get_members(Set<StringName> *p_members); + virtual Vector<ScriptNetData> get_rpc_methods() const; + virtual uint16_t get_rpc_method_id(const StringName &p_method) const; + virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const; + virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const; + virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const; + + virtual Vector<ScriptNetData> get_rset_properties() const; + virtual uint16_t get_rset_property_id(const StringName &p_variable) const; + virtual StringName get_rset_property(const uint16_t p_variable_id) const; + virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_variable_id) const; + virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const; + #ifdef TOOLS_ENABLED virtual bool is_placeholder_fallback_enabled() const { return placeholder_fallback_enabled; } #endif @@ -227,6 +241,7 @@ class GDScriptInstance : public ScriptInstance { friend class GDScriptFunctions; friend class GDScriptCompiler; + ObjectID owner_id; Object *owner; Ref<GDScript> script; #ifdef DEBUG_ENABLED @@ -264,7 +279,16 @@ public: void reload_members(); + virtual Vector<ScriptNetData> get_rpc_methods() const; + virtual uint16_t get_rpc_method_id(const StringName &p_method) const; + virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const; + virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const; virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const; + + virtual Vector<ScriptNetData> get_rset_properties() const; + virtual uint16_t get_rset_property_id(const StringName &p_variable) const; + virtual StringName get_rset_property(const uint16_t p_variable_id) const; + virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_variable_id) const; virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const; GDScriptInstance(); diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index 65c61cb57c..c2c8ff5b99 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -2186,7 +2186,7 @@ static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p "and", "in", "not", "or", "false", "PI", "TAU", "INF", "NAN", "self", "true", "as", "assert", "breakpoint", "class", "extends", "is", "func", "preload", "setget", "signal", "tool", "yield", "const", "enum", "export", "onready", "static", "var", "break", "continue", "if", "elif", - "else", "for", "pass", "return", "match", "while", "remote", "sync", "master", "puppet", "slave", + "else", "for", "pass", "return", "match", "while", "remote", "master", "puppet", "remotesync", "mastersync", "puppetsync", 0 }; diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp index 452b1933eb..cbf7d81a61 100644 --- a/modules/gdscript/gdscript_function.cpp +++ b/modules/gdscript/gdscript_function.cpp @@ -137,18 +137,19 @@ static String _get_var_type(const Variant *p_var) { String basestr; if (p_var->get_type() == Variant::OBJECT) { - Object *bobj = *p_var; + bool was_freed; + Object *bobj = p_var->get_validated_object_with_check(was_freed); if (!bobj) { - basestr = "null instance"; - } else { - if (ObjectDB::instance_validate(bobj)) { - if (bobj->get_script_instance()) - basestr = bobj->get_class() + " (" + bobj->get_script_instance()->get_script()->get_path().get_file() + ")"; - else - basestr = bobj->get_class(); + if (was_freed) { + basestr = "null instance"; } else { - basestr = "previously freed instance"; + basestr = "previously freed"; } + } else { + if (bobj->get_script_instance()) + basestr = bobj->get_class() + " (" + bobj->get_script_instance()->get_script()->get_path().get_file() + ")"; + else + basestr = bobj->get_class(); } } else { @@ -497,14 +498,26 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a bool extends_ok = false; if (a->get_type() == Variant::OBJECT && a->operator Object *() != NULL) { - Object *obj_A = *a; - Object *obj_B = *b; #ifdef DEBUG_ENABLED - if (!ObjectDB::instance_validate(obj_A)) { - err_text = "Left operand of 'is' was already freed."; + bool was_freed; + Object *obj_A = a->get_validated_object_with_check(was_freed); + + if (was_freed) { + err_text = "Left operand of 'is' is a previously freed instance."; OPCODE_BREAK; } + + Object *obj_B = b->get_validated_object_with_check(was_freed); + + if (was_freed) { + err_text = "Right operand of 'is' is a previously freed instance."; + OPCODE_BREAK; + } +#else + + Object *obj_A = *a; + Object *obj_B = *b; #endif // DEBUG_ENABLED GDScript *scr_B = Object::cast_to<GDScript>(obj_B); @@ -1274,7 +1287,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a gdfs->state.script = Ref<GDScript>(_script); gdfs->state.ip = ip + ipofs; gdfs->state.line = line; - gdfs->state.instance_id = (p_instance && p_instance->get_owner()) ? p_instance->get_owner()->get_instance_id() : 0; + gdfs->state.instance_id = (p_instance && p_instance->get_owner()) ? p_instance->get_owner()->get_instance_id() : ObjectID(); //gdfs->state.result_pos=ip+ipofs-1; gdfs->state.defarg = defarg; gdfs->state.instance = p_instance; @@ -1298,20 +1311,20 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a } #endif - Object *obj = argobj->operator Object *(); +#ifdef DEBUG_ENABLED + bool was_freed; + Object *obj = argobj->get_validated_object_with_check(was_freed); String signal = argname->operator String(); -#ifdef DEBUG_ENABLED + if (was_freed) { + err_text = "First argument of yield() is a previously freed instance."; + OPCODE_BREAK; + } + if (!obj) { err_text = "First argument of yield() is null."; OPCODE_BREAK; } - if (ScriptDebugger::get_singleton()) { - if (!ObjectDB::instance_validate(obj)) { - err_text = "First argument of yield() is a previously freed instance."; - OPCODE_BREAK; - } - } if (signal.length() == 0) { err_text = "Second argument of yield() is an empty string (for signal name)."; @@ -1324,6 +1337,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE_BREAK; } #else + Object *obj = argobj->operator Object *(); + String signal = argname->operator String(); + obj->connect(signal, gdfs.ptr(), "_signal_callback", varray(gdfs), Object::CONNECT_ONESHOT); #endif } @@ -1565,14 +1581,14 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a //error // function, file, line, error, explanation String err_file; - if (p_instance && ObjectDB::instance_validate(p_instance->owner) && p_instance->script->is_valid() && p_instance->script->path != "") + if (p_instance && ObjectDB::get_instance(p_instance->owner_id) != nullptr && p_instance->script->is_valid() && p_instance->script->path != "") err_file = p_instance->script->path; else if (script) err_file = script->path; if (err_file == "") err_file = "<built-in>"; String err_func = name; - if (p_instance && ObjectDB::instance_validate(p_instance->owner) && p_instance->script->is_valid() && p_instance->script->name != "") + if (p_instance && ObjectDB::get_instance(p_instance->owner_id) != nullptr && p_instance->script->is_valid() && p_instance->script->name != "") err_func = p_instance->script->name + "." + err_func; int err_line = line; if (err_text == "") { @@ -1829,7 +1845,7 @@ bool GDScriptFunctionState::is_valid(bool p_extended_check) const { if (p_extended_check) { //class instance gone? - if (state.instance_id && !ObjectDB::get_instance(state.instance_id)) + if (state.instance_id.is_valid() && !ObjectDB::get_instance(state.instance_id)) return false; } @@ -1839,7 +1855,7 @@ bool GDScriptFunctionState::is_valid(bool p_extended_check) const { Variant GDScriptFunctionState::resume(const Variant &p_arg) { ERR_FAIL_COND_V(!function, Variant()); - if (state.instance_id && !ObjectDB::get_instance(state.instance_id)) { + if (state.instance_id.is_valid() && !ObjectDB::get_instance(state.instance_id)) { #ifdef DEBUG_ENABLED ERR_FAIL_V_MSG(Variant(), "Resumed function '" + String(function->get_name()) + "()' after yield, but class instance is gone. At script: " + state.script->get_path() + ":" + itos(state.line)); #else diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h index ad95ebc543..7b7bcbaac9 100644 --- a/modules/gdscript/gdscript_function.h +++ b/modules/gdscript/gdscript_function.h @@ -77,8 +77,8 @@ struct GDScriptDataType { return false; } - Object *obj = p_variant.operator Object *(); - if (!obj || !ObjectDB::instance_validate(obj)) { + Object *obj = p_variant.get_validated_object(); + if (!obj) { return false; } @@ -100,8 +100,8 @@ struct GDScriptDataType { return false; } - Object *obj = p_variant.operator Object *(); - if (!obj || !ObjectDB::instance_validate(obj)) { + Object *obj = p_variant.get_validated_object(); + if (!obj) { return false; } diff --git a/modules/gdscript/gdscript_functions.cpp b/modules/gdscript/gdscript_functions.cpp index 01d62a1c62..a46337d7dd 100644 --- a/modules/gdscript/gdscript_functions.cpp +++ b/modules/gdscript/gdscript_functions.cpp @@ -72,7 +72,6 @@ const char *GDScriptFunctions::get_func_name(Function p_func) { "is_equal_approx", "is_zero_approx", "ease", - "decimals", "step_decimals", "stepify", "lerp", @@ -346,12 +345,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ VALIDATE_ARG_NUM(1); r_ret = Math::ease((double)*p_args[0], (double)*p_args[1]); } break; - case MATH_DECIMALS: { - VALIDATE_ARG_COUNT(1); - VALIDATE_ARG_NUM(0); - r_ret = Math::step_decimals((double)*p_args[0]); - WARN_DEPRECATED_MSG("GDScript method 'decimals' is deprecated and has been renamed to 'step_decimals', please update your code accordingly."); - } break; case MATH_STEP_DECIMALS: { VALIDATE_ARG_COUNT(1); VALIDATE_ARG_NUM(0); @@ -800,7 +793,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ } String message = *p_args[0]; - ERR_PRINTS(message); + ERR_PRINT(message); r_ret = Variant(); } break; case PUSH_WARNING: { @@ -814,7 +807,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ } String message = *p_args[0]; - WARN_PRINTS(message); + WARN_PRINT(message); r_ret = Variant(); } break; case VAR_TO_STR: { @@ -1260,7 +1253,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ if (err != OK) { r_ret = Variant(); - ERR_PRINTS(vformat("Error parsing JSON at line %s: %s", errl, errs)); + ERR_PRINT(vformat("Error parsing JSON at line %s: %s", errl, errs)); } } break; @@ -1374,7 +1367,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ break; } - uint32_t id = *p_args[0]; + ObjectID id = *p_args[0]; r_ret = ObjectDB::get_instance(id); } break; @@ -1448,8 +1441,8 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ if (p_args[0]->get_type() != Variant::OBJECT) { r_ret = false; } else { - Object *obj = *p_args[0]; - r_ret = ObjectDB::instance_validate(obj); + Object *obj = p_args[0]->get_validated_object(); + r_ret = obj != nullptr; } } break; @@ -1492,7 +1485,6 @@ bool GDScriptFunctions::is_deterministic(Function p_func) { case MATH_ISNAN: case MATH_ISINF: case MATH_EASE: - case MATH_DECIMALS: case MATH_STEP_DECIMALS: case MATH_STEPIFY: case MATH_LERP: @@ -1673,11 +1665,6 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) { mi.return_val.type = Variant::REAL; return mi; } break; - case MATH_DECIMALS: { - MethodInfo mi("decimals", PropertyInfo(Variant::REAL, "step")); - mi.return_val.type = Variant::INT; - return mi; - } break; case MATH_STEP_DECIMALS: { MethodInfo mi("step_decimals", PropertyInfo(Variant::REAL, "step")); mi.return_val.type = Variant::INT; diff --git a/modules/gdscript/gdscript_functions.h b/modules/gdscript/gdscript_functions.h index 1812ddf121..8b97194ed6 100644 --- a/modules/gdscript/gdscript_functions.h +++ b/modules/gdscript/gdscript_functions.h @@ -63,7 +63,6 @@ public: MATH_ISEQUALAPPROX, MATH_ISZEROAPPROX, MATH_EASE, - MATH_DECIMALS, MATH_STEP_DECIMALS, MATH_STEPIFY, MATH_LERP, diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index d125da5b79..fae6fbbb0c 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -4099,10 +4099,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { _ADVANCE_AND_CONSUME_NEWLINES; - if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { - WARN_DEPRECATED_MSG("Exporting bit flags hint requires string constants."); - break; - } if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) { _set_error("Expected \",\" in the bit flags hint."); return; @@ -4588,10 +4584,10 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { #undef _ADVANCE_AND_CONSUME_NEWLINES } - if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_ONREADY && tokenizer->get_token() != GDScriptTokenizer::TK_PR_REMOTE && tokenizer->get_token() != GDScriptTokenizer::TK_PR_MASTER && tokenizer->get_token() != GDScriptTokenizer::TK_PR_PUPPET && tokenizer->get_token() != GDScriptTokenizer::TK_PR_SYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_REMOTESYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_MASTERSYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_PUPPETSYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_SLAVE) { + if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_ONREADY && tokenizer->get_token() != GDScriptTokenizer::TK_PR_REMOTE && tokenizer->get_token() != GDScriptTokenizer::TK_PR_MASTER && tokenizer->get_token() != GDScriptTokenizer::TK_PR_PUPPET && tokenizer->get_token() != GDScriptTokenizer::TK_PR_REMOTESYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_MASTERSYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_PUPPETSYNC) { current_export = PropertyInfo(); - _set_error("Expected \"var\", \"onready\", \"remote\", \"master\", \"puppet\", \"sync\", \"remotesync\", \"mastersync\", \"puppetsync\"."); + _set_error("Expected \"var\", \"onready\", \"remote\", \"master\", \"puppet\", \"remotesync\", \"mastersync\", \"puppetsync\"."); return; } @@ -4648,11 +4644,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { rpc_mode = MultiplayerAPI::RPC_MODE_MASTER; continue; } break; - case GDScriptTokenizer::TK_PR_SLAVE: -#ifdef DEBUG_ENABLED - _add_warning(GDScriptWarning::DEPRECATED_KEYWORD, tokenizer->get_token_line(), "slave", "puppet"); -#endif - FALLTHROUGH; case GDScriptTokenizer::TK_PR_PUPPET: { //may be fallthrough from export, ignore if so @@ -4673,8 +4664,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { rpc_mode = MultiplayerAPI::RPC_MODE_PUPPET; continue; } break; - case GDScriptTokenizer::TK_PR_REMOTESYNC: - case GDScriptTokenizer::TK_PR_SYNC: { + case GDScriptTokenizer::TK_PR_REMOTESYNC: { //may be fallthrough from export, ignore if so tokenizer->advance(); diff --git a/modules/gdscript/gdscript_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp index 11ffa22906..a0e0811c1f 100644 --- a/modules/gdscript/gdscript_tokenizer.cpp +++ b/modules/gdscript/gdscript_tokenizer.cpp @@ -106,11 +106,9 @@ const char *GDScriptTokenizer::token_names[TK_MAX] = { "yield", "signal", "breakpoint", - "rpc", - "sync", + "remote", "master", "puppet", - "slave", "remotesync", "mastersync", "puppetsync", @@ -207,9 +205,7 @@ static const _kws _keyword_list[] = { { GDScriptTokenizer::TK_PR_BREAKPOINT, "breakpoint" }, { GDScriptTokenizer::TK_PR_REMOTE, "remote" }, { GDScriptTokenizer::TK_PR_MASTER, "master" }, - { GDScriptTokenizer::TK_PR_SLAVE, "slave" }, { GDScriptTokenizer::TK_PR_PUPPET, "puppet" }, - { GDScriptTokenizer::TK_PR_SYNC, "sync" }, { GDScriptTokenizer::TK_PR_REMOTESYNC, "remotesync" }, { GDScriptTokenizer::TK_PR_MASTERSYNC, "mastersync" }, { GDScriptTokenizer::TK_PR_PUPPETSYNC, "puppetsync" }, @@ -255,7 +251,6 @@ bool GDScriptTokenizer::is_token_literal(int p_offset, bool variable_safe) const case TK_PR_REMOTE: case TK_PR_MASTER: case TK_PR_PUPPET: - case TK_PR_SYNC: case TK_PR_REMOTESYNC: case TK_PR_MASTERSYNC: case TK_PR_PUPPETSYNC: @@ -815,7 +810,7 @@ void GDScriptTokenizerText::_advance() { break; //wtf case 'u': { - //hexnumbarh - oct is deprecated + // hex number i += 1; for (int j = 0; j < 4; j++) { CharType c = GETCHAR(i + j); diff --git a/modules/gdscript/gdscript_tokenizer.h b/modules/gdscript/gdscript_tokenizer.h index 0efc8551cb..3694825d80 100644 --- a/modules/gdscript/gdscript_tokenizer.h +++ b/modules/gdscript/gdscript_tokenizer.h @@ -113,9 +113,7 @@ public: TK_PR_SIGNAL, TK_PR_BREAKPOINT, TK_PR_REMOTE, - TK_PR_SYNC, TK_PR_MASTER, - TK_PR_SLAVE, // Deprecated by TK_PR_PUPPET, to remove in 4.0 TK_PR_PUPPET, TK_PR_REMOTESYNC, TK_PR_MASTERSYNC, diff --git a/modules/gdscript/language_server/gdscript_text_document.cpp b/modules/gdscript/language_server/gdscript_text_document.cpp index 0572c5f746..d5723fd20f 100644 --- a/modules/gdscript/language_server/gdscript_text_document.cpp +++ b/modules/gdscript/language_server/gdscript_text_document.cpp @@ -321,6 +321,8 @@ Variant GDScriptTextDocument::hover(const Dictionary &p_params) { lsp::Hover hover; hover.contents = symbol->render(); + hover.range.start = params.position; + hover.range.end = params.position; return hover.to_json(); } else if (GDScriptLanguageProtocol::get_singleton()->is_smart_resolve_enabled()) { diff --git a/modules/glslang/SCsub b/modules/glslang/SCsub new file mode 100644 index 0000000000..8c9445436e --- /dev/null +++ b/modules/glslang/SCsub @@ -0,0 +1,68 @@ +#!/usr/bin/env python + +Import('env') +Import('env_modules') + +env_glslang = env_modules.Clone() + +# Thirdparty source files +if env['builtin_glslang']: + thirdparty_dir = "#thirdparty/glslang/" + thirdparty_sources = [ + "glslang/MachineIndependent/RemoveTree.cpp", + "glslang/MachineIndependent/ParseHelper.cpp", + "glslang/MachineIndependent/iomapper.cpp", + "glslang/MachineIndependent/propagateNoContraction.cpp", + "glslang/MachineIndependent/Intermediate.cpp", + "glslang/MachineIndependent/linkValidate.cpp", + "glslang/MachineIndependent/attribute.cpp", + "glslang/MachineIndependent/Scan.cpp", + "glslang/MachineIndependent/Initialize.cpp", + "glslang/MachineIndependent/Constant.cpp", + "glslang/MachineIndependent/reflection.cpp", + "glslang/MachineIndependent/limits.cpp", + "glslang/MachineIndependent/preprocessor/PpScanner.cpp", + "glslang/MachineIndependent/preprocessor/PpTokens.cpp", + "glslang/MachineIndependent/preprocessor/PpAtom.cpp", + "glslang/MachineIndependent/preprocessor/PpContext.cpp", + "glslang/MachineIndependent/preprocessor/Pp.cpp", + "glslang/MachineIndependent/InfoSink.cpp", + "glslang/MachineIndependent/intermOut.cpp", + "glslang/MachineIndependent/SymbolTable.cpp", + "glslang/MachineIndependent/glslang_tab.cpp", + "glslang/MachineIndependent/pch.cpp", + "glslang/MachineIndependent/Versions.cpp", + "glslang/MachineIndependent/ShaderLang.cpp", + "glslang/MachineIndependent/parseConst.cpp", + "glslang/MachineIndependent/PoolAlloc.cpp", + "glslang/MachineIndependent/ParseContextBase.cpp", + "glslang/MachineIndependent/IntermTraverse.cpp", + "glslang/GenericCodeGen/Link.cpp", + "glslang/GenericCodeGen/CodeGen.cpp", + "OGLCompilersDLL/InitializeDll.cpp", + "SPIRV/InReadableOrder.cpp", + "SPIRV/GlslangToSpv.cpp", + "SPIRV/SpvBuilder.cpp", + "SPIRV/SpvTools.cpp", + "SPIRV/disassemble.cpp", + "SPIRV/doc.cpp", + "SPIRV/SPVRemapper.cpp", + "SPIRV/SpvPostProcess.cpp", + "SPIRV/Logger.cpp" + ] + + if (env["platform"]=="windows"): + thirdparty_sources.append("glslang/OSDependent/Windows/ossource.cpp") + else: + thirdparty_sources.append("glslang/OSDependent/Unix/ossource.cpp") + + thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] + + env_glslang.Prepend(CPPPATH=[thirdparty_dir]) + + env_thirdparty = env_glslang.Clone() + env_thirdparty.disable_warnings() + env_thirdparty.add_source_files(env.modules_sources, thirdparty_sources) + +# Godot's own source files +env_glslang.add_source_files(env.modules_sources, "*.cpp") diff --git a/modules/glslang/config.py b/modules/glslang/config.py new file mode 100644 index 0000000000..1c8cd12a2d --- /dev/null +++ b/modules/glslang/config.py @@ -0,0 +1,5 @@ +def can_build(env, platform): + return True + +def configure(env): + pass diff --git a/modules/glslang/register_types.cpp b/modules/glslang/register_types.cpp new file mode 100644 index 0000000000..1e4481a6a0 --- /dev/null +++ b/modules/glslang/register_types.cpp @@ -0,0 +1,246 @@ +/*************************************************************************/ +/* register_types.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 "register_types.h" + +#include "servers/visual/rendering_device.h" + +#include <SPIRV/GlslangToSpv.h> +#include <glslang/Include/Types.h> +#include <glslang/Public/ShaderLang.h> + +static const TBuiltInResource default_builtin_resource = { + /*maxLights*/ 32, + /*maxClipPlanes*/ 6, + /*maxTextureUnits*/ 32, + /*maxTextureCoords*/ 32, + /*maxVertexAttribs*/ 64, + /*maxVertexUniformComponents*/ 4096, + /*maxVaryingFloats*/ 64, + /*maxVertexTextureImageUnits*/ 32, + /*maxCombinedTextureImageUnits*/ 80, + /*maxTextureImageUnits*/ 32, + /*maxFragmentUniformComponents*/ 4096, + /*maxDrawBuffers*/ 32, + /*maxVertexUniformVectors*/ 128, + /*maxVaryingVectors*/ 8, + /*maxFragmentUniformVectors*/ 16, + /*maxVertexOutputVectors*/ 16, + /*maxFragmentInputVectors*/ 15, + /*minProgramTexelOffset*/ -8, + /*maxProgramTexelOffset*/ 7, + /*maxClipDistances*/ 8, + /*maxComputeWorkGroupCountX*/ 65535, + /*maxComputeWorkGroupCountY*/ 65535, + /*maxComputeWorkGroupCountZ*/ 65535, + /*maxComputeWorkGroupSizeX*/ 1024, + /*maxComputeWorkGroupSizeY*/ 1024, + /*maxComputeWorkGroupSizeZ*/ 64, + /*maxComputeUniformComponents*/ 1024, + /*maxComputeTextureImageUnits*/ 16, + /*maxComputeImageUniforms*/ 8, + /*maxComputeAtomicCounters*/ 8, + /*maxComputeAtomicCounterBuffers*/ 1, + /*maxVaryingComponents*/ 60, + /*maxVertexOutputComponents*/ 64, + /*maxGeometryInputComponents*/ 64, + /*maxGeometryOutputComponents*/ 128, + /*maxFragmentInputComponents*/ 128, + /*maxImageUnits*/ 8, + /*maxCombinedImageUnitsAndFragmentOutputs*/ 8, + /*maxCombinedShaderOutputResources*/ 8, + /*maxImageSamples*/ 0, + /*maxVertexImageUniforms*/ 0, + /*maxTessControlImageUniforms*/ 0, + /*maxTessEvaluationImageUniforms*/ 0, + /*maxGeometryImageUniforms*/ 0, + /*maxFragmentImageUniforms*/ 8, + /*maxCombinedImageUniforms*/ 8, + /*maxGeometryTextureImageUnits*/ 16, + /*maxGeometryOutputVertices*/ 256, + /*maxGeometryTotalOutputComponents*/ 1024, + /*maxGeometryUniformComponents*/ 1024, + /*maxGeometryVaryingComponents*/ 64, + /*maxTessControlInputComponents*/ 128, + /*maxTessControlOutputComponents*/ 128, + /*maxTessControlTextureImageUnits*/ 16, + /*maxTessControlUniformComponents*/ 1024, + /*maxTessControlTotalOutputComponents*/ 4096, + /*maxTessEvaluationInputComponents*/ 128, + /*maxTessEvaluationOutputComponents*/ 128, + /*maxTessEvaluationTextureImageUnits*/ 16, + /*maxTessEvaluationUniformComponents*/ 1024, + /*maxTessPatchComponents*/ 120, + /*maxPatchVertices*/ 32, + /*maxTessGenLevel*/ 64, + /*maxViewports*/ 16, + /*maxVertexAtomicCounters*/ 0, + /*maxTessControlAtomicCounters*/ 0, + /*maxTessEvaluationAtomicCounters*/ 0, + /*maxGeometryAtomicCounters*/ 0, + /*maxFragmentAtomicCounters*/ 8, + /*maxCombinedAtomicCounters*/ 8, + /*maxAtomicCounterBindings*/ 1, + /*maxVertexAtomicCounterBuffers*/ 0, + /*maxTessControlAtomicCounterBuffers*/ 0, + /*maxTessEvaluationAtomicCounterBuffers*/ 0, + /*maxGeometryAtomicCounterBuffers*/ 0, + /*maxFragmentAtomicCounterBuffers*/ 1, + /*maxCombinedAtomicCounterBuffers*/ 1, + /*maxAtomicCounterBufferSize*/ 16384, + /*maxTransformFeedbackBuffers*/ 4, + /*maxTransformFeedbackInterleavedComponents*/ 64, + /*maxCullDistances*/ 8, + /*maxCombinedClipAndCullDistances*/ 8, + /*maxSamples*/ 4, + /*maxMeshOutputVerticesNV*/ 0, + /*maxMeshOutputPrimitivesNV*/ 0, + /*maxMeshWorkGroupSizeX_NV*/ 0, + /*maxMeshWorkGroupSizeY_NV*/ 0, + /*maxMeshWorkGroupSizeZ_NV*/ 0, + /*maxTaskWorkGroupSizeX_NV*/ 0, + /*maxTaskWorkGroupSizeY_NV*/ 0, + /*maxTaskWorkGroupSizeZ_NV*/ 0, + /*maxMeshViewCountNV*/ 0, + /*limits*/ { + /*nonInductiveForLoops*/ 1, + /*whileLoops*/ 1, + /*doWhileLoops*/ 1, + /*generalUniformIndexing*/ 1, + /*generalAttributeMatrixVectorIndexing*/ 1, + /*generalVaryingIndexing*/ 1, + /*generalSamplerIndexing*/ 1, + /*generalVariableIndexing*/ 1, + /*generalConstantMatrixVectorIndexing*/ 1, + } +}; + +static PoolVector<uint8_t> _compile_shader_glsl(RenderingDevice::ShaderStage p_stage, const String &p_source_code, RenderingDevice::ShaderLanguage p_language, String *r_error) { + + PoolVector<uint8_t> ret; + + ERR_FAIL_COND_V(p_language == RenderingDevice::SHADER_LANGUAGE_HLSL, ret); + + EShLanguage stages[RenderingDevice::SHADER_STAGE_MAX] = { + EShLangVertex, + EShLangFragment, + EShLangTessControl, + EShLangTessEvaluation, + EShLangCompute + }; + + int ClientInputSemanticsVersion = 100; // maps to, say, #define VULKAN 100 + + glslang::EShTargetClientVersion VulkanClientVersion = glslang::EShTargetVulkan_1_0; + glslang::EShTargetLanguageVersion TargetVersion = glslang::EShTargetSpv_1_0; + glslang::TShader::ForbidIncluder includer; + + glslang::TShader shader(stages[p_stage]); + CharString cs = p_source_code.ascii(); + const char *cs_strings = cs.get_data(); + + shader.setStrings(&cs_strings, 1); + shader.setEnvInput(glslang::EShSourceGlsl, stages[p_stage], glslang::EShClientVulkan, ClientInputSemanticsVersion); + shader.setEnvClient(glslang::EShClientVulkan, VulkanClientVersion); + shader.setEnvTarget(glslang::EShTargetSpv, TargetVersion); + + EShMessages messages = (EShMessages)(EShMsgSpvRules | EShMsgVulkanRules); + const int DefaultVersion = 100; + std::string pre_processed_code; + + //preprocess + if (!shader.preprocess(&default_builtin_resource, DefaultVersion, ENoProfile, false, false, messages, &pre_processed_code, includer)) { + + if (r_error) { + (*r_error) = "Failed pre-process:\n"; + (*r_error) += shader.getInfoLog(); + (*r_error) += "\n"; + (*r_error) += shader.getInfoDebugLog(); + } + + return ret; + } + //set back.. + cs_strings = pre_processed_code.c_str(); + shader.setStrings(&cs_strings, 1); + + //parse + if (!shader.parse(&default_builtin_resource, DefaultVersion, false, messages)) { + if (r_error) { + (*r_error) = "Failed parse:\n"; + (*r_error) += shader.getInfoLog(); + (*r_error) += "\n"; + (*r_error) += shader.getInfoDebugLog(); + } + return ret; + } + + //link + glslang::TProgram program; + program.addShader(&shader); + + if (!program.link(messages)) { + if (r_error) { + (*r_error) = "Failed link:\n"; + (*r_error) += program.getInfoLog(); + (*r_error) += "\n"; + (*r_error) += program.getInfoDebugLog(); + } + + return ret; + } + + std::vector<uint32_t> SpirV; + spv::SpvBuildLogger logger; + glslang::SpvOptions spvOptions; + glslang::GlslangToSpv(*program.getIntermediate(stages[p_stage]), SpirV, &logger, &spvOptions); + + ret.resize(SpirV.size() * sizeof(uint32_t)); + { + PoolVector<uint8_t>::Write w = ret.write(); + copymem(w.ptr(), &SpirV[0], SpirV.size() * sizeof(uint32_t)); + } + + return ret; +} + +void preregister_glslang_types() { + // initialize in case it's not initialized. This is done once per thread + // and it's safe to call multiple times + glslang::InitializeProcess(); + RenderingDevice::shader_set_compile_function(_compile_shader_glsl); +} + +void register_glslang_types() { +} +void unregister_glslang_types() { + + glslang::FinalizeProcess(); +} diff --git a/modules/glslang/register_types.h b/modules/glslang/register_types.h new file mode 100644 index 0000000000..37a1ef67f2 --- /dev/null +++ b/modules/glslang/register_types.h @@ -0,0 +1,34 @@ +/*************************************************************************/ +/* register_types.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. */ +/*************************************************************************/ + +#define MODULE_GLSLANG_HAS_PREREGISTER +void preregister_glslang_types(); +void register_glslang_types(); +void unregister_glslang_types(); diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp index 3d40220869..7fe58f8ce7 100644 --- a/modules/gridmap/grid_map.cpp +++ b/modules/gridmap/grid_map.cpp @@ -36,6 +36,7 @@ #include "scene/resources/mesh_library.h" #include "scene/resources/surface_tool.h" #include "scene/scene_string_names.h" +#include "servers/navigation_server.h" #include "servers/visual_server.h" bool GridMap::_set(const StringName &p_name, const Variant &p_value) { @@ -418,12 +419,10 @@ bool GridMap::_octant_update(const OctantKey &p_key) { } //erase navigation - if (navigation) { - for (Map<IndexKey, Octant::NavMesh>::Element *E = g.navmesh_ids.front(); E; E = E->next()) { - navigation->navmesh_remove(E->get().id); - } - g.navmesh_ids.clear(); + for (Map<IndexKey, Octant::NavMesh>::Element *E = g.navmesh_ids.front(); E; E = E->next()) { + NavigationServer::get_singleton()->free(E->get().region); } + g.navmesh_ids.clear(); //erase multimeshes @@ -498,9 +497,11 @@ bool GridMap::_octant_update(const OctantKey &p_key) { nm.xform = xform * mesh_library->get_item_navmesh_transform(c.item); if (navigation) { - nm.id = navigation->navmesh_add(navmesh, xform, this); - } else { - nm.id = -1; + RID region = NavigationServer::get_singleton()->region_create(); + NavigationServer::get_singleton()->region_set_navmesh(region, navmesh); + NavigationServer::get_singleton()->region_set_transform(region, navigation->get_global_transform() * nm.xform); + NavigationServer::get_singleton()->region_set_map(region, navigation->get_rid()); + nm.region = region; } g.navmesh_ids[E->get()] = nm; } @@ -513,7 +514,7 @@ bool GridMap::_octant_update(const OctantKey &p_key) { Octant::MultimeshInstance mmi; RID mm = VS::get_singleton()->multimesh_create(); - VS::get_singleton()->multimesh_allocate(mm, E->get().size(), VS::MULTIMESH_TRANSFORM_3D, VS::MULTIMESH_COLOR_NONE); + VS::get_singleton()->multimesh_allocate(mm, E->get().size(), VS::MULTIMESH_TRANSFORM_3D); VS::get_singleton()->multimesh_set_mesh(mm, mesh_library->get_item_mesh(E->key())->get_rid()); int idx = 0; @@ -591,10 +592,14 @@ void GridMap::_octant_enter_world(const OctantKey &p_key) { if (navigation && mesh_library.is_valid()) { for (Map<IndexKey, Octant::NavMesh>::Element *F = g.navmesh_ids.front(); F; F = F->next()) { - if (cell_map.has(F->key()) && F->get().id < 0) { + if (cell_map.has(F->key()) && F->get().region.is_valid() == false) { Ref<NavigationMesh> nm = mesh_library->get_item_navmesh(cell_map[F->key()].item); if (nm.is_valid()) { - F->get().id = navigation->navmesh_add(nm, F->get().xform, this); + RID region = NavigationServer::get_singleton()->region_create(); + NavigationServer::get_singleton()->region_set_navmesh(region, nm); + NavigationServer::get_singleton()->region_set_transform(region, navigation->get_global_transform() * F->get().xform); + NavigationServer::get_singleton()->region_set_map(region, navigation->get_rid()); + F->get().region = region; } } } @@ -620,9 +625,9 @@ void GridMap::_octant_exit_world(const OctantKey &p_key) { if (navigation) { for (Map<IndexKey, Octant::NavMesh>::Element *F = g.navmesh_ids.front(); F; F = F->next()) { - if (F->get().id >= 0) { - navigation->navmesh_remove(F->get().id); - F->get().id = -1; + if (F->get().region.is_valid()) { + NavigationServer::get_singleton()->free(F->get().region); + F->get().region = RID(); } } } @@ -640,13 +645,11 @@ void GridMap::_octant_clean_up(const OctantKey &p_key) { PhysicsServer::get_singleton()->free(g.static_body); - //erase navigation - if (navigation) { - for (Map<IndexKey, Octant::NavMesh>::Element *E = g.navmesh_ids.front(); E; E = E->next()) { - navigation->navmesh_remove(E->get().id); - } - g.navmesh_ids.clear(); + // Erase navigation + for (Map<IndexKey, Octant::NavMesh>::Element *E = g.navmesh_ids.front(); E; E = E->next()) { + NavigationServer::get_singleton()->free(E->get().region); } + g.navmesh_ids.clear(); //erase multimeshes diff --git a/modules/gridmap/grid_map.h b/modules/gridmap/grid_map.h index 705f4929e1..cc1c8c2923 100644 --- a/modules/gridmap/grid_map.h +++ b/modules/gridmap/grid_map.h @@ -91,7 +91,7 @@ class GridMap : public Spatial { struct Octant { struct NavMesh { - int id; + RID region; Transform xform; }; diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp index 4aa407f966..2144ff264f 100644 --- a/modules/gridmap/grid_map_editor_plugin.cpp +++ b/modules/gridmap/grid_map_editor_plugin.cpp @@ -840,15 +840,33 @@ void GridMapEditor::_text_changed(const String &p_text) { void GridMapEditor::_sbox_input(const Ref<InputEvent> &p_ie) { - Ref<InputEventKey> k = p_ie; + const Ref<InputEventKey> k = p_ie; if (k.is_valid() && (k->get_scancode() == KEY_UP || k->get_scancode() == KEY_DOWN || k->get_scancode() == KEY_PAGEUP || k->get_scancode() == KEY_PAGEDOWN)) { + // Forward the key input to the ItemList so it can be scrolled mesh_library_palette->call("_gui_input", k); search_box->accept_event(); } } +void GridMapEditor::_mesh_library_palette_input(const Ref<InputEvent> &p_ie) { + + const Ref<InputEventMouseButton> mb = p_ie; + + // Zoom in/out using Ctrl + mouse wheel + if (mb.is_valid() && mb->is_pressed() && mb->get_command()) { + + if (mb->is_pressed() && mb->get_button_index() == BUTTON_WHEEL_UP) { + size_slider->set_value(size_slider->get_value() + 0.2); + } + + if (mb->is_pressed() && mb->get_button_index() == BUTTON_WHEEL_DOWN) { + size_slider->set_value(size_slider->get_value() - 0.2); + } + } +} + void GridMapEditor::_icon_size_changed(float p_value) { mesh_library_palette->set_icon_scale(p_value); update_palette(); @@ -907,7 +925,7 @@ void GridMapEditor::update_palette() { for (List<_CGMEItemSort>::Element *E = il.front(); E; E = E->next()) { int id = E->get().id; String name = mesh_library->get_item_name(id); - Ref<Texture> preview = mesh_library->get_item_preview(id); + Ref<Texture2D> preview = mesh_library->get_item_preview(id); if (name == "") { name = "#" + itos(id); @@ -1004,8 +1022,7 @@ void GridMapEditor::_draw_grids(const Vector3 &cell_size) { Vector3 edited_floor = node->has_meta("_editor_floor_") ? node->get_meta("_editor_floor_") : Variant(); for (int i = 0; i < 3; i++) { - if (VS::get_singleton()->mesh_get_surface_count(grid[i]) > 0) - VS::get_singleton()->mesh_remove_surface(grid[i], 0); + VS::get_singleton()->mesh_clear(grid[i]); edit_floor[i] = edited_floor[i]; } @@ -1183,6 +1200,7 @@ void GridMapEditor::_bind_methods() { ClassDB::bind_method("_text_changed", &GridMapEditor::_text_changed); ClassDB::bind_method("_sbox_input", &GridMapEditor::_sbox_input); + ClassDB::bind_method("_mesh_library_palette_input", &GridMapEditor::_mesh_library_palette_input); ClassDB::bind_method("_icon_size_changed", &GridMapEditor::_icon_size_changed); ClassDB::bind_method("_menu_option", &GridMapEditor::_menu_option); ClassDB::bind_method("_configure", &GridMapEditor::_configure); @@ -1311,7 +1329,7 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { size_slider = memnew(HSlider); size_slider->set_h_size_flags(SIZE_EXPAND_FILL); - size_slider->set_min(0.1f); + size_slider->set_min(0.2f); size_slider->set_max(4.0f); size_slider->set_step(0.1f); size_slider->set_value(1.0f); @@ -1325,6 +1343,7 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { mesh_library_palette = memnew(ItemList); add_child(mesh_library_palette); mesh_library_palette->set_v_size_flags(SIZE_EXPAND_FILL); + mesh_library_palette->connect("gui_input", this, "_mesh_library_palette_input"); info_message = memnew(Label); info_message->set_text(TTR("Give a MeshLibrary resource to this GridMap to use its meshes.")); @@ -1427,8 +1446,8 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { inner_mat.instance(); inner_mat->set_albedo(Color(0.7, 0.7, 1.0, 0.2)); - inner_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true); - inner_mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); + inner_mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); + inner_mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); d[VS::ARRAY_VERTEX] = triangles; VisualServer::get_singleton()->mesh_add_surface_from_arrays(selection_mesh, VS::PRIMITIVE_TRIANGLES, d); @@ -1437,15 +1456,14 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { outer_mat.instance(); outer_mat->set_albedo(Color(0.7, 0.7, 1.0, 0.8)); outer_mat->set_on_top_of_alpha(); - outer_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true); - outer_mat->set_line_width(3.0); - outer_mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); + + outer_mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); + outer_mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); selection_floor_mat.instance(); selection_floor_mat->set_albedo(Color(0.80, 0.80, 1.0, 1)); selection_floor_mat->set_on_top_of_alpha(); - selection_floor_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true); - selection_floor_mat->set_line_width(3.0); + selection_floor_mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); d[VS::ARRAY_VERTEX] = lines; VisualServer::get_singleton()->mesh_add_surface_from_arrays(selection_mesh, VS::PRIMITIVE_LINES, d); @@ -1472,10 +1490,10 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { accumulated_floor_delta = 0.0; indicator_mat.instance(); - indicator_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true); - indicator_mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); - indicator_mat->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true); - indicator_mat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); + indicator_mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); + indicator_mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA); + indicator_mat->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true); + indicator_mat->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true); indicator_mat->set_albedo(Color(0.8, 0.5, 0.1)); } diff --git a/modules/gridmap/grid_map_editor_plugin.h b/modules/gridmap/grid_map_editor_plugin.h index 404e95b74c..d6459cee0a 100644 --- a/modules/gridmap/grid_map_editor_plugin.h +++ b/modules/gridmap/grid_map_editor_plugin.h @@ -125,10 +125,10 @@ class GridMapEditor : public VBoxContainer { List<ClipboardItem> clipboard_items; - Ref<SpatialMaterial> indicator_mat; - Ref<SpatialMaterial> inner_mat; - Ref<SpatialMaterial> outer_mat; - Ref<SpatialMaterial> selection_floor_mat; + Ref<StandardMaterial3D> indicator_mat; + Ref<StandardMaterial3D> inner_mat; + Ref<StandardMaterial3D> outer_mat; + Ref<StandardMaterial3D> selection_floor_mat; bool updating; @@ -214,6 +214,7 @@ class GridMapEditor : public VBoxContainer { void _text_changed(const String &p_text); void _sbox_input(const Ref<InputEvent> &p_ie); + void _mesh_library_palette_input(const Ref<InputEvent> &p_ie); void _icon_size_changed(float p_value); diff --git a/modules/hdr/image_loader_hdr.cpp b/modules/hdr/image_loader_hdr.cpp index 4505df0f8f..3fa7266f1a 100644 --- a/modules/hdr/image_loader_hdr.cpp +++ b/modules/hdr/image_loader_hdr.cpp @@ -47,7 +47,7 @@ Error ImageLoaderHDR::load_image(Ref<Image> p_image, FileAccess *f, bool p_force if (line.begins_with("FORMAT=")) { // leave option to implement other commands ERR_FAIL_COND_V_MSG(line != "FORMAT=32-bit_rle_rgbe", ERR_FILE_UNRECOGNIZED, "Only 32-bit_rle_rgbe is supported for HDR files."); } else if (!line.begins_with("#")) { // not comment - WARN_PRINTS("Ignoring unsupported header information in HDR: " + line + "."); + WARN_PRINT("Ignoring unsupported header information in HDR: " + line + "."); } } diff --git a/modules/mbedtls/crypto_mbedtls.cpp b/modules/mbedtls/crypto_mbedtls.cpp index 9b072785af..2bd80064e3 100644 --- a/modules/mbedtls/crypto_mbedtls.cpp +++ b/modules/mbedtls/crypto_mbedtls.cpp @@ -182,7 +182,7 @@ CryptoMbedTLS::CryptoMbedTLS() { mbedtls_entropy_init(&entropy); int ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0); if (ret != 0) { - ERR_PRINTS(" failed\n ! mbedtls_ctr_drbg_seed returned an error" + itos(ret)); + ERR_PRINT(" failed\n ! mbedtls_ctr_drbg_seed returned an error" + itos(ret)); } } @@ -267,7 +267,7 @@ Ref<X509Certificate> CryptoMbedTLS::generate_self_signed_certificate(Ref<CryptoK if (err != 0) { mbedtls_mpi_free(&serial); mbedtls_x509write_crt_free(&crt); - ERR_PRINTS("Generated invalid certificate: " + itos(err)); + ERR_PRINT("Generated invalid certificate: " + itos(err)); return NULL; } diff --git a/modules/mbedtls/stream_peer_mbedtls.cpp b/modules/mbedtls/stream_peer_mbedtls.cpp index b88d9e48a4..f06327e0d5 100755 --- a/modules/mbedtls/stream_peer_mbedtls.cpp +++ b/modules/mbedtls/stream_peer_mbedtls.cpp @@ -88,7 +88,7 @@ Error StreamPeerMbedTLS::_do_handshake() { while ((ret = mbedtls_ssl_handshake(ssl_ctx->get_context())) != 0) { if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { // An error occurred. - ERR_PRINTS("TLS handshake error: " + itos(ret)); + ERR_PRINT("TLS handshake error: " + itos(ret)); _print_error(ret); disconnect_from_stream(); status = STATUS_ERROR; diff --git a/modules/mobile_vr/mobile_vr_interface.cpp b/modules/mobile_vr/mobile_vr_interface.cpp index 22b708f206..afa8766bce 100644 --- a/modules/mobile_vr/mobile_vr_interface.cpp +++ b/modules/mobile_vr/mobile_vr_interface.cpp @@ -424,13 +424,7 @@ void MobileVRInterface::commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_t } // we don't offset the eye center vertically (yet) eye_center.y = 0.0; - - // unset our render target so we are outputting to our main screen by making RasterizerStorageGLES3::system_fbo our current FBO - VSG::rasterizer->set_current_render_target(RID()); - - // and output - VSG::rasterizer->output_lens_distorted_to_screen(p_render_target, dest, k1, k2, eye_center, oversample); -}; +} void MobileVRInterface::process() { _THREAD_SAFE_METHOD_ diff --git a/modules/modules_builders.py b/modules/modules_builders.py new file mode 100644 index 0000000000..0e9cba2b0b --- /dev/null +++ b/modules/modules_builders.py @@ -0,0 +1,16 @@ +"""Functions used to generate source files during build time + +All such functions are invoked in a subprocess on Windows to prevent build flakiness. +""" + +from platform_methods import subprocess_main + + +def generate_modules_enabled(target, source, env): + with open(target[0].path, 'w') as f: + for module in env.module_list: + f.write('#define %s\n' % ("MODULE_" + module.upper() + "_ENABLED")) + + +if __name__ == '__main__': + subprocess_main(globals()) diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 9e19e5f8c4..c722076fe2 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -31,6 +31,7 @@ #include "csharp_script.h" #include <mono/metadata/threads.h> +#include <stdint.h> #include "core/io/json.h" #include "core/os/file_access.h" @@ -161,13 +162,13 @@ void CSharpLanguage::finish() { #ifdef DEBUG_ENABLED for (Map<ObjectID, int>::Element *E = unsafe_object_references.front(); E; E = E->next()) { - const ObjectID &id = E->get(); + const ObjectID &id = E->key(); Object *obj = ObjectDB::get_instance(id); if (obj) { - ERR_PRINTS("Leaked unsafe reference to object: " + obj->get_class() + ":" + itos(id)); + ERR_PRINT("Leaked unsafe reference to object: " + obj->to_string()); } else { - ERR_PRINTS("Leaked unsafe reference to deleted object: " + itos(id)); + ERR_PRINT("Leaked unsafe reference to deleted object: " + itos(id)); } } #endif @@ -853,7 +854,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { while (script->instances.front()) { Object *obj = script->instances.front()->get(); - obj->set_script(RefPtr()); // Remove script and existing script instances (placeholder are not removed before domain reload) + obj->set_script(REF()); // Remove script and existing script instances (placeholder are not removed before domain reload) } script->_clear(); @@ -876,7 +877,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { // Use a placeholder for now to avoid losing the state when saving a scene - obj->set_script(scr.get_ref_ptr()); + obj->set_script(scr); PlaceHolderScriptInstance *placeholder = scr->placeholder_instance_create(obj); obj->set_script_instance(placeholder); @@ -1002,7 +1003,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { CRASH_COND(si != NULL); #endif // Re-create script instance - obj->set_script(script.get_ref_ptr()); // will create the script instance as well + obj->set_script(script); // will create the script instance as well } } @@ -1080,7 +1081,7 @@ void CSharpLanguage::_load_scripts_metadata() { int err_line; Error json_err = JSON::parse(old_json, old_dict_var, err_str, err_line); if (json_err != OK) { - ERR_PRINTS("Failed to parse metadata file: '" + err_str + "' (" + String::num_int64(err_line) + ")."); + ERR_PRINT("Failed to parse metadata file: '" + err_str + "' (" + String::num_int64(err_line) + ")."); return; } @@ -1721,8 +1722,7 @@ bool CSharpInstance::has_method(const StringName &p_method) const { Variant CSharpInstance::call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) { - if (!script.is_valid()) - ERR_FAIL_V(Variant()); + ERR_FAIL_COND_V(!script.is_valid(), Variant()); GD_MONO_SCOPE_THREAD_ATTACH; @@ -1980,67 +1980,44 @@ bool CSharpInstance::refcount_decremented() { return ref_dying; } -MultiplayerAPI::RPCMode CSharpInstance::_member_get_rpc_mode(IMonoClassMember *p_member) const { - - if (p_member->has_attribute(CACHED_CLASS(RemoteAttribute))) - return MultiplayerAPI::RPC_MODE_REMOTE; - if (p_member->has_attribute(CACHED_CLASS(MasterAttribute))) - return MultiplayerAPI::RPC_MODE_MASTER; - if (p_member->has_attribute(CACHED_CLASS(PuppetAttribute))) - return MultiplayerAPI::RPC_MODE_PUPPET; - if (p_member->has_attribute(CACHED_CLASS(SlaveAttribute))) - return MultiplayerAPI::RPC_MODE_PUPPET; - if (p_member->has_attribute(CACHED_CLASS(RemoteSyncAttribute))) - return MultiplayerAPI::RPC_MODE_REMOTESYNC; - if (p_member->has_attribute(CACHED_CLASS(SyncAttribute))) - return MultiplayerAPI::RPC_MODE_REMOTESYNC; - if (p_member->has_attribute(CACHED_CLASS(MasterSyncAttribute))) - return MultiplayerAPI::RPC_MODE_MASTERSYNC; - if (p_member->has_attribute(CACHED_CLASS(PuppetSyncAttribute))) - return MultiplayerAPI::RPC_MODE_PUPPETSYNC; +Vector<ScriptNetData> CSharpInstance::get_rpc_methods() const { + return script->get_rpc_methods(); +} - return MultiplayerAPI::RPC_MODE_DISABLED; +uint16_t CSharpInstance::get_rpc_method_id(const StringName &p_method) const { + return script->get_rpc_method_id(p_method); } -MultiplayerAPI::RPCMode CSharpInstance::get_rpc_mode(const StringName &p_method) const { +StringName CSharpInstance::get_rpc_method(const uint16_t p_rpc_method_id) const { + return script->get_rpc_method(p_rpc_method_id); +} - GD_MONO_SCOPE_THREAD_ATTACH; +MultiplayerAPI::RPCMode CSharpInstance::get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const { + return script->get_rpc_mode_by_id(p_rpc_method_id); +} - GDMonoClass *top = script->script_class; +MultiplayerAPI::RPCMode CSharpInstance::get_rpc_mode(const StringName &p_method) const { + return script->get_rpc_mode(p_method); +} - while (top && top != script->native) { - GDMonoMethod *method = top->get_fetched_method_unknown_params(p_method); +Vector<ScriptNetData> CSharpInstance::get_rset_properties() const { + return script->get_rset_properties(); +} - if (method && !method->is_static()) - return _member_get_rpc_mode(method); +uint16_t CSharpInstance::get_rset_property_id(const StringName &p_variable) const { + return script->get_rset_property_id(p_variable); +} - top = top->get_parent_class(); - } +StringName CSharpInstance::get_rset_property(const uint16_t p_rset_member_id) const { + return script->get_rset_property(p_rset_member_id); +} - return MultiplayerAPI::RPC_MODE_DISABLED; +MultiplayerAPI::RPCMode CSharpInstance::get_rset_mode_by_id(const uint16_t p_rset_member_id) const { + return script->get_rset_mode_by_id(p_rset_member_id); } MultiplayerAPI::RPCMode CSharpInstance::get_rset_mode(const StringName &p_variable) const { - - GD_MONO_SCOPE_THREAD_ATTACH; - - GDMonoClass *top = script->script_class; - - while (top && top != script->native) { - GDMonoField *field = top->get_field(p_variable); - - if (field && !field->is_static()) - return _member_get_rpc_mode(field); - - GDMonoProperty *property = top->get_property(p_variable); - - if (property && !property->is_static()) - return _member_get_rpc_mode(property); - - top = top->get_parent_class(); - } - - return MultiplayerAPI::RPC_MODE_DISABLED; + return script->get_rset_mode(p_variable); } void CSharpInstance::notification(int p_notification) { @@ -2444,7 +2421,7 @@ bool CSharpScript::_update_exports() { if (tmp_native && !base_ref) { Node *node = Object::cast_to<Node>(tmp_native); if (node && node->is_inside_tree()) { - ERR_PRINTS("Temporary instance was added to the scene tree."); + ERR_PRINT("Temporary instance was added to the scene tree."); } else { memdelete(tmp_native); } @@ -2522,7 +2499,7 @@ bool CSharpScript::_get_signal(GDMonoClass *p_class, GDMonoClass *p_delegate, Ve arg.type = GDMonoMarshal::managed_to_variant_type(types[i]); if (arg.type == Variant::NIL) { - ERR_PRINTS("Unknown type of signal parameter: '" + arg.name + "' in '" + p_class->get_full_name() + "'."); + ERR_PRINT("Unknown type of signal parameter: '" + arg.name + "' in '" + p_class->get_full_name() + "'."); return false; } @@ -2552,7 +2529,7 @@ bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect if (p_member->is_static()) { if (p_member->has_attribute(CACHED_CLASS(ExportAttribute))) - ERR_PRINTS("Cannot export member because it is static: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'."); + ERR_PRINT("Cannot export member because it is static: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'."); return false; } @@ -2575,12 +2552,12 @@ bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect GDMonoProperty *property = static_cast<GDMonoProperty *>(p_member); if (!property->has_getter()) { if (exported) - ERR_PRINTS("Read-only property cannot be exported: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'."); + ERR_PRINT("Read-only property cannot be exported: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'."); return false; } if (!property->has_setter()) { if (exported) - ERR_PRINTS("Write-only property (without getter) cannot be exported: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'."); + ERR_PRINT("Write-only property (without getter) cannot be exported: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'."); return false; } } @@ -2599,7 +2576,7 @@ bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect String hint_string; if (variant_type == Variant::NIL) { - ERR_PRINTS("Unknown exported member type: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'."); + ERR_PRINT("Unknown exported member type: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'."); return false; } @@ -2891,7 +2868,7 @@ bool CSharpScript::can_instance() const { "Compile", ProjectSettings::get_singleton()->globalize_path(get_path())); } else { - ERR_PRINTS("C# project could not be created; cannot add file: '" + get_path() + "'."); + ERR_PRINT("C# project could not be created; cannot add file: '" + get_path() + "'."); } } } @@ -3252,6 +3229,69 @@ Error CSharpScript::reload(bool p_keep_state) { _update_exports(); } + rpc_functions.clear(); + rpc_variables.clear(); + + GDMonoClass *top = script_class; + while (top && top != native) { + { + Vector<GDMonoMethod *> methods = top->get_all_methods(); + for (int i = 0; i < methods.size(); i++) { + if (!methods[i]->is_static()) { + MultiplayerAPI::RPCMode mode = _member_get_rpc_mode(methods[i]); + if (MultiplayerAPI::RPC_MODE_DISABLED != mode) { + ScriptNetData nd; + nd.name = methods[i]->get_name(); + nd.mode = mode; + if (-1 == rpc_functions.find(nd)) { + rpc_functions.push_back(nd); + } + } + } + } + } + + { + Vector<GDMonoField *> fields = top->get_all_fields(); + for (int i = 0; i < fields.size(); i++) { + if (!fields[i]->is_static()) { + MultiplayerAPI::RPCMode mode = _member_get_rpc_mode(fields[i]); + if (MultiplayerAPI::RPC_MODE_DISABLED != mode) { + ScriptNetData nd; + nd.name = fields[i]->get_name(); + nd.mode = mode; + if (-1 == rpc_variables.find(nd)) { + rpc_variables.push_back(nd); + } + } + } + } + } + + { + Vector<GDMonoProperty *> properties = top->get_all_properties(); + for (int i = 0; i < properties.size(); i++) { + if (!properties[i]->is_static()) { + MultiplayerAPI::RPCMode mode = _member_get_rpc_mode(properties[i]); + if (MultiplayerAPI::RPC_MODE_DISABLED != mode) { + ScriptNetData nd; + nd.name = properties[i]->get_name(); + nd.mode = mode; + if (-1 == rpc_variables.find(nd)) { + rpc_variables.push_back(nd); + } + } + } + } + } + + top = top->get_parent_class(); + } + + // Sort so we are 100% that they are always the same. + rpc_functions.sort_custom<SortNetData>(); + rpc_variables.sort_custom<SortNetData>(); + return OK; } @@ -3325,6 +3365,78 @@ int CSharpScript::get_member_line(const StringName &p_member) const { return -1; } +MultiplayerAPI::RPCMode CSharpScript::_member_get_rpc_mode(IMonoClassMember *p_member) const { + + if (p_member->has_attribute(CACHED_CLASS(RemoteAttribute))) + return MultiplayerAPI::RPC_MODE_REMOTE; + if (p_member->has_attribute(CACHED_CLASS(MasterAttribute))) + return MultiplayerAPI::RPC_MODE_MASTER; + if (p_member->has_attribute(CACHED_CLASS(PuppetAttribute))) + return MultiplayerAPI::RPC_MODE_PUPPET; + if (p_member->has_attribute(CACHED_CLASS(RemoteSyncAttribute))) + return MultiplayerAPI::RPC_MODE_REMOTESYNC; + if (p_member->has_attribute(CACHED_CLASS(MasterSyncAttribute))) + return MultiplayerAPI::RPC_MODE_MASTERSYNC; + if (p_member->has_attribute(CACHED_CLASS(PuppetSyncAttribute))) + return MultiplayerAPI::RPC_MODE_PUPPETSYNC; + + return MultiplayerAPI::RPC_MODE_DISABLED; +} + +Vector<ScriptNetData> CSharpScript::get_rpc_methods() const { + return rpc_functions; +} + +uint16_t CSharpScript::get_rpc_method_id(const StringName &p_method) const { + for (int i = 0; i < rpc_functions.size(); i++) { + if (rpc_functions[i].name == p_method) { + return i; + } + } + return UINT16_MAX; +} + +StringName CSharpScript::get_rpc_method(const uint16_t p_rpc_method_id) const { + ERR_FAIL_COND_V(p_rpc_method_id >= rpc_functions.size(), StringName()); + return rpc_functions[p_rpc_method_id].name; +} + +MultiplayerAPI::RPCMode CSharpScript::get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const { + ERR_FAIL_COND_V(p_rpc_method_id >= rpc_functions.size(), MultiplayerAPI::RPC_MODE_DISABLED); + return rpc_functions[p_rpc_method_id].mode; +} + +MultiplayerAPI::RPCMode CSharpScript::get_rpc_mode(const StringName &p_method) const { + return get_rpc_mode_by_id(get_rpc_method_id(p_method)); +} + +Vector<ScriptNetData> CSharpScript::get_rset_properties() const { + return rpc_variables; +} + +uint16_t CSharpScript::get_rset_property_id(const StringName &p_variable) const { + for (int i = 0; i < rpc_variables.size(); i++) { + if (rpc_variables[i].name == p_variable) { + return i; + } + } + return UINT16_MAX; +} + +StringName CSharpScript::get_rset_property(const uint16_t p_rset_member_id) const { + ERR_FAIL_COND_V(p_rset_member_id >= rpc_variables.size(), StringName()); + return rpc_variables[p_rset_member_id].name; +} + +MultiplayerAPI::RPCMode CSharpScript::get_rset_mode_by_id(const uint16_t p_rset_member_id) const { + ERR_FAIL_COND_V(p_rset_member_id >= rpc_functions.size(), MultiplayerAPI::RPC_MODE_DISABLED); + return rpc_functions[p_rset_member_id].mode; +} + +MultiplayerAPI::RPCMode CSharpScript::get_rset_mode(const StringName &p_variable) const { + return get_rset_mode_by_id(get_rset_property_id(p_variable)); +} + Error CSharpScript::load_source_code(const String &p_path) { Error ferr = read_all_file_utf8(p_path, source); @@ -3437,7 +3549,7 @@ Error ResourceFormatSaverCSharpScript::save(const String &p_path, const RES &p_r "Compile", ProjectSettings::get_singleton()->globalize_path(p_path)); } else { - ERR_PRINTS("C# project could not be created; cannot add file: '" + p_path + "'."); + ERR_PRINT("C# project could not be created; cannot add file: '" + p_path + "'."); } } #endif diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h index f244bc4119..32a5b30c18 100644 --- a/modules/mono/csharp_script.h +++ b/modules/mono/csharp_script.h @@ -113,6 +113,9 @@ class CSharpScript : public Script { Map<StringName, Vector<Argument> > _signals; bool signals_invalidated; + Vector<ScriptNetData> rpc_functions; + Vector<ScriptNetData> rpc_variables; + #ifdef TOOLS_ENABLED List<PropertyInfo> exported_members_cache; // members_cache Map<StringName, Variant> exported_members_defval_cache; // member_default_values_cache @@ -146,6 +149,8 @@ class CSharpScript : public Script { static Ref<CSharpScript> create_for_managed_type(GDMonoClass *p_class, GDMonoClass *p_native); static void initialize_for_managed_type(Ref<CSharpScript> p_script, GDMonoClass *p_class, GDMonoClass *p_native); + MultiplayerAPI::RPCMode _member_get_rpc_mode(IMonoClassMember *p_member) const; + protected: static void _bind_methods(); @@ -187,6 +192,18 @@ public: virtual int get_member_line(const StringName &p_member) const; + virtual Vector<ScriptNetData> get_rpc_methods() const; + virtual uint16_t get_rpc_method_id(const StringName &p_method) const; + virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const; + virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const; + virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const; + + virtual Vector<ScriptNetData> get_rset_properties() const; + virtual uint16_t get_rset_property_id(const StringName &p_variable) const; + virtual StringName get_rset_property(const uint16_t p_variable_id) const; + virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_variable_id) const; + virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const; + #ifdef TOOLS_ENABLED virtual bool is_placeholder_fallback_enabled() const { return placeholder_fallback_enabled; } #endif @@ -232,8 +249,6 @@ class CSharpInstance : public ScriptInstance { void _call_multilevel(MonoObject *p_mono_object, const StringName &p_method, const Variant **p_args, int p_argcount); - MultiplayerAPI::RPCMode _member_get_rpc_mode(IMonoClassMember *p_member) const; - void get_properties_state_for_reloading(List<Pair<StringName, Variant> > &r_state); public: @@ -265,7 +280,16 @@ public: virtual void refcount_incremented(); virtual bool refcount_decremented(); + virtual Vector<ScriptNetData> get_rpc_methods() const; + virtual uint16_t get_rpc_method_id(const StringName &p_method) const; + virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const; + virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const; virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const; + + virtual Vector<ScriptNetData> get_rset_properties() const; + virtual uint16_t get_rset_property_id(const StringName &p_variable) const; + virtual StringName get_rset_property(const uint16_t p_variable_id) const; + virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_variable_id) const; virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const; virtual void notification(int p_notification); diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index 9beadb1778..34f01ce3c6 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -278,7 +278,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf Vector<String> link_target_parts = link_target.split("."); if (link_target_parts.size() <= 0 || link_target_parts.size() > 2) { - ERR_PRINTS("Invalid reference format: '" + tag + "'."); + ERR_PRINT("Invalid reference format: '" + tag + "'."); xml_output.append("<c>"); xml_output.append(tag); @@ -374,7 +374,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf xml_output.append(target_enum_itype.proxy_name); // Includes nesting class if any xml_output.append("\"/>"); } else { - ERR_PRINTS("Cannot resolve enum reference in documentation: '" + link_target + "'."); + ERR_PRINT("Cannot resolve enum reference in documentation: '" + link_target + "'."); xml_output.append("<c>"); xml_output.append(link_target); @@ -423,7 +423,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf xml_output.append(target_iconst->proxy_name); xml_output.append("\"/>"); } else { - ERR_PRINTS("Cannot resolve global constant reference in documentation: '" + link_target + "'."); + ERR_PRINT("Cannot resolve global constant reference in documentation: '" + link_target + "'."); xml_output.append("<c>"); xml_output.append(link_target); @@ -463,7 +463,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf xml_output.append(target_iconst->proxy_name); xml_output.append("\"/>"); } else { - ERR_PRINTS("Cannot resolve constant reference in documentation: '" + link_target + "'."); + ERR_PRINT("Cannot resolve constant reference in documentation: '" + link_target + "'."); xml_output.append("<c>"); xml_output.append(link_target); @@ -533,7 +533,7 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf xml_output.append(target_itype->proxy_name); xml_output.append("\"/>"); } else { - ERR_PRINTS("Cannot resolve type reference in documentation: '" + tag + "'."); + ERR_PRINT("Cannot resolve type reference in documentation: '" + tag + "'."); xml_output.append("<c>"); xml_output.append(tag); @@ -1207,7 +1207,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str output.append(obj_types[itype.base_name].proxy_name); output.append("\n"); } else { - ERR_PRINTS("Base type '" + itype.base_name.operator String() + "' does not exist, for class '" + itype.name + "'."); + ERR_PRINT("Base type '" + itype.base_name.operator String() + "' does not exist, for class '" + itype.name + "'."); return ERR_INVALID_DATA; } } @@ -1646,7 +1646,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf if (p_imethod.is_deprecated) { if (p_imethod.deprecation_message.empty()) - WARN_PRINTS("An empty deprecation message is discouraged. Method: '" + p_imethod.proxy_name + "'."); + WARN_PRINT("An empty deprecation message is discouraged. Method: '" + p_imethod.proxy_name + "'."); p_output.append(MEMBER_BEGIN "[Obsolete(\""); p_output.append(p_imethod.deprecation_message); @@ -2134,7 +2134,7 @@ const BindingsGenerator::TypeInterface *BindingsGenerator::_get_type_or_placehol if (found) return found; - ERR_PRINTS(String() + "Type not found. Creating placeholder: '" + p_typeref.cname.operator String() + "'."); + ERR_PRINT(String() + "Type not found. Creating placeholder: '" + p_typeref.cname.operator String() + "'."); const Map<StringName, TypeInterface>::Element *match = placeholder_types.find(p_typeref.cname); @@ -2358,9 +2358,9 @@ bool BindingsGenerator::_populate_object_type_interfaces() { // which could actually will return something different. // Let's put this to notify us if that ever happens. if (itype.cname != name_cache.type_Object || imethod.name != "free") { - WARN_PRINTS("Notification: New unexpected virtual non-overridable method found." - " We only expected Object.free, but found '" + - itype.name + "." + imethod.name + "'."); + WARN_PRINT("Notification: New unexpected virtual non-overridable method found." + " We only expected Object.free, but found '" + + itype.name + "." + imethod.name + "'."); } } else if (return_info.type == Variant::INT && return_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM) { imethod.return_type.cname = return_info.class_name; @@ -2369,7 +2369,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() { imethod.return_type.cname = return_info.class_name; if (!imethod.is_virtual && ClassDB::is_parent_class(return_info.class_name, name_cache.type_Reference) && return_info.hint != PROPERTY_HINT_RESOURCE_TYPE) { /* clang-format off */ - ERR_PRINTS("Return type is reference but hint is not '" _STR(PROPERTY_HINT_RESOURCE_TYPE) "'." + ERR_PRINT("Return type is reference but hint is not '" _STR(PROPERTY_HINT_RESOURCE_TYPE) "'." " Are you returning a reference type by pointer? Method: '" + itype.name + "." + imethod.name + "'."); /* clang-format on */ ERR_FAIL_V(false); @@ -3038,7 +3038,7 @@ void BindingsGenerator::_populate_global_constants() { // HARDCODED: The Error enum have the prefix 'ERR_' for everything except 'OK' and 'FAILED'. if (ienum.cname == name_cache.enum_Error) { if (prefix_length > 0) { // Just in case it ever changes - ERR_PRINTS("Prefix for enum '" _STR(Error) "' is not empty."); + ERR_PRINT("Prefix for enum '" _STR(Error) "' is not empty."); } prefix_length = 1; // 'ERR_' @@ -3133,7 +3133,7 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args) glue_dir_path = path_elem->get(); elem = elem->next(); } else { - ERR_PRINTS(generate_all_glue_option + ": No output directory specified (expected path to '{GODOT_ROOT}/modules/mono/glue')."); + ERR_PRINT(generate_all_glue_option + ": No output directory specified (expected path to '{GODOT_ROOT}/modules/mono/glue')."); } --options_left; @@ -3144,7 +3144,7 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args) cs_dir_path = path_elem->get(); elem = elem->next(); } else { - ERR_PRINTS(generate_cs_glue_option + ": No output directory specified."); + ERR_PRINT(generate_cs_glue_option + ": No output directory specified."); } --options_left; @@ -3155,7 +3155,7 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args) cpp_dir_path = path_elem->get(); elem = elem->next(); } else { - ERR_PRINTS(generate_cpp_glue_option + ": No output directory specified."); + ERR_PRINT(generate_cpp_glue_option + ": No output directory specified."); } --options_left; @@ -3169,26 +3169,26 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args) bindings_generator.set_log_print_enabled(true); if (!bindings_generator.initialized) { - ERR_PRINTS("Failed to initialize the bindings generator"); + ERR_PRINT("Failed to initialize the bindings generator"); ::exit(0); } if (glue_dir_path.length()) { if (bindings_generator.generate_glue(glue_dir_path) != OK) - ERR_PRINTS(generate_all_glue_option + ": Failed to generate the C++ glue."); + ERR_PRINT(generate_all_glue_option + ": Failed to generate the C++ glue."); if (bindings_generator.generate_cs_api(glue_dir_path.plus_file(API_SOLUTION_NAME)) != OK) - ERR_PRINTS(generate_all_glue_option + ": Failed to generate the C# API."); + ERR_PRINT(generate_all_glue_option + ": Failed to generate the C# API."); } if (cs_dir_path.length()) { if (bindings_generator.generate_cs_api(cs_dir_path) != OK) - ERR_PRINTS(generate_cs_glue_option + ": Failed to generate the C# API."); + ERR_PRINT(generate_cs_glue_option + ": Failed to generate the C# API."); } if (cpp_dir_path.length()) { if (bindings_generator.generate_glue(cpp_dir_path) != OK) - ERR_PRINTS(generate_cpp_glue_option + ": Failed to generate the C++ glue."); + ERR_PRINT(generate_cpp_glue_option + ": Failed to generate the C++ glue."); } // Exit once done diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttributes.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttributes.cs index 1bf6d5199a..8fc430b6bc 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttributes.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/RPCAttributes.cs @@ -6,18 +6,12 @@ namespace Godot public class RemoteAttribute : Attribute {} [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)] - public class SyncAttribute : Attribute {} - - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)] public class MasterAttribute : Attribute {} [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)] public class PuppetAttribute : Attribute {} [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)] - public class SlaveAttribute : Attribute {} - - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)] public class RemoteSyncAttribute : Attribute {} [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)] diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs index d38589013e..baf470a0cc 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs @@ -93,11 +93,15 @@ namespace Godot } } - public Vector3 this[int columnIndex] + /// <summary> + /// Access whole columns in the form of Vector3. + /// </summary> + /// <param name="column">Which column vector.</param> + public Vector3 this[int column] { get { - switch (columnIndex) + switch (column) { case 0: return Column0; @@ -111,7 +115,7 @@ namespace Godot } set { - switch (columnIndex) + switch (column) { case 0: Column0 = value; @@ -128,50 +132,22 @@ namespace Godot } } - public real_t this[int columnIndex, int rowIndex] + /// <summary> + /// Access matrix elements in column-major order. + /// </summary> + /// <param name="column">Which column, the matrix horizontal position.</param> + /// <param name="row">Which row, the matrix vertical position.</param> + public real_t this[int column, int row] { get { - switch (columnIndex) - { - case 0: - return Column0[rowIndex]; - case 1: - return Column1[rowIndex]; - case 2: - return Column2[rowIndex]; - default: - throw new IndexOutOfRangeException(); - } + return this[column][row]; } set { - switch (columnIndex) - { - case 0: - { - var column0 = Column0; - column0[rowIndex] = value; - Column0 = column0; - return; - } - case 1: - { - var column1 = Column1; - column1[rowIndex] = value; - Column1 = column1; - return; - } - case 2: - { - var column2 = Column2; - column2[rowIndex] = value; - Column2 = column2; - return; - } - default: - throw new IndexOutOfRangeException(); - } + Vector3 columnVector = this[column]; + columnVector[row] = value; + this[column] = columnVector; } } @@ -290,12 +266,6 @@ namespace Godot this[index] = value; } - [Obsolete("GetAxis is deprecated. Use GetColumn instead.")] - public Vector3 GetAxis(int axis) - { - return new Vector3(this.Row0[axis], this.Row1[axis], this.Row2[axis]); - } - public int GetOrthogonalIndex() { var orth = this; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs index 0462ef1125..1d1a49945f 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs @@ -318,9 +318,9 @@ namespace Godot return res; } - public int ToAbgr32() + public uint ToAbgr32() { - int c = (byte)Math.Round(a * 255); + uint c = (byte)Math.Round(a * 255); c <<= 8; c |= (byte)Math.Round(b * 255); c <<= 8; @@ -331,9 +331,9 @@ namespace Godot return c; } - public long ToAbgr64() + public ulong ToAbgr64() { - long c = (ushort)Math.Round(a * 65535); + ulong c = (ushort)Math.Round(a * 65535); c <<= 16; c |= (ushort)Math.Round(b * 65535); c <<= 16; @@ -344,9 +344,9 @@ namespace Godot return c; } - public int ToArgb32() + public uint ToArgb32() { - int c = (byte)Math.Round(a * 255); + uint c = (byte)Math.Round(a * 255); c <<= 8; c |= (byte)Math.Round(r * 255); c <<= 8; @@ -357,9 +357,9 @@ namespace Godot return c; } - public long ToArgb64() + public ulong ToArgb64() { - long c = (ushort)Math.Round(a * 65535); + ulong c = (ushort)Math.Round(a * 65535); c <<= 16; c |= (ushort)Math.Round(r * 65535); c <<= 16; @@ -370,9 +370,9 @@ namespace Godot return c; } - public int ToRgba32() + public uint ToRgba32() { - int c = (byte)Math.Round(r * 255); + uint c = (byte)Math.Round(r * 255); c <<= 8; c |= (byte)Math.Round(g * 255); c <<= 8; @@ -383,9 +383,9 @@ namespace Godot return c; } - public long ToRgba64() + public ulong ToRgba64() { - long c = (ushort)Math.Round(r * 65535); + ulong c = (ushort)Math.Round(r * 65535); c <<= 16; c |= (ushort)Math.Round(g * 65535); c <<= 16; @@ -419,7 +419,7 @@ namespace Godot this.a = a; } - public Color(int rgba) + public Color(uint rgba) { a = (rgba & 0xFF) / 255.0f; rgba >>= 8; @@ -430,7 +430,7 @@ namespace Godot r = (rgba & 0xFF) / 255.0f; } - public Color(long rgba) + public Color(ulong rgba) { a = (rgba & 0xFFFF) / 65535.0f; rgba >>= 16; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs index ddfed180b5..4f7aa99df8 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Mathf.cs @@ -130,7 +130,7 @@ namespace Godot public static real_t InverseLerp(real_t from, real_t to, real_t weight) { - return (weight - from) / (to - from); + return (weight - from) / (to - from); } public static bool IsEqualApprox(real_t a, real_t b) @@ -151,12 +151,12 @@ namespace Godot public static bool IsInf(real_t s) { - return real_t.IsInfinity(s); + return real_t.IsInfinity(s); } public static bool IsNaN(real_t s) { - return real_t.IsNaN(s); + return real_t.IsNaN(s); } public static bool IsZeroApprox(real_t s) diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Quat.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Quat.cs index 6702634c51..bbc617ea6e 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Quat.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Quat.cs @@ -104,33 +104,6 @@ namespace Godot return this / Length; } - [Obsolete("Set is deprecated. Use the Quat(" + nameof(real_t) + ", " + nameof(real_t) + ", " + nameof(real_t) + ", " + nameof(real_t) + ") constructor instead.", error: true)] - public void Set(real_t x, real_t y, real_t z, real_t w) - { - this.x = x; - this.y = y; - this.z = z; - this.w = w; - } - - [Obsolete("Set is deprecated. Use the Quat(" + nameof(Quat) + ") constructor instead.", error: true)] - public void Set(Quat q) - { - this = q; - } - - [Obsolete("SetAxisAngle is deprecated. Use the Quat(" + nameof(Vector3) + ", " + nameof(real_t) + ") constructor instead.", error: true)] - public void SetAxisAngle(Vector3 axis, real_t angle) - { - this = new Quat(axis, angle); - } - - [Obsolete("SetEuler is deprecated. Use the Quat(" + nameof(Vector3) + ") constructor instead.", error: true)] - public void SetEuler(Vector3 eulerYXZ) - { - this = new Quat(eulerYXZ); - } - public Quat Slerp(Quat b, real_t t) { #if DEBUG diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs index b926037e5a..b85a00d869 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs @@ -264,7 +264,8 @@ namespace Godot instanceIndex++; toIndex++; } - } else + } + else { while (true) { @@ -474,7 +475,7 @@ namespace Godot int source = 0; int target = 0; - while (instance[source] != 0 && text[target] != 0) + while (source < len && target < text.Length) { bool match; @@ -491,7 +492,7 @@ namespace Godot if (match) { source++; - if (instance[source] == 0) + if (source >= len) return true; } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform.cs index 0b84050f07..aa8815d1aa 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform.cs @@ -15,6 +15,76 @@ namespace Godot public Basis basis; public Vector3 origin; + /// <summary> + /// Access whole columns in the form of Vector3. The fourth column is the origin vector. + /// </summary> + /// <param name="column">Which column vector.</param> + public Vector3 this[int column] + { + get + { + switch (column) + { + case 0: + return basis.Column0; + case 1: + return basis.Column1; + case 2: + return basis.Column2; + case 3: + return origin; + default: + throw new IndexOutOfRangeException(); + } + } + set + { + switch (column) + { + case 0: + basis.Column0 = value; + return; + case 1: + basis.Column1 = value; + return; + case 2: + basis.Column2 = value; + return; + case 3: + origin = value; + return; + default: + throw new IndexOutOfRangeException(); + } + } + } + + /// <summary> + /// Access matrix elements in column-major order. The fourth column is the origin vector. + /// </summary> + /// <param name="column">Which column, the matrix horizontal position.</param> + /// <param name="row">Which row, the matrix vertical position.</param> + public real_t this[int column, int row] + { + get + { + if (column == 3) + { + return origin[row]; + } + return basis[column, row]; + } + set + { + if (column == 3) + { + origin[row] = value; + return; + } + basis[column, row] = value; + } + } + public Transform AffineInverse() { Basis basisInv = basis.Inverse(); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs index 77ea3e5830..e72a44809a 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs @@ -54,11 +54,15 @@ namespace Godot } } - public Vector2 this[int rowIndex] + /// <summary> + /// Access whole columns in the form of Vector2. The third column is the origin vector. + /// </summary> + /// <param name="column">Which column vector.</param> + public Vector2 this[int column] { get { - switch (rowIndex) + switch (column) { case 0: return x; @@ -72,7 +76,7 @@ namespace Godot } set { - switch (rowIndex) + switch (column) { case 0: x = value; @@ -89,38 +93,22 @@ namespace Godot } } - public real_t this[int rowIndex, int columnIndex] + /// <summary> + /// Access matrix elements in column-major order. The third column is the origin vector. + /// </summary> + /// <param name="column">Which column, the matrix horizontal position.</param> + /// <param name="row">Which row, the matrix vertical position.</param> + public real_t this[int column, int row] { get { - switch (rowIndex) - { - case 0: - return x[columnIndex]; - case 1: - return y[columnIndex]; - case 2: - return origin[columnIndex]; - default: - throw new IndexOutOfRangeException(); - } + return this[column][row]; } set { - switch (rowIndex) - { - case 0: - x[columnIndex] = value; - return; - case 1: - y[columnIndex] = value; - return; - case 2: - origin[columnIndex] = value; - return; - default: - throw new IndexOutOfRangeException(); - } + Vector2 columnVector = this[column]; + columnVector[row] = value; + this[column] = columnVector; } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs index f92453f546..385bfed122 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs @@ -248,19 +248,6 @@ namespace Godot return new Vector2(Mathf.Round(x), Mathf.Round(y)); } - [Obsolete("Set is deprecated. Use the Vector2(" + nameof(real_t) + ", " + nameof(real_t) + ") constructor instead.", error: true)] - public void Set(real_t x, real_t y) - { - this.x = x; - this.y = y; - } - [Obsolete("Set is deprecated. Use the Vector2(" + nameof(Vector2) + ") constructor instead.", error: true)] - public void Set(Vector2 v) - { - x = v.x; - y = v.y; - } - public Vector2 Sign() { Vector2 v; diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs index fded34002d..390036c654 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs @@ -270,21 +270,6 @@ namespace Godot return new Basis(axis, phi).Xform(this); } - [Obsolete("Set is deprecated. Use the Vector3(" + nameof(real_t) + ", " + nameof(real_t) + ", " + nameof(real_t) + ") constructor instead.", error: true)] - public void Set(real_t x, real_t y, real_t z) - { - this.x = x; - this.y = y; - this.z = z; - } - [Obsolete("Set is deprecated. Use the Vector3(" + nameof(Vector3) + ") constructor instead.", error: true)] - public void Set(Vector3 v) - { - x = v.x; - y = v.y; - z = v.z; - } - public Vector3 Sign() { Vector3 v; diff --git a/modules/mono/glue/gd_glue.cpp b/modules/mono/glue/gd_glue.cpp index 9bea625450..17483c4457 100644 --- a/modules/mono/glue/gd_glue.cpp +++ b/modules/mono/glue/gd_glue.cpp @@ -235,7 +235,7 @@ MonoObject *godot_icall_GD_str2var(MonoString *p_str) { Error err = VariantParser::parse(&ss, ret, errs, line); if (err != OK) { String err_str = "Parse error at line " + itos(line) + ": " + errs + "."; - ERR_PRINTS(err_str); + ERR_PRINT(err_str); ret = err_str; } @@ -247,11 +247,11 @@ MonoBoolean godot_icall_GD_type_exists(MonoString *p_type) { } void godot_icall_GD_pusherror(MonoString *p_str) { - ERR_PRINTS(GDMonoMarshal::mono_string_to_godot(p_str)); + ERR_PRINT(GDMonoMarshal::mono_string_to_godot(p_str)); } void godot_icall_GD_pushwarning(MonoString *p_str) { - WARN_PRINTS(GDMonoMarshal::mono_string_to_godot(p_str)); + WARN_PRINT(GDMonoMarshal::mono_string_to_godot(p_str)); } MonoArray *godot_icall_GD_var2bytes(MonoObject *p_var, MonoBoolean p_full_objects) { diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index 60008f8fab..895393537f 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -621,7 +621,7 @@ bool GDMono::copy_prebuilt_api_assembly(ApiAssemblyInfo::Type p_api_type, const memdelete(da); if (err != OK) { - ERR_PRINTS("Failed to create destination directory for the API assemblies. Error: " + itos(err) + "."); + ERR_PRINT("Failed to create destination directory for the API assemblies. Error: " + itos(err) + "."); return false; } } @@ -630,15 +630,15 @@ bool GDMono::copy_prebuilt_api_assembly(ApiAssemblyInfo::Type p_api_type, const String xml_file = assembly_name + ".xml"; if (da->copy(src_dir.plus_file(xml_file), dst_dir.plus_file(xml_file)) != OK) - WARN_PRINTS("Failed to copy '" + xml_file + "'."); + WARN_PRINT("Failed to copy '" + xml_file + "'."); String pdb_file = assembly_name + ".pdb"; if (da->copy(src_dir.plus_file(pdb_file), dst_dir.plus_file(pdb_file)) != OK) - WARN_PRINTS("Failed to copy '" + pdb_file + "'."); + WARN_PRINT("Failed to copy '" + pdb_file + "'."); String assembly_file = assembly_name + ".dll"; if (da->copy(src_dir.plus_file(assembly_file), dst_dir.plus_file(assembly_file)) != OK) { - ERR_PRINTS("Failed to copy '" + assembly_file + "'."); + ERR_PRINT("Failed to copy '" + assembly_file + "'."); return false; } @@ -1115,7 +1115,7 @@ Error GDMono::finalize_and_unload_domain(MonoDomain *p_domain) { mono_domain_try_unload(p_domain, (MonoObject **)&exc); if (exc) { - ERR_PRINTS("Exception thrown when unloading domain '" + domain_name + "'."); + ERR_PRINT("Exception thrown when unloading domain '" + domain_name + "'."); GDMonoUtils::debug_print_unhandled_exception(exc); return FAILED; } diff --git a/modules/mono/mono_gd/gd_mono_android.cpp b/modules/mono/mono_gd/gd_mono_android.cpp index 27f394fae0..761368878f 100644 --- a/modules/mono/mono_gd/gd_mono_android.cpp +++ b/modules/mono/mono_gd/gd_mono_android.cpp @@ -315,7 +315,7 @@ MonoArray *_gd_mono_android_cert_store_lookup(MonoString *p_alias) { char *alias_utf8 = mono_string_to_utf8_checked(p_alias, &mono_error); if (!mono_error_ok(&mono_error)) { - ERR_PRINTS(String() + "Failed to convert MonoString* to UTF-8: '" + mono_error_get_message(&mono_error) + "'."); + ERR_PRINT(String() + "Failed to convert MonoString* to UTF-8: '" + mono_error_get_message(&mono_error) + "'."); mono_error_cleanup(&mono_error); return NULL; } diff --git a/modules/mono/mono_gd/gd_mono_cache.cpp b/modules/mono/mono_gd/gd_mono_cache.cpp index f1f6524cd2..0ad90a510e 100644 --- a/modules/mono/mono_gd/gd_mono_cache.cpp +++ b/modules/mono/mono_gd/gd_mono_cache.cpp @@ -136,10 +136,8 @@ void CachedData::clear_godot_api_cache() { class_SignalAttribute = NULL; class_ToolAttribute = NULL; class_RemoteAttribute = NULL; - class_SyncAttribute = NULL; class_MasterAttribute = NULL; class_PuppetAttribute = NULL; - class_SlaveAttribute = NULL; class_RemoteSyncAttribute = NULL; class_MasterSyncAttribute = NULL; class_PuppetSyncAttribute = NULL; @@ -254,10 +252,8 @@ void update_godot_api_cache() { CACHE_CLASS_AND_CHECK(SignalAttribute, GODOT_API_CLASS(SignalAttribute)); CACHE_CLASS_AND_CHECK(ToolAttribute, GODOT_API_CLASS(ToolAttribute)); CACHE_CLASS_AND_CHECK(RemoteAttribute, GODOT_API_CLASS(RemoteAttribute)); - CACHE_CLASS_AND_CHECK(SyncAttribute, GODOT_API_CLASS(SyncAttribute)); CACHE_CLASS_AND_CHECK(MasterAttribute, GODOT_API_CLASS(MasterAttribute)); CACHE_CLASS_AND_CHECK(PuppetAttribute, GODOT_API_CLASS(PuppetAttribute)); - CACHE_CLASS_AND_CHECK(SlaveAttribute, GODOT_API_CLASS(SlaveAttribute)); CACHE_CLASS_AND_CHECK(RemoteSyncAttribute, GODOT_API_CLASS(RemoteSyncAttribute)); CACHE_CLASS_AND_CHECK(MasterSyncAttribute, GODOT_API_CLASS(MasterSyncAttribute)); CACHE_CLASS_AND_CHECK(PuppetSyncAttribute, GODOT_API_CLASS(PuppetSyncAttribute)); diff --git a/modules/mono/mono_gd/gd_mono_cache.h b/modules/mono/mono_gd/gd_mono_cache.h index 1dc6b70479..0458e91240 100644 --- a/modules/mono/mono_gd/gd_mono_cache.h +++ b/modules/mono/mono_gd/gd_mono_cache.h @@ -106,13 +106,11 @@ struct CachedData { GDMonoClass *class_SignalAttribute; GDMonoClass *class_ToolAttribute; GDMonoClass *class_RemoteAttribute; - GDMonoClass *class_SyncAttribute; + GDMonoClass *class_MasterAttribute; + GDMonoClass *class_PuppetAttribute; GDMonoClass *class_RemoteSyncAttribute; GDMonoClass *class_MasterSyncAttribute; GDMonoClass *class_PuppetSyncAttribute; - GDMonoClass *class_MasterAttribute; - GDMonoClass *class_PuppetAttribute; - GDMonoClass *class_SlaveAttribute; GDMonoClass *class_GodotMethodAttribute; GDMonoField *field_GodotMethodAttribute_methodName; diff --git a/modules/mono/mono_gd/gd_mono_class.cpp b/modules/mono/mono_gd/gd_mono_class.cpp index 2132fd36f7..648f5f6c6b 100644 --- a/modules/mono/mono_gd/gd_mono_class.cpp +++ b/modules/mono/mono_gd/gd_mono_class.cpp @@ -166,8 +166,8 @@ void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base #ifdef DEBUG_ENABLED String fullname = method->get_ret_type_full_name() + " " + name + "(" + method->get_signature_desc(true) + ")"; - WARN_PRINTS("Method '" + fullname + "' is hidden by Godot API method. Should be '" + - method->get_full_name_no_class() + "'. In class '" + namespace_name + "." + class_name + "'."); + WARN_PRINT("Method '" + fullname + "' is hidden by Godot API method. Should be '" + + method->get_full_name_no_class() + "'. In class '" + namespace_name + "." + class_name + "'."); #endif continue; } @@ -185,8 +185,8 @@ void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base if (m && m->get_name() != name) { // found String fullname = m->get_ret_type_full_name() + " " + name + "(" + m->get_signature_desc(true) + ")"; - WARN_PRINTS("Method '" + fullname + "' should be '" + m->get_full_name_no_class() + - "'. In class '" + namespace_name + "." + class_name + "'."); + WARN_PRINT("Method '" + fullname + "' should be '" + m->get_full_name_no_class() + + "'. In class '" + namespace_name + "." + class_name + "'."); break; } diff --git a/modules/mono/mono_gd/gd_mono_field.cpp b/modules/mono/mono_gd/gd_mono_field.cpp index 3e0f9a3f15..178647b968 100644 --- a/modules/mono/mono_gd/gd_mono_field.cpp +++ b/modules/mono/mono_gd/gd_mono_field.cpp @@ -512,7 +512,7 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ } break; default: { - ERR_PRINTS("Attempted to set the value of a field of unexpected type encoding: " + itos(type.type_encoding) + "."); + ERR_PRINT("Attempted to set the value of a field of unexpected type encoding: " + itos(type.type_encoding) + "."); } break; } diff --git a/modules/mono/mono_gd/gd_mono_internals.cpp b/modules/mono/mono_gd/gd_mono_internals.cpp index 75aa77c7b0..74ffa90cb3 100644 --- a/modules/mono/mono_gd/gd_mono_internals.cpp +++ b/modules/mono/mono_gd/gd_mono_internals.cpp @@ -107,7 +107,7 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) { ScriptInstance *si = CSharpInstance::create_for_managed_type(unmanaged, script.ptr(), gchandle); - unmanaged->set_script_and_instance(script.get_ref_ptr(), si); + unmanaged->set_script_and_instance(script, si); } void unhandled_exception(MonoException *p_exc) { diff --git a/modules/mono/mono_gd/gd_mono_log.cpp b/modules/mono/mono_gd/gd_mono_log.cpp index ad68a4d90e..76828a66e0 100644 --- a/modules/mono/mono_gd/gd_mono_log.cpp +++ b/modules/mono/mono_gd/gd_mono_log.cpp @@ -83,7 +83,7 @@ void GDMonoLog::mono_log_callback(const char *log_domain, const char *log_level, } if (fatal) { - ERR_PRINTS("Mono: FATAL ERROR, ABORTING! Logfile: '" + GDMonoLog::get_singleton()->log_file_path + "'."); + ERR_PRINT("Mono: FATAL ERROR, ABORTING! Logfile: '" + GDMonoLog::get_singleton()->log_file_path + "'."); // Make sure to flush before aborting f->flush(); f->close(); @@ -139,7 +139,7 @@ void GDMonoLog::initialize() { CharString log_level = OS::get_singleton()->get_environment("GODOT_MONO_LOG_LEVEL").utf8(); if (log_level.length() != 0 && get_log_level_id(log_level.get_data()) == -1) { - ERR_PRINTS(String() + "Mono: Ignoring invalid log level (GODOT_MONO_LOG_LEVEL): '" + log_level.get_data() + "'."); + ERR_PRINT(String() + "Mono: Ignoring invalid log level (GODOT_MONO_LOG_LEVEL): '" + log_level.get_data() + "'."); log_level = CharString(); } @@ -167,7 +167,7 @@ void GDMonoLog::initialize() { log_file = FileAccess::open(log_file_path, FileAccess::WRITE); if (!log_file) { - ERR_PRINTS("Mono: Cannot create log file at: " + log_file_path); + ERR_PRINT("Mono: Cannot create log file at: " + log_file_path); } } diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp index b81c20348d..19d627218e 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.cpp +++ b/modules/mono/mono_gd/gd_mono_marshal.cpp @@ -277,7 +277,7 @@ String mono_to_utf8_string(MonoString *p_mono_string) { char *utf8 = mono_string_to_utf8_checked(p_mono_string, &error); if (!mono_error_ok(&error)) { - ERR_PRINTS(String() + "Failed to convert MonoString* to UTF-8: '" + mono_error_get_message(&error) + "'."); + ERR_PRINT(String() + "Failed to convert MonoString* to UTF-8: '" + mono_error_get_message(&error) + "'."); mono_error_cleanup(&error); return String(); } diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp index 4e7f590a69..05077a00c4 100644 --- a/modules/mono/mono_gd/gd_mono_utils.cpp +++ b/modules/mono/mono_gd/gd_mono_utils.cpp @@ -354,7 +354,7 @@ void debug_send_unhandled_exception_error(MonoException *p_exc) { if (!ScriptDebugger::get_singleton()) { #ifdef TOOLS_ENABLED if (Engine::get_singleton()->is_editor_hint()) { - ERR_PRINTS(GDMonoUtils::get_exception_name_and_message(p_exc)); + ERR_PRINT(GDMonoUtils::get_exception_name_and_message(p_exc)); } #endif return; @@ -431,7 +431,7 @@ void set_pending_exception(MonoException *p_exc) { } if (!mono_runtime_set_pending_exception(p_exc, false)) { - ERR_PRINTS("Exception thrown from managed code, but it could not be set as pending:"); + ERR_PRINT("Exception thrown from managed code, but it could not be set as pending:"); GDMonoUtils::debug_print_unhandled_exception(p_exc); } #endif diff --git a/modules/mono/signal_awaiter_utils.cpp b/modules/mono/signal_awaiter_utils.cpp index d3226762ea..b85d5f2fd9 100644 --- a/modules/mono/signal_awaiter_utils.cpp +++ b/modules/mono/signal_awaiter_utils.cpp @@ -68,7 +68,7 @@ Error connect_signal_awaiter(Object *p_source, const String &p_signal, Object *p Variant SignalAwaiterHandle::_signal_callback(const Variant **p_args, int p_argcount, Variant::CallError &r_error) { #ifdef DEBUG_ENABLED - ERR_FAIL_COND_V_MSG(conn_target_id && !ObjectDB::get_instance(conn_target_id), Variant(), + ERR_FAIL_COND_V_MSG(conn_target_id.is_valid() && !ObjectDB::get_instance(conn_target_id), Variant(), "Resumed after await, but class instance is gone."); #endif @@ -116,12 +116,7 @@ void SignalAwaiterHandle::_bind_methods() { } SignalAwaiterHandle::SignalAwaiterHandle(MonoObject *p_managed) : - MonoGCHandle(MonoGCHandle::new_strong_handle(p_managed), STRONG_HANDLE) { - -#ifdef DEBUG_ENABLED - conn_target_id = 0; -#endif -} + MonoGCHandle(MonoGCHandle::new_strong_handle(p_managed), STRONG_HANDLE) {} SignalAwaiterHandle::~SignalAwaiterHandle() { diff --git a/modules/opensimplex/doc_classes/NoiseTexture.xml b/modules/opensimplex/doc_classes/NoiseTexture.xml index 0790cde557..c06f3096de 100644 --- a/modules/opensimplex/doc_classes/NoiseTexture.xml +++ b/modules/opensimplex/doc_classes/NoiseTexture.xml @@ -1,12 +1,12 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="NoiseTexture" inherits="Texture" version="4.0"> +<class name="NoiseTexture" inherits="Texture2D" version="4.0"> <brief_description> [OpenSimplexNoise] filled texture. </brief_description> <description> Uses an [OpenSimplexNoise] to fill the texture data. You can specify the texture size but keep in mind that larger textures will take longer to generate and seamless noise only works with square sized textures. NoiseTexture can also generate normalmap textures. - The class uses [Thread]s to generate the texture data internally, so [method Texture.get_data] may return [code]null[/code] if the generation process has not completed yet. In that case, you need to wait for the texture to be generated before accessing the data: + The class uses [Thread]s to generate the texture data internally, so [method Texture2D.get_data] may return [code]null[/code] if the generation process has not completed yet. In that case, you need to wait for the texture to be generated before accessing the data: [codeblock] var texture = preload("res://noise.tres") yield(texture, "changed") @@ -24,7 +24,6 @@ <member name="bump_strength" type="float" setter="set_bump_strength" getter="get_bump_strength" default="8.0"> Strength of the bump maps used in this texture. A higher value will make the bump maps appear larger while a lower value will make them appear softer. </member> - <member name="flags" type="int" setter="set_flags" getter="get_flags" override="true" default="7" /> <member name="height" type="int" setter="set_height" getter="get_height" default="512"> Height of the generated texture. </member> diff --git a/modules/opensimplex/noise_texture.cpp b/modules/opensimplex/noise_texture.cpp index aa1c822813..19aa281a72 100644 --- a/modules/opensimplex/noise_texture.cpp +++ b/modules/opensimplex/noise_texture.cpp @@ -42,17 +42,16 @@ NoiseTexture::NoiseTexture() { seamless = false; as_normalmap = false; bump_strength = 8.0; - flags = FLAGS_DEFAULT; noise = Ref<OpenSimplexNoise>(); - texture = VS::get_singleton()->texture_create(); - _queue_update(); } NoiseTexture::~NoiseTexture() { - VS::get_singleton()->free(texture); + if (texture.is_valid()) { + VS::get_singleton()->free(texture); + } if (noise_thread) { Thread::wait_to_finish(noise_thread); memdelete(noise_thread); @@ -101,8 +100,12 @@ void NoiseTexture::_validate_property(PropertyInfo &property) const { void NoiseTexture::_set_texture_data(const Ref<Image> &p_image) { data = p_image; if (data.is_valid()) { - VS::get_singleton()->texture_allocate(texture, size.x, size.y, 0, Image::FORMAT_RGBA8, VS::TEXTURE_TYPE_2D, flags); - VS::get_singleton()->texture_set_data(texture, p_image); + if (texture.is_valid()) { + RID new_texture = VS::get_singleton()->texture_2d_create(p_image); + VS::get_singleton()->texture_replace(texture, new_texture); + } else { + texture = VS::get_singleton()->texture_2d_create(p_image); + } } emit_changed(); } @@ -250,13 +253,12 @@ int NoiseTexture::get_height() const { return size.y; } -void NoiseTexture::set_flags(uint32_t p_flags) { - flags = p_flags; - VS::get_singleton()->texture_set_flags(texture, flags); -} +RID NoiseTexture::get_rid() const { + if (!texture.is_valid()) { + texture = VS::get_singleton()->texture_2d_placeholder_create(); + } -uint32_t NoiseTexture::get_flags() const { - return flags; + return texture; } Ref<Image> NoiseTexture::get_data() const { diff --git a/modules/opensimplex/noise_texture.h b/modules/opensimplex/noise_texture.h index 285fd1eba9..b1d7d3fac9 100644 --- a/modules/opensimplex/noise_texture.h +++ b/modules/opensimplex/noise_texture.h @@ -39,8 +39,8 @@ #include "editor/editor_plugin.h" #include "editor/property_editor.h" -class NoiseTexture : public Texture { - GDCLASS(NoiseTexture, Texture); +class NoiseTexture : public Texture2D { + GDCLASS(NoiseTexture, Texture2D); private: Ref<Image> data; @@ -51,7 +51,7 @@ private: bool update_queued; bool regen_queued; - RID texture; + mutable RID texture; uint32_t flags; Ref<OpenSimplexNoise> noise; @@ -91,10 +91,7 @@ public: int get_width() const; int get_height() const; - virtual void set_flags(uint32_t p_flags); - virtual uint32_t get_flags() const; - - virtual RID get_rid() const { return texture; } + virtual RID get_rid() const; virtual bool has_alpha() const { return false; } virtual Ref<Image> get_data() const; diff --git a/modules/pvr/texture_loader_pvr.cpp b/modules/pvr/texture_loader_pvr.cpp index 65c21d5af8..36f2fe1ba1 100644 --- a/modules/pvr/texture_loader_pvr.cpp +++ b/modules/pvr/texture_loader_pvr.cpp @@ -154,16 +154,11 @@ RES ResourceFormatPVR::load(const String &p_path, const String &p_original_path, w.release(); - int tex_flags = Texture::FLAG_FILTER | Texture::FLAG_REPEAT; - - if (mipmaps) - tex_flags |= Texture::FLAG_MIPMAPS; - Ref<Image> image = memnew(Image(width, height, mipmaps, format, data)); ERR_FAIL_COND_V(image->empty(), RES()); Ref<ImageTexture> texture = memnew(ImageTexture); - texture->create_from_image(image, tex_flags); + texture->create_from_image(image); if (r_error) *r_error = OK; @@ -177,12 +172,12 @@ void ResourceFormatPVR::get_recognized_extensions(List<String> *p_extensions) co } bool ResourceFormatPVR::handles_type(const String &p_type) const { - return ClassDB::is_parent_class(p_type, "Texture"); + return ClassDB::is_parent_class(p_type, "Texture2D"); } String ResourceFormatPVR::get_resource_type(const String &p_path) const { if (p_path.get_extension().to_lower() == "pvr") - return "Texture"; + return "Texture2D"; return ""; } diff --git a/modules/recast/SCsub b/modules/recast/SCsub deleted file mode 100644 index 94d9968164..0000000000 --- a/modules/recast/SCsub +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env python - -Import('env') -Import('env_modules') - -env_recast = env_modules.Clone() - -# Thirdparty source files -if env['builtin_recast']: - thirdparty_dir = "#thirdparty/recastnavigation/Recast/" - thirdparty_sources = [ - "Source/Recast.cpp", - "Source/RecastAlloc.cpp", - "Source/RecastArea.cpp", - "Source/RecastAssert.cpp", - "Source/RecastContour.cpp", - "Source/RecastFilter.cpp", - "Source/RecastLayers.cpp", - "Source/RecastMesh.cpp", - "Source/RecastMeshDetail.cpp", - "Source/RecastRasterization.cpp", - "Source/RecastRegion.cpp", - ] - thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - - env_recast.Prepend(CPPPATH=[thirdparty_dir + "/Include"]) - - env_thirdparty = env_recast.Clone() - env_thirdparty.disable_warnings() - env_thirdparty.add_source_files(env.modules_sources, thirdparty_sources) - -# Godot source files -env_recast.add_source_files(env.modules_sources, "*.cpp") diff --git a/modules/register_module_types.h b/modules/register_module_types.h index a8eb68b929..acd9fc7c97 100644 --- a/modules/register_module_types.h +++ b/modules/register_module_types.h @@ -31,9 +31,8 @@ #ifndef REGISTER_MODULE_TYPES_H #define REGISTER_MODULE_TYPES_H -// - +void preregister_module_types(); void register_module_types(); void unregister_module_types(); -#endif +#endif // REGISTER_MODULE_TYPES_H diff --git a/modules/squish/image_compress_squish.cpp b/modules/squish/image_compress_squish.cpp index 58b8115dfc..2f680fd3d0 100644 --- a/modules/squish/image_compress_squish.cpp +++ b/modules/squish/image_compress_squish.cpp @@ -50,7 +50,7 @@ void image_decompress_squish(Image *p_image) { squish_flags = squish::kDxt1; } else if (p_image->get_format() == Image::FORMAT_DXT3) { squish_flags = squish::kDxt3; - } else if (p_image->get_format() == Image::FORMAT_DXT5) { + } else if (p_image->get_format() == Image::FORMAT_DXT5 || p_image->get_format() == Image::FORMAT_DXT5_RA_AS_RG) { squish_flags = squish::kDxt5; } else if (p_image->get_format() == Image::FORMAT_RGTC_R) { squish_flags = squish::kBc4; @@ -71,9 +71,13 @@ void image_decompress_squish(Image *p_image) { } p_image->create(p_image->get_width(), p_image->get_height(), p_image->has_mipmaps(), target_format, data); + + if (p_image->get_format() == Image::FORMAT_DXT5_RA_AS_RG) { + p_image->convert_ra_rgba8_to_rg(); + } } -void image_compress_squish(Image *p_image, float p_lossy_quality, Image::CompressSource p_source) { +void image_compress_squish(Image *p_image, float p_lossy_quality, Image::UsedChannels p_channels) { if (p_image->get_format() >= Image::FORMAT_DXT1) return; //do not compress, already compressed @@ -92,75 +96,35 @@ void image_compress_squish(Image *p_image, float p_lossy_quality, Image::Compres Image::Format target_format = Image::FORMAT_RGBA8; - Image::DetectChannels dc = p_image->get_detected_channels(); - - if (p_source == Image::COMPRESS_SOURCE_LAYERED) { - //keep what comes in - switch (p_image->get_format()) { - case Image::FORMAT_L8: { - dc = Image::DETECTED_L; - } break; - case Image::FORMAT_LA8: { - dc = Image::DETECTED_LA; - } break; - case Image::FORMAT_R8: { - dc = Image::DETECTED_R; - } break; - case Image::FORMAT_RG8: { - dc = Image::DETECTED_RG; - } break; - case Image::FORMAT_RGB8: { - dc = Image::DETECTED_RGB; - } break; - case Image::FORMAT_RGBA8: - case Image::FORMAT_RGBA4444: - case Image::FORMAT_RGBA5551: { - dc = Image::DETECTED_RGBA; - } break; - default: { - } - } - } - p_image->convert(Image::FORMAT_RGBA8); //still uses RGBA to convert - if (p_source == Image::COMPRESS_SOURCE_SRGB && (dc == Image::DETECTED_R || dc == Image::DETECTED_RG)) { - //R and RG do not support SRGB - dc = Image::DETECTED_RGB; - } - - if (p_source == Image::COMPRESS_SOURCE_NORMAL) { - //R and RG do not support SRGB - dc = Image::DETECTED_RG; - } - - switch (dc) { - case Image::DETECTED_L: { + switch (p_channels) { + case Image::USED_CHANNELS_L: { target_format = Image::FORMAT_DXT1; squish_comp |= squish::kDxt1; } break; - case Image::DETECTED_LA: { + case Image::USED_CHANNELS_LA: { target_format = Image::FORMAT_DXT5; squish_comp |= squish::kDxt5; } break; - case Image::DETECTED_R: { + case Image::USED_CHANNELS_R: { target_format = Image::FORMAT_RGTC_R; squish_comp |= squish::kBc4; } break; - case Image::DETECTED_RG: { + case Image::USED_CHANNELS_RG: { target_format = Image::FORMAT_RGTC_RG; squish_comp |= squish::kBc5; } break; - case Image::DETECTED_RGB: { + case Image::USED_CHANNELS_RGB: { target_format = Image::FORMAT_DXT1; squish_comp |= squish::kDxt1; } break; - case Image::DETECTED_RGBA: { + case Image::USED_CHANNELS_RGBA: { //TODO, should convert both, then measure which one does a better job target_format = Image::FORMAT_DXT5; diff --git a/modules/squish/image_compress_squish.h b/modules/squish/image_compress_squish.h index b5a209ceb9..19e6d57474 100644 --- a/modules/squish/image_compress_squish.h +++ b/modules/squish/image_compress_squish.h @@ -33,7 +33,7 @@ #include "core/image.h" -void image_compress_squish(Image *p_image, float p_lossy_quality, Image::CompressSource p_source); +void image_compress_squish(Image *p_image, float p_lossy_quality, Image::UsedChannels p_channels); void image_decompress_squish(Image *p_image); #endif // IMAGE_COMPRESS_SQUISH_H diff --git a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp index b80b126bde..f2d0f5c9a6 100644 --- a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp +++ b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp @@ -57,7 +57,7 @@ void AudioStreamPlaybackOGGVorbis::_mix_internal(AudioFrame *p_buffer, int p_fra if (todo) { //end of file! - if (vorbis_stream->loop) { + if (vorbis_stream->loop && mixed > 0) { //loop seek(vorbis_stream->loop_offset); loops++; diff --git a/modules/svg/SCsub b/modules/svg/SCsub index 9324c1634b..7961d1f33e 100644 --- a/modules/svg/SCsub +++ b/modules/svg/SCsub @@ -13,10 +13,6 @@ thirdparty_sources = [ thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] env_svg.Prepend(CPPPATH=[thirdparty_dir]) -# FIXME: Needed in editor/editor_themes.cpp for now, but ideally there -# shouldn't be a dependency on modules/ and its own 3rd party deps. -env.Prepend(CPPPATH=[thirdparty_dir]) -env.Append(CPPDEFINES=["SVG_ENABLED"]) env_thirdparty = env_svg.Clone() env_thirdparty.disable_warnings() diff --git a/modules/svg/image_loader_svg.cpp b/modules/svg/image_loader_svg.cpp index 11ae2f81bf..7f91908a33 100644 --- a/modules/svg/image_loader_svg.cpp +++ b/modules/svg/image_loader_svg.cpp @@ -30,9 +30,8 @@ #include "image_loader_svg.h" -#include "core/os/os.h" -#include "core/print_string.h" -#include "core/ustring.h" +#include <nanosvg.h> +#include <nanosvgrast.h> void SVGRasterizer::rasterize(NSVGimage *p_image, float p_tx, float p_ty, float p_scale, unsigned char *p_dst, int p_w, int p_h, int p_stride) { nsvgRasterize(rasterizer, p_image, p_tx, p_ty, p_scale, p_dst, p_w, p_h, p_stride); diff --git a/modules/svg/image_loader_svg.h b/modules/svg/image_loader_svg.h index 9e9366e91b..24cee82480 100644 --- a/modules/svg/image_loader_svg.h +++ b/modules/svg/image_loader_svg.h @@ -34,13 +34,14 @@ #include "core/io/image_loader.h" #include "core/ustring.h" -#include <nanosvg.h> -#include <nanosvgrast.h> - /** @author Daniel Ramirez <djrmuv@gmail.com> */ +// Forward declare and include thirdparty headers in .cpp. +struct NSVGrasterizer; +struct NSVGimage; + class SVGRasterizer { NSVGrasterizer *rasterizer; diff --git a/modules/theora/video_stream_theora.cpp b/modules/theora/video_stream_theora.cpp index cf1fc3f175..de229745f5 100644 --- a/modules/theora/video_stream_theora.cpp +++ b/modules/theora/video_stream_theora.cpp @@ -110,7 +110,7 @@ void VideoStreamPlaybackTheora::video_write(void) { Ref<Image> img = memnew(Image(size.x, size.y, 0, Image::FORMAT_RGBA8, frame_data)); //zero copy image creation - texture->set_data(img); //zero copy send to visual server + texture->update(img, true); //zero copy send to visual server frames_pending = 1; } @@ -336,7 +336,9 @@ void VideoStreamPlaybackTheora::set_file(const String &p_file) { size.x = w; size.y = h; - texture->create(w, h, Image::FORMAT_RGBA8, Texture::FLAG_FILTER | Texture::FLAG_VIDEO_SURFACE); + Ref<Image> img; + img.instance(); + img->create(w, h, false, Image::FORMAT_RGBA8); } else { /* tear down the partial theora setup */ @@ -363,11 +365,13 @@ void VideoStreamPlaybackTheora::set_file(const String &p_file) { }; float VideoStreamPlaybackTheora::get_time() const { - - return time - AudioServer::get_singleton()->get_output_latency() - delay_compensation; //-((get_total())/(float)vi.rate); + // FIXME: AudioServer output latency was fixed in af9bb0e, previously it used to + // systematically return 0. Now that it gives a proper latency, it broke this + // code where the delay compensation likely never really worked. + return time - /* AudioServer::get_singleton()->get_output_latency() - */ delay_compensation; }; -Ref<Texture> VideoStreamPlaybackTheora::get_texture() const { +Ref<Texture2D> VideoStreamPlaybackTheora::get_texture() const { return texture; } diff --git a/modules/theora/video_stream_theora.h b/modules/theora/video_stream_theora.h index 0f201ffa9d..c0a0faec4b 100644 --- a/modules/theora/video_stream_theora.h +++ b/modules/theora/video_stream_theora.h @@ -147,7 +147,7 @@ public: void set_file(const String &p_file); - virtual Ref<Texture> get_texture() const; + virtual Ref<Texture2D> get_texture() const; virtual void update(float p_delta); virtual void set_mix_callback(AudioMixCallback p_callback, void *p_userdata); diff --git a/modules/tinyexr/image_loader_tinyexr.cpp b/modules/tinyexr/image_loader_tinyexr.cpp index bca3b749e3..79cb135abb 100644 --- a/modules/tinyexr/image_loader_tinyexr.cpp +++ b/modules/tinyexr/image_loader_tinyexr.cpp @@ -69,7 +69,7 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f ret = ParseEXRHeaderFromMemory(&exr_header, &exr_version, w.ptr(), src_image_len, &err); if (ret != TINYEXR_SUCCESS) { if (err) { - ERR_PRINTS(String(err)); + ERR_PRINT(String(err)); } return ERR_FILE_CORRUPT; } @@ -85,7 +85,7 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f ret = LoadEXRImageFromMemory(&exr_image, &exr_header, w.ptr(), src_image_len, &err); if (ret != TINYEXR_SUCCESS) { if (err) { - ERR_PRINTS(String(err)); + ERR_PRINT(String(err)); } return ERR_FILE_CORRUPT; } diff --git a/modules/tinyexr/image_saver_tinyexr.cpp b/modules/tinyexr/image_saver_tinyexr.cpp index 17f920746f..a0c01f7e65 100644 --- a/modules/tinyexr/image_saver_tinyexr.cpp +++ b/modules/tinyexr/image_saver_tinyexr.cpp @@ -58,7 +58,8 @@ static bool is_supported_format(Image::Format p_format) { enum SrcPixelType { SRC_FLOAT, SRC_HALF, - SRC_BYTE + SRC_BYTE, + SRC_UNSUPPORTED }; static SrcPixelType get_source_pixel_type(Image::Format p_format) { @@ -79,7 +80,7 @@ static SrcPixelType get_source_pixel_type(Image::Format p_format) { case Image::FORMAT_RGBA8: return SRC_BYTE; default: - CRASH_NOW(); + return SRC_UNSUPPORTED; } } @@ -101,7 +102,7 @@ static int get_target_pixel_type(Image::Format p_format) { case Image::FORMAT_RGBA8: return TINYEXR_PIXELTYPE_HALF; default: - CRASH_NOW(); + return -1; } } @@ -112,7 +113,7 @@ static int get_pixel_type_size(int p_pixel_type) { case TINYEXR_PIXELTYPE_FLOAT: return 4; } - CRASH_NOW(); + return -1; } static int get_channel_count(Image::Format p_format) { @@ -134,7 +135,7 @@ static int get_channel_count(Image::Format p_format) { case Image::FORMAT_RGBA8: return 4; default: - CRASH_NOW(); + return -1; } } @@ -173,11 +174,15 @@ Error save_exr(const String &p_path, const Ref<Image> &p_img, bool p_grayscale) }; int channel_count = get_channel_count(format); + ERR_FAIL_COND_V(channel_count < 0, ERR_UNAVAILABLE); ERR_FAIL_COND_V(p_grayscale && channel_count != 1, ERR_INVALID_PARAMETER); int target_pixel_type = get_target_pixel_type(format); + ERR_FAIL_COND_V(target_pixel_type < 0, ERR_UNAVAILABLE); int target_pixel_type_size = get_pixel_type_size(target_pixel_type); + ERR_FAIL_COND_V(target_pixel_type_size < 0, ERR_UNAVAILABLE); SrcPixelType src_pixel_type = get_source_pixel_type(format); + ERR_FAIL_COND_V(src_pixel_type == SRC_UNSUPPORTED, ERR_UNAVAILABLE); const int pixel_count = p_img->get_width() * p_img->get_height(); const int *channel_mapping = channel_mappings[channel_count - 1]; diff --git a/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml b/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml index 95085d9652..9f4846ee1f 100644 --- a/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml +++ b/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml @@ -89,7 +89,7 @@ <constant name="MATH_EASE" value="23" enum="BuiltinFunc"> Easing function, based on exponent. 0 is constant, 1 is linear, 0 to 1 is ease-in, 1+ is ease out. Negative values are in-out/out in. </constant> - <constant name="MATH_DECIMALS" value="24" enum="BuiltinFunc"> + <constant name="MATH_STEP_DECIMALS" value="24" enum="BuiltinFunc"> Return the number of digit places after the decimal that the first non-zero digit occurs. </constant> <constant name="MATH_STEPIFY" value="25" enum="BuiltinFunc"> diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp index c591e3b5c2..e712190344 100644 --- a/modules/visual_script/visual_script.cpp +++ b/modules/visual_script/visual_script.cpp @@ -30,6 +30,8 @@ #include "visual_script.h" +#include <stdint.h> + #include "core/core_string_names.h" #include "core/os/os.h" #include "core/project_settings.h" @@ -1102,6 +1104,60 @@ bool VisualScript::are_subnodes_edited() const { } #endif +Vector<ScriptNetData> VisualScript::get_rpc_methods() const { + return rpc_functions; +} + +uint16_t VisualScript::get_rpc_method_id(const StringName &p_method) const { + for (int i = 0; i < rpc_functions.size(); i++) { + if (rpc_functions[i].name == p_method) { + return i; + } + } + return UINT16_MAX; +} + +StringName VisualScript::get_rpc_method(const uint16_t p_rpc_method_id) const { + ERR_FAIL_COND_V(p_rpc_method_id >= rpc_functions.size(), StringName()); + return rpc_functions[p_rpc_method_id].name; +} + +MultiplayerAPI::RPCMode VisualScript::get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const { + ERR_FAIL_COND_V(p_rpc_method_id >= rpc_functions.size(), MultiplayerAPI::RPC_MODE_DISABLED); + return rpc_functions[p_rpc_method_id].mode; +} + +MultiplayerAPI::RPCMode VisualScript::get_rpc_mode(const StringName &p_method) const { + return get_rpc_mode_by_id(get_rpc_method_id(p_method)); +} + +Vector<ScriptNetData> VisualScript::get_rset_properties() const { + return rpc_variables; +} + +uint16_t VisualScript::get_rset_property_id(const StringName &p_variable) const { + for (int i = 0; i < rpc_variables.size(); i++) { + if (rpc_variables[i].name == p_variable) { + return i; + } + } + return UINT16_MAX; +} + +StringName VisualScript::get_rset_property(const uint16_t p_rset_property_id) const { + ERR_FAIL_COND_V(p_rset_property_id >= rpc_variables.size(), StringName()); + return rpc_variables[p_rset_property_id].name; +} + +MultiplayerAPI::RPCMode VisualScript::get_rset_mode_by_id(const uint16_t p_rset_variable_id) const { + ERR_FAIL_COND_V(p_rset_variable_id >= rpc_functions.size(), MultiplayerAPI::RPC_MODE_DISABLED); + return rpc_functions[p_rset_variable_id].mode; +} + +MultiplayerAPI::RPCMode VisualScript::get_rset_mode(const StringName &p_variable) const { + return get_rset_mode_by_id(get_rset_property_id(p_variable)); +} + void VisualScript::_set_data(const Dictionary &p_data) { Dictionary d = p_data; @@ -1206,6 +1262,30 @@ void VisualScript::_set_data(const Dictionary &p_data) { is_tool_script = d["is_tool_script"]; else is_tool_script = false; + + // Takes all the rpc methods + rpc_functions.clear(); + rpc_variables.clear(); + for (Map<StringName, Function>::Element *E = functions.front(); E; E = E->next()) { + if (E->get().function_id >= 0 && E->get().nodes.find(E->get().function_id)) { + Ref<VisualScriptFunction> vsf = E->get().nodes[E->get().function_id].node; + if (vsf.is_valid()) { + if (vsf->get_rpc_mode() != MultiplayerAPI::RPC_MODE_DISABLED) { + ScriptNetData nd; + nd.name = E->key(); + nd.mode = vsf->get_rpc_mode(); + if (rpc_functions.find(nd) == -1) { + rpc_functions.push_back(nd); + } + } + } + } + } + + // Visual script doesn't have rset :( + + // Sort so we are 100% that they are always the same. + rpc_functions.sort_custom<SortNetData>(); } Dictionary VisualScript::_get_data() const { @@ -2043,31 +2123,44 @@ Ref<Script> VisualScriptInstance::get_script() const { return script; } -MultiplayerAPI::RPCMode VisualScriptInstance::get_rpc_mode(const StringName &p_method) const { +Vector<ScriptNetData> VisualScriptInstance::get_rpc_methods() const { + return script->get_rpc_methods(); +} - if (p_method == script->get_default_func()) - return MultiplayerAPI::RPC_MODE_DISABLED; +uint16_t VisualScriptInstance::get_rpc_method_id(const StringName &p_method) const { + return script->get_rpc_method_id(p_method); +} - const Map<StringName, VisualScript::Function>::Element *E = script->functions.find(p_method); - if (!E) { - return MultiplayerAPI::RPC_MODE_DISABLED; - } +StringName VisualScriptInstance::get_rpc_method(const uint16_t p_rpc_method_id) const { + return script->get_rpc_method(p_rpc_method_id); +} - if (E->get().function_id >= 0 && E->get().nodes.has(E->get().function_id)) { +MultiplayerAPI::RPCMode VisualScriptInstance::get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const { + return script->get_rpc_mode_by_id(p_rpc_method_id); +} - Ref<VisualScriptFunction> vsf = E->get().nodes[E->get().function_id].node; - if (vsf.is_valid()) { +MultiplayerAPI::RPCMode VisualScriptInstance::get_rpc_mode(const StringName &p_method) const { + return script->get_rpc_mode(p_method); +} - return vsf->get_rpc_mode(); - } - } +Vector<ScriptNetData> VisualScriptInstance::get_rset_properties() const { + return script->get_rset_properties(); +} - return MultiplayerAPI::RPC_MODE_DISABLED; +uint16_t VisualScriptInstance::get_rset_property_id(const StringName &p_variable) const { + return script->get_rset_property_id(p_variable); } -MultiplayerAPI::RPCMode VisualScriptInstance::get_rset_mode(const StringName &p_variable) const { +StringName VisualScriptInstance::get_rset_property(const uint16_t p_rset_property_id) const { + return script->get_rset_property(p_rset_property_id); +} - return MultiplayerAPI::RPC_MODE_DISABLED; +MultiplayerAPI::RPCMode VisualScriptInstance::get_rset_mode_by_id(const uint16_t p_rset_variable_id) const { + return script->get_rset_mode_by_id(p_rset_variable_id); +} + +MultiplayerAPI::RPCMode VisualScriptInstance::get_rset_mode(const StringName &p_variable) const { + return script->get_rset_mode(p_variable); } void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_owner) { @@ -2321,8 +2414,8 @@ Variant VisualScriptFunctionState::_signal_callback(const Variant **p_args, int #ifdef DEBUG_ENABLED - ERR_FAIL_COND_V_MSG(instance_id && !ObjectDB::get_instance(instance_id), Variant(), "Resumed after yield, but class instance is gone."); - ERR_FAIL_COND_V_MSG(script_id && !ObjectDB::get_instance(script_id), Variant(), "Resumed after yield, but script is gone."); + ERR_FAIL_COND_V_MSG(instance_id.is_valid() && !ObjectDB::get_instance(instance_id), Variant(), "Resumed after yield, but class instance is gone."); + ERR_FAIL_COND_V_MSG(script_id.is_valid() && !ObjectDB::get_instance(script_id), Variant(), "Resumed after yield, but script is gone."); #endif @@ -2383,8 +2476,8 @@ Variant VisualScriptFunctionState::resume(Array p_args) { ERR_FAIL_COND_V(function == StringName(), Variant()); #ifdef DEBUG_ENABLED - ERR_FAIL_COND_V_MSG(instance_id && !ObjectDB::get_instance(instance_id), Variant(), "Resumed after yield, but class instance is gone."); - ERR_FAIL_COND_V_MSG(script_id && !ObjectDB::get_instance(script_id), Variant(), "Resumed after yield, but script is gone."); + ERR_FAIL_COND_V_MSG(instance_id.is_valid() && !ObjectDB::get_instance(instance_id), Variant(), "Resumed after yield, but class instance is gone."); + ERR_FAIL_COND_V_MSG(script_id.is_valid() && !ObjectDB::get_instance(script_id), Variant(), "Resumed after yield, but script is gone."); #endif diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h index 9305226dc6..d3569bb040 100644 --- a/modules/visual_script/visual_script.h +++ b/modules/visual_script/visual_script.h @@ -245,6 +245,8 @@ private: Map<StringName, Function> functions; Map<StringName, Variable> variables; Map<StringName, Vector<Argument> > custom_signals; + Vector<ScriptNetData> rpc_functions; + Vector<ScriptNetData> rpc_variables; Map<Object *, VisualScriptInstance *> instances; @@ -362,6 +364,18 @@ public: virtual int get_member_line(const StringName &p_member) const; + virtual Vector<ScriptNetData> get_rpc_methods() const; + virtual uint16_t get_rpc_method_id(const StringName &p_method) const; + virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const; + virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const; + virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const; + + virtual Vector<ScriptNetData> get_rset_properties() const; + virtual uint16_t get_rset_property_id(const StringName &p_property) const; + virtual StringName get_rset_property(const uint16_t p_rset_property_id) const; + virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_rpc_method_id) const; + virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const; + #ifdef TOOLS_ENABLED virtual bool are_subnodes_edited() const; #endif @@ -441,7 +455,16 @@ public: virtual ScriptLanguage *get_language(); + virtual Vector<ScriptNetData> get_rpc_methods() const; + virtual uint16_t get_rpc_method_id(const StringName &p_method) const; + virtual StringName get_rpc_method(const uint16_t p_rpc_method_id) const; + virtual MultiplayerAPI::RPCMode get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const; virtual MultiplayerAPI::RPCMode get_rpc_mode(const StringName &p_method) const; + + virtual Vector<ScriptNetData> get_rset_properties() const; + virtual uint16_t get_rset_property_id(const StringName &p_property) const; + virtual StringName get_rset_property(const uint16_t p_rset_property_id) const; + virtual MultiplayerAPI::RPCMode get_rset_mode_by_id(const uint16_t p_rpc_method_id) const; virtual MultiplayerAPI::RPCMode get_rset_mode(const StringName &p_variable) const; VisualScriptInstance(); diff --git a/modules/visual_script/visual_script_builtin_funcs.cpp b/modules/visual_script/visual_script_builtin_funcs.cpp index 2894f6367b..832c4c2cc4 100644 --- a/modules/visual_script/visual_script_builtin_funcs.cpp +++ b/modules/visual_script/visual_script_builtin_funcs.cpp @@ -63,7 +63,7 @@ const char *VisualScriptBuiltinFunc::func_name[VisualScriptBuiltinFunc::FUNC_MAX "is_nan", "is_inf", "ease", - "decimals", + "step_decimals", "stepify", "lerp", "inverse_lerp", @@ -171,7 +171,7 @@ int VisualScriptBuiltinFunc::get_func_argument_count(BuiltinFunc p_func) { case MATH_EXP: case MATH_ISNAN: case MATH_ISINF: - case MATH_DECIMALS: + case MATH_STEP_DECIMALS: case MATH_SEED: case MATH_RANDSEED: case MATH_DEG2RAD: @@ -312,7 +312,7 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const else return PropertyInfo(Variant::REAL, "curve"); } break; - case MATH_DECIMALS: { + case MATH_STEP_DECIMALS: { return PropertyInfo(Variant::REAL, "step"); } break; case MATH_STEPIFY: { @@ -528,7 +528,7 @@ PropertyInfo VisualScriptBuiltinFunc::get_output_value_port_info(int p_idx) cons case MATH_EASE: { t = Variant::REAL; } break; - case MATH_DECIMALS: { + case MATH_STEP_DECIMALS: { t = Variant::INT; } break; case MATH_STEPIFY: @@ -841,7 +841,7 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in VALIDATE_ARG_NUM(1); *r_return = Math::ease((double)*p_inputs[0], (double)*p_inputs[1]); } break; - case VisualScriptBuiltinFunc::MATH_DECIMALS: { + case VisualScriptBuiltinFunc::MATH_STEP_DECIMALS: { VALIDATE_ARG_NUM(0); *r_return = Math::step_decimals((double)*p_inputs[0]); @@ -1361,7 +1361,7 @@ void VisualScriptBuiltinFunc::_bind_methods() { BIND_ENUM_CONSTANT(MATH_ISNAN); BIND_ENUM_CONSTANT(MATH_ISINF); BIND_ENUM_CONSTANT(MATH_EASE); - BIND_ENUM_CONSTANT(MATH_DECIMALS); + BIND_ENUM_CONSTANT(MATH_STEP_DECIMALS); BIND_ENUM_CONSTANT(MATH_STEPIFY); BIND_ENUM_CONSTANT(MATH_LERP); BIND_ENUM_CONSTANT(MATH_INVERSE_LERP); @@ -1455,7 +1455,7 @@ void register_visual_script_builtin_func_node() { VisualScriptLanguage::singleton->add_register_func("functions/built_in/isinf", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_ISINF>); VisualScriptLanguage::singleton->add_register_func("functions/built_in/ease", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_EASE>); - VisualScriptLanguage::singleton->add_register_func("functions/built_in/decimals", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_DECIMALS>); + VisualScriptLanguage::singleton->add_register_func("functions/built_in/step_decimals", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_STEP_DECIMALS>); VisualScriptLanguage::singleton->add_register_func("functions/built_in/stepify", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_STEPIFY>); VisualScriptLanguage::singleton->add_register_func("functions/built_in/lerp", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_LERP>); VisualScriptLanguage::singleton->add_register_func("functions/built_in/lerp_angle", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_LERP_ANGLE>); diff --git a/modules/visual_script/visual_script_builtin_funcs.h b/modules/visual_script/visual_script_builtin_funcs.h index f5021cb545..d0787b3dd3 100644 --- a/modules/visual_script/visual_script_builtin_funcs.h +++ b/modules/visual_script/visual_script_builtin_funcs.h @@ -63,7 +63,7 @@ public: MATH_ISNAN, MATH_ISINF, MATH_EASE, - MATH_DECIMALS, + MATH_STEP_DECIMALS, MATH_STEPIFY, MATH_LERP, MATH_INVERSE_LERP, diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index ec20698ae8..9a1125c375 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -499,7 +499,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) { graph->show(); select_func_text->hide(); - Ref<Texture> type_icons[Variant::VARIANT_MAX] = { + Ref<Texture2D> type_icons[Variant::VARIANT_MAX] = { Control::get_icon("Variant", "EditorIcons"), Control::get_icon("bool", "EditorIcons"), Control::get_icon("int", "EditorIcons"), @@ -529,7 +529,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) { Control::get_icon("PoolColorArray", "EditorIcons") }; - Ref<Texture> seq_port = Control::get_icon("VisualShaderPort", "EditorIcons"); + Ref<Texture2D> seq_port = Control::get_icon("VisualShaderPort", "EditorIcons"); for (List<StringName>::Element *F = funcs.front(); F; F = F->next()) { // loop through all the functions @@ -702,7 +702,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) { vbc->add_child(hbc2); if (left_ok) { - Ref<Texture> t; + Ref<Texture2D> t; if (left_type >= 0 && left_type < Variant::VARIANT_MAX) { t = type_icons[left_type]; } @@ -830,7 +830,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) { hbc->add_child(memnew(Label(right_name))); } - Ref<Texture> t; + Ref<Texture2D> t; if (right_type >= 0 && right_type < Variant::VARIANT_MAX) { t = type_icons[right_type]; } @@ -846,7 +846,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) { bool dark_theme = get_constant("dark_theme", "Editor"); if (i < mixed_seq_ports) { - gnode->set_slot(slot_idx, left_ok, left_type, _color_from_type(left_type, dark_theme), true, TYPE_SEQUENCE, mono_color, Ref<Texture>(), seq_port); + gnode->set_slot(slot_idx, left_ok, left_type, _color_from_type(left_type, dark_theme), true, TYPE_SEQUENCE, mono_color, Ref<Texture2D>(), seq_port); } else { gnode->set_slot(slot_idx, left_ok, left_type, _color_from_type(left_type, dark_theme), right_ok, right_type, _color_from_type(right_type, dark_theme)); } @@ -955,7 +955,7 @@ void VisualScriptEditor::_update_members() { variables->add_button(0, Control::get_icon("Add", "EditorIcons"), -1, false, TTR("Create a new variable.")); variables->set_custom_color(0, Control::get_color("mono_color", "Editor")); - Ref<Texture> type_icons[Variant::VARIANT_MAX] = { + Ref<Texture2D> type_icons[Variant::VARIANT_MAX] = { Control::get_icon("Variant", "EditorIcons"), Control::get_icon("bool", "EditorIcons"), Control::get_icon("int", "EditorIcons"), @@ -2369,7 +2369,7 @@ void VisualScriptEditor::_draw_color_over_button(Object *obj, Color p_color) { button->draw_rect(Rect2(normal->get_offset(), button->get_size() - normal->get_minimum_size()), p_color); } -void VisualScriptEditor::_button_resource_previewed(const String &p_path, const Ref<Texture> &p_preview, const Ref<Texture> &p_small_preview, Variant p_ud) { +void VisualScriptEditor::_button_resource_previewed(const String &p_path, const Ref<Texture2D> &p_preview, const Ref<Texture2D> &p_small_preview, Variant p_ud) { Array ud = p_ud; ERR_FAIL_COND(ud.size() != 2); @@ -2447,7 +2447,7 @@ String VisualScriptEditor::get_name() { return name; } -Ref<Texture> VisualScriptEditor::get_icon() { +Ref<Texture2D> VisualScriptEditor::get_icon() { return Control::get_icon("VisualScript", "EditorIcons"); } @@ -4467,9 +4467,9 @@ void VisualScriptEditor::_member_rmb_selected(const Vector2 &p_pos) { TreeItem *root = members->get_root(); - Ref<Texture> del_icon = Control::get_icon("Remove", "EditorIcons"); + Ref<Texture2D> del_icon = Control::get_icon("Remove", "EditorIcons"); - Ref<Texture> edit_icon = Control::get_icon("Edit", "EditorIcons"); + Ref<Texture2D> edit_icon = Control::get_icon("Edit", "EditorIcons"); if (ti->get_parent() == root->get_children()) { @@ -4963,7 +4963,7 @@ Ref<VisualScriptNode> _VisualScriptEditor::create_node_custom(const String &p_na } _VisualScriptEditor *_VisualScriptEditor::singleton = NULL; -Map<String, RefPtr> _VisualScriptEditor::custom_nodes; +Map<String, REF> _VisualScriptEditor::custom_nodes; _VisualScriptEditor::_VisualScriptEditor() { singleton = this; @@ -4975,7 +4975,7 @@ _VisualScriptEditor::~_VisualScriptEditor() { void _VisualScriptEditor::add_custom_node(const String &p_name, const String &p_category, const Ref<Script> &p_script) { String node_name = "custom/" + p_category + "/" + p_name; - custom_nodes.insert(node_name, p_script.get_ref_ptr()); + custom_nodes.insert(node_name, p_script); VisualScriptLanguage::singleton->add_register_func(node_name, &_VisualScriptEditor::create_node_custom); emit_signal("custom_nodes_updated"); } diff --git a/modules/visual_script/visual_script_editor.h b/modules/visual_script/visual_script_editor.h index 7f3bf79d50..9f52d87b6a 100644 --- a/modules/visual_script/visual_script_editor.h +++ b/modules/visual_script/visual_script_editor.h @@ -277,7 +277,7 @@ class VisualScriptEditor : public ScriptEditorBase { void _selected_method(const String &p_method, const String &p_type, const bool p_connecting); void _draw_color_over_button(Object *obj, Color p_color); - void _button_resource_previewed(const String &p_path, const Ref<Texture> &p_preview, const Ref<Texture> &p_small_preview, Variant p_ud); + void _button_resource_previewed(const String &p_path, const Ref<Texture2D> &p_preview, const Ref<Texture2D> &p_small_preview, Variant p_ud); VisualScriptNode::TypeGuess _guess_output_type(int p_port_action_node, int p_port_action_output, Set<int> &p_visited_nodes); @@ -298,7 +298,7 @@ public: virtual Vector<String> get_functions(); virtual void reload_text(); virtual String get_name(); - virtual Ref<Texture> get_icon(); + virtual Ref<Texture2D> get_icon(); virtual bool is_unsaved(); virtual Variant get_edit_state(); virtual void set_edit_state(const Variant &p_state); @@ -341,7 +341,7 @@ protected: static void _bind_methods(); static _VisualScriptEditor *singleton; - static Map<String, RefPtr> custom_nodes; + static Map<String, REF> custom_nodes; static Ref<VisualScriptNode> create_node_custom(const String &p_name); public: diff --git a/modules/visual_script/visual_script_expression.cpp b/modules/visual_script/visual_script_expression.cpp index 4feef53c2e..63880df21d 100644 --- a/modules/visual_script/visual_script_expression.cpp +++ b/modules/visual_script/visual_script_expression.cpp @@ -392,8 +392,7 @@ Error VisualScriptExpression::_get_token(Token &r_token) { case 'f': res = 12; break; case 'r': res = 13; break; case 'u': { - //hexnumbarh - oct is deprecated - + // hex number for (int j = 0; j < 4; j++) { CharType c = GET_CHAR(); @@ -418,7 +417,7 @@ Error VisualScriptExpression::_get_token(Token &r_token) { v = c - 'A'; v += 10; } else { - ERR_PRINT("BUG"); + ERR_PRINT("Bug parsing hex constant."); v = 0; } @@ -427,13 +426,8 @@ Error VisualScriptExpression::_get_token(Token &r_token) { } } break; - //case '\"': res='\"'; break; - //case '\\': res='\\'; break; - //case '/': res='/'; break; default: { res = next; - //r_err_str="Invalid escape sequence"; - //return ERR_PARSE_ERROR; } break; } diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp index 86c1080182..dc49ed72d0 100644 --- a/modules/visual_script/visual_script_nodes.cpp +++ b/modules/visual_script/visual_script_nodes.cpp @@ -1842,7 +1842,7 @@ PropertyInfo VisualScriptGlobalConstant::get_input_value_port_info(int p_idx) co PropertyInfo VisualScriptGlobalConstant::get_output_value_port_info(int p_idx) const { String name = GlobalConstants::get_global_constant_name(index); - return PropertyInfo(Variant::REAL, name); + return PropertyInfo(Variant::INT, name); } String VisualScriptGlobalConstant::get_caption() const { @@ -1935,8 +1935,11 @@ PropertyInfo VisualScriptClassConstant::get_input_value_port_info(int p_idx) con } PropertyInfo VisualScriptClassConstant::get_output_value_port_info(int p_idx) const { - - return PropertyInfo(Variant::INT, String(base_type) + "." + String(name)); + if (name == "") { + return PropertyInfo(Variant::INT, String(base_type)); + } else { + return PropertyInfo(Variant::INT, String(base_type) + "." + String(name)); + } } String VisualScriptClassConstant::get_caption() const { @@ -1958,6 +1961,22 @@ StringName VisualScriptClassConstant::get_class_constant() { void VisualScriptClassConstant::set_base_type(const StringName &p_which) { base_type = p_which; + List<String> constants; + ClassDB::get_integer_constant_list(base_type, &constants, true); + if (constants.size() > 0) { + bool found_name = false; + for (List<String>::Element *E = constants.front(); E; E = E->next()) { + if (E->get() == name) { + found_name = true; + break; + } + } + if (!found_name) { + name = constants[0]; + } + } else { + name = ""; + } _change_notify(); ports_changed_notify(); } @@ -2060,7 +2079,7 @@ PropertyInfo VisualScriptBasicTypeConstant::get_input_value_port_info(int p_idx) PropertyInfo VisualScriptBasicTypeConstant::get_output_value_port_info(int p_idx) const { - return PropertyInfo(Variant::INT, "value"); + return PropertyInfo(type, "value"); } String VisualScriptBasicTypeConstant::get_caption() const { @@ -2069,8 +2088,11 @@ String VisualScriptBasicTypeConstant::get_caption() const { } String VisualScriptBasicTypeConstant::get_text() const { - - return Variant::get_type_name(type) + "." + String(name); + if (name == "") { + return Variant::get_type_name(type); + } else { + return Variant::get_type_name(type) + "." + String(name); + } } void VisualScriptBasicTypeConstant::set_basic_type_constant(const StringName &p_which) { @@ -2087,6 +2109,23 @@ StringName VisualScriptBasicTypeConstant::get_basic_type_constant() const { void VisualScriptBasicTypeConstant::set_basic_type(Variant::Type p_which) { type = p_which; + + List<StringName> constants; + Variant::get_constants_for_type(type, &constants); + if (constants.size() > 0) { + bool found_name = false; + for (List<StringName>::Element *E = constants.front(); E; E = E->next()) { + if (E->get() == name) { + found_name = true; + break; + } + } + if (!found_name) { + name = constants[0]; + } + } else { + name = ""; + } _change_notify(); ports_changed_notify(); } diff --git a/modules/visual_script/visual_script_property_selector.cpp b/modules/visual_script/visual_script_property_selector.cpp index 99d7ffd05f..e8c02a41c4 100644 --- a/modules/visual_script/visual_script_property_selector.cpp +++ b/modules/visual_script/visual_script_property_selector.cpp @@ -98,7 +98,7 @@ void VisualScriptPropertySelector::_update_search() { List<MethodInfo> methods; List<PropertyInfo> props; TreeItem *category = NULL; - Ref<Texture> type_icons[Variant::VARIANT_MAX] = { + Ref<Texture2D> type_icons[Variant::VARIANT_MAX] = { Control::get_icon("Variant", "EditorIcons"), Control::get_icon("bool", "EditorIcons"), Control::get_icon("int", "EditorIcons"), @@ -133,7 +133,7 @@ void VisualScriptPropertySelector::_update_search() { if (category) { category->set_text(0, b.replace_first("*", "")); category->set_selectable(0, false); - Ref<Texture> icon; + Ref<Texture2D> icon; String rep = b.replace("*", ""); icon = EditorNode::get_singleton()->get_class_icon(rep); category->set_icon(0, icon); @@ -529,7 +529,6 @@ void VisualScriptPropertySelector::select_method_from_base_type(const String &p_ base_type = p_base; selected = p_current; type = Variant::NIL; - script = 0; properties = false; instance = NULL; virtuals_only = p_virtuals_only; @@ -554,7 +553,6 @@ void VisualScriptPropertySelector::select_from_base_type(const String &p_base, c base_type = p_base; selected = p_current; type = Variant::NIL; - script = 0; properties = true; visual_script_generic = false; instance = NULL; @@ -601,7 +599,6 @@ void VisualScriptPropertySelector::select_from_basic_type(Variant::Type p_type, base_type = ""; selected = p_current; type = p_type; - script = 0; properties = true; visual_script_generic = false; instance = NULL; @@ -623,7 +620,6 @@ void VisualScriptPropertySelector::select_from_action(const String &p_type, cons base_type = p_type; selected = p_current; type = Variant::NIL; - script = 0; properties = false; visual_script_generic = false; instance = NULL; @@ -645,7 +641,6 @@ void VisualScriptPropertySelector::select_from_instance(Object *p_instance, cons base_type = p_basetype; selected = p_current; type = Variant::NIL; - script = 0; properties = true; visual_script_generic = false; instance = p_instance; @@ -667,7 +662,6 @@ void VisualScriptPropertySelector::select_from_visual_script(const String &p_bas base_type = p_base; selected = ""; type = Variant::NIL; - script = 0; properties = true; visual_script_generic = true; instance = NULL; diff --git a/modules/webm/video_stream_webm.cpp b/modules/webm/video_stream_webm.cpp index 41f9e67672..54d34a48c5 100644 --- a/modules/webm/video_stream_webm.cpp +++ b/modules/webm/video_stream_webm.cpp @@ -141,7 +141,10 @@ bool VideoStreamPlaybackWebm::open_file(const String &p_file) { } frame_data.resize((webm->getWidth() * webm->getHeight()) << 2); - texture->create(webm->getWidth(), webm->getHeight(), Image::FORMAT_RGBA8, Texture::FLAG_FILTER | Texture::FLAG_VIDEO_SURFACE); + Ref<Image> img; + img.instance(); + img->create(webm->getWidth(), webm->getHeight(), false, Image::FORMAT_RGBA8); + texture->create_from_image(img); return true; } @@ -231,7 +234,7 @@ void VideoStreamPlaybackWebm::set_audio_track(int p_idx) { audio_track = p_idx; } -Ref<Texture> VideoStreamPlaybackWebm::get_texture() const { +Ref<Texture2D> VideoStreamPlaybackWebm::get_texture() const { return texture; } @@ -356,7 +359,7 @@ void VideoStreamPlaybackWebm::update(float p_delta) { if (converted) { Ref<Image> img = memnew(Image(image.w, image.h, 0, Image::FORMAT_RGBA8, frame_data)); - texture->set_data(img); //Zero copy send to visual server + texture->update(img); //Zero copy send to visual server video_frame_done = true; } } @@ -393,17 +396,22 @@ int VideoStreamPlaybackWebm::get_mix_rate() const { inline bool VideoStreamPlaybackWebm::has_enough_video_frames() const { if (video_frames_pos > 0) { - - const double audio_delay = AudioServer::get_singleton()->get_output_latency(); + // FIXME: AudioServer output latency was fixed in af9bb0e, previously it used to + // systematically return 0. Now that it gives a proper latency, it broke this + // code where the delay compensation likely never really worked. + //const double audio_delay = AudioServer::get_singleton()->get_output_latency(); const double video_time = video_frames[video_frames_pos - 1]->time; - return video_time >= time + audio_delay + delay_compensation; + return video_time >= time + /* audio_delay + */ delay_compensation; } return false; } bool VideoStreamPlaybackWebm::should_process(WebMFrame &video_frame) { - const double audio_delay = AudioServer::get_singleton()->get_output_latency(); - return video_frame.time >= time + audio_delay + delay_compensation; + // FIXME: AudioServer output latency was fixed in af9bb0e, previously it used to + // systematically return 0. Now that it gives a proper latency, it broke this + // code where the delay compensation likely never really worked. + //const double audio_delay = AudioServer::get_singleton()->get_output_latency(); + return video_frame.time >= time + /* audio_delay + */ delay_compensation; } void VideoStreamPlaybackWebm::delete_pointers() { diff --git a/modules/webm/video_stream_webm.h b/modules/webm/video_stream_webm.h index e679196cf2..f2a68dd701 100644 --- a/modules/webm/video_stream_webm.h +++ b/modules/webm/video_stream_webm.h @@ -90,7 +90,7 @@ public: virtual void set_audio_track(int p_idx); - virtual Ref<Texture> get_texture() const; + virtual Ref<Texture2D> get_texture() const; virtual void update(float p_delta); virtual void set_mix_callback(AudioMixCallback p_callback, void *p_userdata); diff --git a/modules/websocket/emws_client.cpp b/modules/websocket/emws_client.cpp index 7e68936fc3..e5680ce2e9 100644 --- a/modules/websocket/emws_client.cpp +++ b/modules/websocket/emws_client.cpp @@ -91,10 +91,14 @@ Error EMWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port, int peer_sock = EM_ASM_INT({ var proto_str = UTF8ToString($2); var socket = null; - if (proto_str) { - socket = new WebSocket(UTF8ToString($1), proto_str.split(",")); - } else { - socket = new WebSocket(UTF8ToString($1)); + try { + if (proto_str) { + socket = new WebSocket(UTF8ToString($1), proto_str.split(",")); + } else { + socket = new WebSocket(UTF8ToString($1)); + } + } catch (e) { + return -1; } var c_ptr = Module.IDHandler.get($0); socket.binaryType = "arraybuffer"; @@ -174,6 +178,8 @@ Error EMWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port, return Module.IDHandler.add(socket); }, _js_id, str.utf8().get_data(), proto_string.utf8().get_data()); /* clang-format on */ + if (peer_sock == -1) + return FAILED; static_cast<Ref<EMWSPeer> >(_peer)->set_sock(peer_sock, _in_buf_size, _in_pkt_size); @@ -190,11 +196,11 @@ Ref<WebSocketPeer> EMWSClient::get_peer(int p_peer_id) const { NetworkedMultiplayerPeer::ConnectionStatus EMWSClient::get_connection_status() const { - if (_peer->is_connected_to_host()) + if (_peer->is_connected_to_host()) { + if (_is_connecting) + return CONNECTION_CONNECTING; return CONNECTION_CONNECTED; - - if (_is_connecting) - return CONNECTION_CONNECTING; + } return CONNECTION_DISCONNECTED; }; diff --git a/modules/websocket/emws_peer.cpp b/modules/websocket/emws_peer.cpp index effed8e4d9..588f38cffd 100644 --- a/modules/websocket/emws_peer.cpp +++ b/modules/websocket/emws_peer.cpp @@ -68,12 +68,17 @@ Error EMWSPeer::put_packet(const uint8_t *p_buffer, int p_buffer_size) { bytes_array[i] = getValue($1+i, 'i8'); } - if ($3) { - sock.send(bytes_array.buffer); - } else { - var string = new TextDecoder("utf-8").decode(bytes_array); - sock.send(string); + try { + if ($3) { + sock.send(bytes_array.buffer); + } else { + var string = new TextDecoder("utf-8").decode(bytes_array); + sock.send(string); + } + } catch (e) { + return 1; } + return 0; }, peer_sock, p_buffer, p_buffer_size, is_bin); /* clang-format on */ |