summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/bullet/shape_bullet.cpp57
-rw-r--r--modules/csg/csg_shape.cpp13
-rw-r--r--modules/csg/csg_shape.h1
-rw-r--r--modules/gdscript/gdscript_functions.cpp12
-rw-r--r--modules/gdscript/gdscript_parser.cpp21
-rw-r--r--modules/mono/csharp_script.cpp31
-rw-r--r--modules/mono/csharp_script.h4
-rw-r--r--modules/mono/mono_gd/gd_mono_class.cpp21
-rw-r--r--modules/mono/mono_gd/gd_mono_class.h7
-rw-r--r--modules/mono/mono_gd/gd_mono_method.cpp27
-rw-r--r--modules/mono/mono_gd/gd_mono_method.h5
-rw-r--r--modules/visual_script/visual_script_editor.cpp1
-rw-r--r--modules/webp/SCsub2
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",