diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/bullet/shape_bullet.cpp | 57 | ||||
-rw-r--r-- | modules/csg/csg_shape.cpp | 13 | ||||
-rw-r--r-- | modules/csg/csg_shape.h | 1 | ||||
-rw-r--r-- | modules/gdscript/gdscript_functions.cpp | 12 | ||||
-rw-r--r-- | modules/gdscript/gdscript_parser.cpp | 21 | ||||
-rw-r--r-- | modules/mono/csharp_script.cpp | 31 | ||||
-rw-r--r-- | modules/mono/csharp_script.h | 4 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_class.cpp | 21 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_class.h | 7 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_method.cpp | 27 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_method.h | 5 | ||||
-rw-r--r-- | modules/visual_script/visual_script_editor.cpp | 1 | ||||
-rw-r--r-- | modules/webp/SCsub | 2 |
13 files changed, 153 insertions, 49 deletions
diff --git a/modules/bullet/shape_bullet.cpp b/modules/bullet/shape_bullet.cpp index 8bb621a863..2027d8e1eb 100644 --- a/modules/bullet/shape_bullet.cpp +++ b/modules/bullet/shape_bullet.cpp @@ -461,7 +461,47 @@ void HeightMapShapeBullet::set_data(const Variant &p_data) { int l_width = d["width"]; int l_depth = d["depth"]; - PoolVector<real_t> l_heights = d["heights"]; + + // TODO This code will need adjustments if real_t is set to `double`, + // because that precision is unnecessary for a heightmap and Bullet doesn't support it... + + PoolVector<real_t> l_heights; + Variant l_heights_v = d["heights"]; + + if (l_heights_v.get_type() == Variant::POOL_REAL_ARRAY) { + // Ready-to-use heights can be passed + + l_heights = l_heights_v; + + } else if (l_heights_v.get_type() == Variant::OBJECT) { + // If an image is passed, we have to convert it to a format Bullet supports. + // this would be expensive to do with a script, so it's nice to have it here. + + Ref<Image> l_image = l_heights_v; + ERR_FAIL_COND(l_image.is_null()); + + // Float is the only common format between Godot and Bullet that can be used for decent collision. + // (Int16 would be nice too but we still don't have it) + // We could convert here automatically but it's better to not be intrusive and let the caller do it if necessary. + ERR_FAIL_COND(l_image->get_format() != Image::FORMAT_RF); + + PoolByteArray im_data = l_image->get_data(); + + l_heights.resize(l_image->get_width() * l_image->get_width()); + + PoolRealArray::Write w = l_heights.write(); + PoolByteArray::Read r = im_data.read(); + float *rp = (float *)r.ptr(); + // At this point, `rp` could be used directly for Bullet, but I don't know how safe it would be. + + for (int i = 0; i < l_heights.size(); ++i) { + w[i] = rp[i]; + } + + } else { + ERR_EXPLAIN("Expected PoolRealArray or float Image."); + ERR_FAIL(); + } ERR_FAIL_COND(l_width <= 0); ERR_FAIL_COND(l_depth <= 0); @@ -497,19 +537,8 @@ PhysicsServer::ShapeType HeightMapShapeBullet::get_type() const { void HeightMapShapeBullet::setup(PoolVector<real_t> &p_heights, int p_width, int p_depth, real_t p_min_height, real_t p_max_height) { // TODO cell size must be tweaked using localScaling, which is a shared property for all Bullet shapes - { // Copy - - // TODO If Godot supported 16-bit integer image format, we could share the same memory block for heightfields - // without having to copy anything, optimizing memory and loading performance (Bullet only reads and doesn't take ownership of the data). - - const int heights_size = p_heights.size(); - heights.resize(heights_size); - PoolVector<real_t>::Read p_heights_r = p_heights.read(); - PoolVector<real_t>::Write heights_w = heights.write(); - for (int i = heights_size - 1; 0 <= i; --i) { - heights_w[i] = p_heights_r[i]; - } - } + // If this array is resized outside of here, it should be preserved due to CoW + heights = p_heights; width = p_width; depth = p_depth; diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp index 4e35014459..f4b061f494 100644 --- a/modules/csg/csg_shape.cpp +++ b/modules/csg/csg_shape.cpp @@ -197,17 +197,6 @@ void CSGShape::mikktGetTexCoord(const SMikkTSpaceContext *pContext, float fvTexc fvTexcOut[1] = t.y; } -void CSGShape::mikktSetTSpaceBasic(const SMikkTSpaceContext *pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert) { - ShapeUpdateSurface &surface = *((ShapeUpdateSurface *)pContext->m_pUserData); - - int i = (iFace * 3 + iVert) * 4; - - surface.tansw[i++] = fvTangent[0]; - surface.tansw[i++] = fvTangent[1]; - surface.tansw[i++] = fvTangent[2]; - surface.tansw[i++] = fSign; -} - void CSGShape::mikktSetTSpaceDefault(const SMikkTSpaceContext *pContext, const float fvTangent[], const float fvBiTangent[], const float fMagS, const float fMagT, const tbool bIsOrientationPreserving, const int iFace, const int iVert) { @@ -216,7 +205,7 @@ void CSGShape::mikktSetTSpaceDefault(const SMikkTSpaceContext *pContext, const f int i = iFace * 3 + iVert; Vector3 normal = surface.normalsw[i]; Vector3 tangent = Vector3(fvTangent[0], fvTangent[1], fvTangent[2]); - Vector3 bitangent = Vector3(fvBiTangent[0], fvBiTangent[1], fvBiTangent[2]); + Vector3 bitangent = Vector3(-fvBiTangent[0], -fvBiTangent[1], -fvBiTangent[2]); // for some reason these are reversed, something with the coordinate system in Godot float d = bitangent.dot(normal.cross(tangent)); i *= 4; diff --git a/modules/csg/csg_shape.h b/modules/csg/csg_shape.h index 0a4bb5f665..7326f3d36a 100644 --- a/modules/csg/csg_shape.h +++ b/modules/csg/csg_shape.h @@ -97,7 +97,6 @@ private: static void mikktGetPosition(const SMikkTSpaceContext *pContext, float fvPosOut[], const int iFace, const int iVert); static void mikktGetNormal(const SMikkTSpaceContext *pContext, float fvNormOut[], const int iFace, const int iVert); static void mikktGetTexCoord(const SMikkTSpaceContext *pContext, float fvTexcOut[], const int iFace, const int iVert); - static void mikktSetTSpaceBasic(const SMikkTSpaceContext *pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert); static void mikktSetTSpaceDefault(const SMikkTSpaceContext *pContext, const float fvTangent[], const float fvBiTangent[], const float fMagS, const float fMagT, const tbool bIsOrientationPreserving, const int iFace, const int iVert); diff --git a/modules/gdscript/gdscript_functions.cpp b/modules/gdscript/gdscript_functions.cpp index 2f31d59c46..9ff33594ce 100644 --- a/modules/gdscript/gdscript_functions.cpp +++ b/modules/gdscript/gdscript_functions.cpp @@ -758,22 +758,14 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ r_ret = Variant(); return; } + r_ret = *p_args[0]; VariantParser::StreamString ss; ss.s = *p_args[0]; String errs; int line; - Error err = VariantParser::parse(&ss, r_ret, errs, line); - - if (err != OK) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; - r_error.argument = 0; - r_error.expected = Variant::STRING; - r_ret = "Parse error at line " + itos(line) + ": " + errs; - return; - } - + (void)VariantParser::parse(&ss, r_ret, errs, line); } break; case VAR_TO_BYTES: { VALIDATE_ARG_COUNT(1); diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 0926c1a1ab..6ea0dbcb19 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -5746,18 +5746,23 @@ bool GDScriptParser::_is_type_compatible(const DataType &p_container, const Data if (p_container.kind == DataType::BUILTIN && p_expression.kind == DataType::BUILTIN) { bool valid = p_container.builtin_type == p_expression.builtin_type; if (p_allow_implicit_conversion) { - valid = valid || (p_container.builtin_type == Variant::INT && p_expression.builtin_type == Variant::REAL); - valid = valid || (p_container.builtin_type == Variant::REAL && p_expression.builtin_type == Variant::INT); - valid = valid || (p_container.builtin_type == Variant::STRING && p_expression.builtin_type == Variant::NODE_PATH); - valid = valid || (p_container.builtin_type == Variant::NODE_PATH && p_expression.builtin_type == Variant::STRING); - valid = valid || (p_container.builtin_type == Variant::BOOL && p_expression.builtin_type == Variant::REAL); - valid = valid || (p_container.builtin_type == Variant::BOOL && p_expression.builtin_type == Variant::INT); - valid = valid || (p_container.builtin_type == Variant::INT && p_expression.builtin_type == Variant::BOOL); - valid = valid || (p_container.builtin_type == Variant::REAL && p_expression.builtin_type == Variant::BOOL); + valid = valid || Variant::can_convert_strict(p_expression.builtin_type, p_container.builtin_type); } return valid; } + if (p_container.kind == DataType::BUILTIN && p_container.builtin_type == Variant::OBJECT) { + // Object built-in is a special case, it's compatible with any object and with null + if (p_expression.kind == DataType::BUILTIN && p_expression.builtin_type == Variant::NIL) { + return true; + } + if (p_expression.kind == DataType::BUILTIN) { + return false; + } + // If it's not a built-in, must be an object + return true; + } + if (p_container.kind == DataType::BUILTIN || (p_expression.kind == DataType::BUILTIN && p_expression.builtin_type != Variant::NIL)) { // Can't mix built-ins with objects return false; diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 3c818898e6..943d95bfc9 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -2474,6 +2474,18 @@ void CSharpScript::set_source_code(const String &p_code) { #endif } +void CSharpScript::get_script_method_list(List<MethodInfo> *p_list) const { + + if (!script_class) + return; + + // TODO: Filter out things unsuitable for explicit calls, like constructors. + const Vector<GDMonoMethod *> &methods = script_class->get_all_methods(); + for (int i = 0; i < methods.size(); ++i) { + p_list->push_back(methods[i]->get_method_info()); + } +} + bool CSharpScript::has_method(const StringName &p_method) const { if (!script_class) @@ -2482,6 +2494,25 @@ bool CSharpScript::has_method(const StringName &p_method) const { return script_class->has_fetched_method_unknown_params(p_method); } +MethodInfo CSharpScript::get_method_info(const StringName &p_method) const { + + if (!script_class) + return MethodInfo(); + + GDMonoClass *top = script_class; + + while (top && top != native) { + GDMonoMethod *params = top->get_fetched_method_unknown_params(p_method); + if (params) { + return params->get_method_info(); + } + + top = top->get_parent_class(); + } + + return MethodInfo(); +} + Error CSharpScript::reload(bool p_keep_state) { bool has_instances; diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h index 501e0d9d6d..08466bae58 100644 --- a/modules/mono/csharp_script.h +++ b/modules/mono/csharp_script.h @@ -174,9 +174,9 @@ public: virtual Ref<Script> get_base_script() const; virtual ScriptLanguage *get_language() const; - /* TODO */ virtual void get_script_method_list(List<MethodInfo> *p_list) const {} + virtual void get_script_method_list(List<MethodInfo> *p_list) const; bool has_method(const StringName &p_method) const; - /* TODO */ MethodInfo get_method_info(const StringName &p_method) const { return MethodInfo(); } + MethodInfo get_method_info(const StringName &p_method) const; virtual int get_member_line(const StringName &p_member) const; diff --git a/modules/mono/mono_gd/gd_mono_class.cpp b/modules/mono/mono_gd/gd_mono_class.cpp index 4e515cde28..c55f9160bd 100644 --- a/modules/mono/mono_gd/gd_mono_class.cpp +++ b/modules/mono/mono_gd/gd_mono_class.cpp @@ -151,6 +151,7 @@ void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base while ((raw_method = mono_class_get_methods(get_mono_ptr(), &iter)) != NULL) { StringName name = mono_method_get_name(raw_method); + // get_method implicitly fetches methods and adds them to this->methods GDMonoMethod *method = get_method(raw_method, name); ERR_CONTINUE(!method); @@ -449,6 +450,21 @@ const Vector<GDMonoClass *> &GDMonoClass::get_all_delegates() { return delegates_list; } +const Vector<GDMonoMethod *> &GDMonoClass::get_all_methods() { + + if (!method_list_fetched) { + void *iter = NULL; + MonoMethod *raw_method = NULL; + while ((raw_method = mono_class_get_methods(get_mono_ptr(), &iter)) != NULL) { + method_list.push_back(memnew(GDMonoMethod(mono_method_get_name(raw_method), raw_method))); + } + + method_list_fetched = true; + } + + return method_list; +} + GDMonoClass::GDMonoClass(const StringName &p_namespace, const StringName &p_name, MonoClass *p_class, GDMonoAssembly *p_assembly) { namespace_name = p_namespace; @@ -460,6 +476,7 @@ GDMonoClass::GDMonoClass(const StringName &p_namespace, const StringName &p_name attributes = NULL; methods_fetched = false; + method_list_fetched = false; fields_fetched = false; properties_fetched = false; delegates_fetched = false; @@ -512,4 +529,8 @@ GDMonoClass::~GDMonoClass() { methods.clear(); } + + for (int i = 0; i < method_list.size(); ++i) { + memdelete(method_list[i]); + } } diff --git a/modules/mono/mono_gd/gd_mono_class.h b/modules/mono/mono_gd/gd_mono_class.h index 477305d503..689001f494 100644 --- a/modules/mono/mono_gd/gd_mono_class.h +++ b/modules/mono/mono_gd/gd_mono_class.h @@ -79,9 +79,14 @@ class GDMonoClass { bool attrs_fetched; MonoCustomAttrInfo *attributes; + // This contains both the original method names and remapped method names from the native Godot identifiers to the C# functions. + // Most method-related functions refer to this and it's possible this is unintuitive for outside users; this may be a prime location for refactoring or renaming. bool methods_fetched; HashMap<MethodKey, GDMonoMethod *, MethodKey::Hasher> methods; + bool method_list_fetched; + Vector<GDMonoMethod *> method_list; + bool fields_fetched; Map<StringName, GDMonoField *> fields; Vector<GDMonoField *> fields_list; @@ -143,6 +148,8 @@ public: const Vector<GDMonoClass *> &get_all_delegates(); + const Vector<GDMonoMethod *> &get_all_methods(); + ~GDMonoClass(); }; diff --git a/modules/mono/mono_gd/gd_mono_method.cpp b/modules/mono/mono_gd/gd_mono_method.cpp index 630bda8b4e..6ef6e97f5a 100644 --- a/modules/mono/mono_gd/gd_mono_method.cpp +++ b/modules/mono/mono_gd/gd_mono_method.cpp @@ -68,6 +68,10 @@ void GDMonoMethod::_update_signature(MonoMethodSignature *p_method_sig) { param_types.push_back(param_type); } + + // clear the cache + method_info_fetched = false; + method_info = MethodInfo(); } bool GDMonoMethod::is_static() { @@ -246,11 +250,34 @@ void GDMonoMethod::get_parameter_types(Vector<ManagedType> &types) const { } } +const MethodInfo &GDMonoMethod::get_method_info() { + + if (!method_info_fetched) { + method_info.name = name; + method_info.return_val = PropertyInfo(GDMonoMarshal::managed_to_variant_type(return_type), ""); + + Vector<StringName> names; + get_parameter_names(names); + + for (int i = 0; i < params_count; ++i) { + method_info.arguments.push_back(PropertyInfo(GDMonoMarshal::managed_to_variant_type(param_types[i]), names[i])); + } + + // TODO: default arguments + + method_info_fetched = true; + } + + return method_info; +} + GDMonoMethod::GDMonoMethod(StringName p_name, MonoMethod *p_method) { name = p_name; mono_method = p_method; + method_info_fetched = false; + attrs_fetched = false; attributes = NULL; diff --git a/modules/mono/mono_gd/gd_mono_method.h b/modules/mono/mono_gd/gd_mono_method.h index 444ec2a67d..6c3ae5fce0 100644 --- a/modules/mono/mono_gd/gd_mono_method.h +++ b/modules/mono/mono_gd/gd_mono_method.h @@ -43,6 +43,9 @@ class GDMonoMethod : public GDMonoClassMember { ManagedType return_type; Vector<ManagedType> param_types; + bool method_info_fetched; + MethodInfo method_info; + bool attrs_fetched; MonoCustomAttrInfo *attributes; @@ -83,6 +86,8 @@ public: void get_parameter_names(Vector<StringName> &names) const; void get_parameter_types(Vector<ManagedType> &types) const; + const MethodInfo &get_method_info(); + GDMonoMethod(StringName p_name, MonoMethod *p_method); ~GDMonoMethod(); }; diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index afaa6a9b95..080d0643a2 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -3491,6 +3491,7 @@ VisualScriptEditor::VisualScriptEditor() { edit_menu = memnew(MenuButton); edit_menu->set_text(TTR("Edit")); + edit_menu->set_switch_on_hover(true); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("visual_script_editor/delete_selected"), EDIT_DELETE_NODES); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("visual_script_editor/toggle_breakpoint"), EDIT_TOGGLE_BREAKPOINT); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("visual_script_editor/find_node_type"), EDIT_FIND_NODE_TYPE); diff --git a/modules/webp/SCsub b/modules/webp/SCsub index 8a4307fbe1..d215f19cef 100644 --- a/modules/webp/SCsub +++ b/modules/webp/SCsub @@ -42,7 +42,6 @@ if env['builtin_libwebp']: "dsp/dec_neon.c", "dsp/dec_sse2.c", "dsp/dec_sse41.c", - "dsp/enc_avx2.c", "dsp/enc.c", "dsp/enc_mips32.c", "dsp/enc_mips_dsp_r2.c", @@ -90,7 +89,6 @@ if env['builtin_libwebp']: "enc/backward_references_enc.c", "enc/config_enc.c", "enc/cost_enc.c", - "enc/delta_palettization_enc.c", "enc/filter_enc.c", "enc/frame_enc.c", "enc/histogram_enc.c", |