diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/gdscript/gdscript_editor.cpp | 15 | ||||
-rw-r--r-- | modules/gdscript/gdscript_parser.cpp | 288 | ||||
-rw-r--r-- | modules/glslang/glslang_resource_limits.h | 18 | ||||
-rw-r--r-- | modules/gltf/doc_classes/GLTFPhysicsBody.xml | 6 | ||||
-rw-r--r-- | modules/gltf/doc_classes/GLTFSkeleton.xml | 2 | ||||
-rw-r--r-- | modules/gltf/extensions/physics/gltf_physics_body.cpp | 37 | ||||
-rw-r--r-- | modules/gltf/extensions/physics/gltf_physics_body.h | 6 | ||||
-rw-r--r-- | modules/mono/csharp_script.cpp | 5 | ||||
-rw-r--r-- | modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs | 14 | ||||
-rw-r--r-- | modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs | 12 | ||||
-rw-r--r-- | modules/mono/editor/GodotTools/GodotTools/Build/DotNetFinder.cs | 6 | ||||
-rw-r--r-- | modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs | 23 | ||||
-rw-r--r-- | modules/mono/editor/bindings_generator.cpp | 26 | ||||
-rw-r--r-- | modules/mono/icons/CSharpScript.svg | 2 | ||||
-rw-r--r-- | modules/text_server_adv/thorvg_svg_in_ot.cpp | 2 | ||||
-rw-r--r-- | modules/text_server_fb/thorvg_svg_in_ot.cpp | 2 |
16 files changed, 303 insertions, 161 deletions
diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index 829567d734..09af51656c 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -906,19 +906,20 @@ static void _list_available_types(bool p_inherit_only, GDScriptParser::Completio } } -static void _find_identifiers_in_suite(const GDScriptParser::SuiteNode *p_suite, HashMap<String, ScriptLanguage::CodeCompletionOption> &r_result) { +static void _find_identifiers_in_suite(const GDScriptParser::SuiteNode *p_suite, HashMap<String, ScriptLanguage::CodeCompletionOption> &r_result, int p_recursion_depth = 0) { for (int i = 0; i < p_suite->locals.size(); i++) { ScriptLanguage::CodeCompletionOption option; + int location = p_recursion_depth == 0 ? ScriptLanguage::LOCATION_LOCAL : (p_recursion_depth | ScriptLanguage::LOCATION_PARENT_MASK); if (p_suite->locals[i].type == GDScriptParser::SuiteNode::Local::CONSTANT) { - option = ScriptLanguage::CodeCompletionOption(p_suite->locals[i].name, ScriptLanguage::CODE_COMPLETION_KIND_CONSTANT, ScriptLanguage::LOCATION_LOCAL); + option = ScriptLanguage::CodeCompletionOption(p_suite->locals[i].name, ScriptLanguage::CODE_COMPLETION_KIND_CONSTANT, location); option.default_value = p_suite->locals[i].constant->initializer->reduced_value; } else { - option = ScriptLanguage::CodeCompletionOption(p_suite->locals[i].name, ScriptLanguage::CODE_COMPLETION_KIND_VARIABLE, ScriptLanguage::LOCATION_LOCAL); + option = ScriptLanguage::CodeCompletionOption(p_suite->locals[i].name, ScriptLanguage::CODE_COMPLETION_KIND_VARIABLE, location); } r_result.insert(option.display, option); } if (p_suite->parent_block) { - _find_identifiers_in_suite(p_suite->parent_block, r_result); + _find_identifiers_in_suite(p_suite->parent_block, r_result, p_recursion_depth + 1); } } @@ -933,7 +934,7 @@ static void _find_identifiers_in_class(const GDScriptParser::ClassNode *p_class, int classes_processed = 0; while (clss) { for (int i = 0; i < clss->members.size(); i++) { - const int location = (classes_processed + p_recursion_depth) | ScriptLanguage::LOCATION_PARENT_MASK; + const int location = p_recursion_depth == 0 ? classes_processed : (p_recursion_depth | ScriptLanguage::LOCATION_PARENT_MASK); const GDScriptParser::ClassNode::Member &member = clss->members[i]; ScriptLanguage::CodeCompletionOption option; switch (member.type) { @@ -1025,7 +1026,7 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base while (!base_type.has_no_type()) { switch (base_type.kind) { case GDScriptParser::DataType::CLASS: { - _find_identifiers_in_class(base_type.class_type, p_only_functions, base_type.is_meta_type, false, r_result, p_recursion_depth + 1); + _find_identifiers_in_class(base_type.class_type, p_only_functions, base_type.is_meta_type, false, r_result, p_recursion_depth); // This already finds all parent identifiers, so we are done. base_type = GDScriptParser::DataType(); } break; @@ -1205,7 +1206,7 @@ static void _find_identifiers(const GDScriptParser::CompletionContext &p_context } if (p_context.current_class) { - _find_identifiers_in_class(p_context.current_class, p_only_functions, (!p_context.current_function || p_context.current_function->is_static), false, r_result, p_recursion_depth + 1); + _find_identifiers_in_class(p_context.current_class, p_only_functions, (!p_context.current_function || p_context.current_function->is_static), false, r_result, p_recursion_depth); } List<StringName> functions; diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index fdbd505975..d90503c658 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -3293,31 +3293,114 @@ GDScriptParser::TypeNode *GDScriptParser::parse_type(bool p_allow_void) { } #ifdef TOOLS_ENABLED -static bool _in_codeblock(String p_line, bool p_already_in, int *r_block_begins = nullptr) { - int start_block = p_line.rfind("[codeblock]"); - int end_block = p_line.rfind("[/codeblock]"); - - if (start_block != -1 && r_block_begins) { - *r_block_begins = start_block; +enum DocLineState { + DOC_LINE_NORMAL, + DOC_LINE_IN_CODE, + DOC_LINE_IN_CODEBLOCK, +}; + +static String _process_doc_line(const String &p_line, const String &p_text, const String &p_space_prefix, DocLineState &r_state) { + String line = p_line; + if (r_state == DOC_LINE_NORMAL) { + line = line.strip_edges(true, false); + } else { + line = line.trim_prefix(p_space_prefix); } - if (p_already_in) { - if (end_block == -1) { - return true; - } else if (start_block == -1) { - return false; + String line_join; + if (!p_text.is_empty()) { + if (r_state == DOC_LINE_NORMAL) { + if (p_text.ends_with("[/codeblock]")) { + line_join = "\n"; + } else if (!p_text.ends_with("[br]")) { + line_join = " "; + } } else { - return start_block > end_block; + line_join = "\n"; } - } else { - if (start_block == -1) { - return false; - } else if (end_block == -1) { - return true; - } else { - return start_block > end_block; + } + + String result; + int from = 0; + int buffer_start = 0; + const int len = line.length(); + bool process = true; + while (process) { + switch (r_state) { + case DOC_LINE_NORMAL: { + int lb_pos = line.find_char('[', from); + if (lb_pos < 0) { + process = false; + break; + } + int rb_pos = line.find_char(']', lb_pos + 1); + if (rb_pos < 0) { + process = false; + break; + } + + from = rb_pos + 1; + + String tag = line.substr(lb_pos + 1, rb_pos - lb_pos - 1); + if (tag == "code") { + r_state = DOC_LINE_IN_CODE; + } else if (tag == "codeblock") { + if (lb_pos == 0) { + line_join = "\n"; + } else { + result += line.substr(buffer_start, lb_pos - buffer_start) + '\n'; + } + result += "[codeblock]"; + if (from < len) { + result += '\n'; + } + + r_state = DOC_LINE_IN_CODEBLOCK; + buffer_start = from; + } + } break; + case DOC_LINE_IN_CODE: { + int pos = line.find("[/code]", from); + if (pos < 0) { + process = false; + break; + } + + from = pos + 7; + + r_state = DOC_LINE_NORMAL; + } break; + case DOC_LINE_IN_CODEBLOCK: { + int pos = line.find("[/codeblock]", from); + if (pos < 0) { + process = false; + break; + } + + from = pos + 12; + + if (pos == 0) { + line_join = "\n"; + } else { + result += line.substr(buffer_start, pos - buffer_start) + '\n'; + } + result += "[/codeblock]"; + if (from < len) { + result += '\n'; + } + + r_state = DOC_LINE_NORMAL; + buffer_start = from; + } break; } } + + result += line.substr(buffer_start); + if (r_state == DOC_LINE_NORMAL) { + result = result.strip_edges(false, true); + } + + return line_join + result; } bool GDScriptParser::has_comment(int p_line, bool p_must_be_doc) { @@ -3345,7 +3428,7 @@ String GDScriptParser::get_doc_comment(int p_line, bool p_single_line) { String doc; int line = p_line; - bool in_codeblock = false; + DocLineState state = DOC_LINE_NORMAL; while (comments.has(line - 1)) { if (!comments[line - 1].new_line || !comments[line - 1].comment.begins_with("##")) { @@ -3354,29 +3437,24 @@ String GDScriptParser::get_doc_comment(int p_line, bool p_single_line) { line--; } - int codeblock_begins = 0; + String space_prefix; + if (comments.has(line) && comments[line].comment.begins_with("##")) { + int i = 2; + for (; i < comments[line].comment.length(); i++) { + if (comments[line].comment[i] != ' ') { + break; + } + } + space_prefix = String(" ").repeat(i - 2); + } + while (comments.has(line)) { if (!comments[line].new_line || !comments[line].comment.begins_with("##")) { break; } - String doc_line = comments[line].comment.trim_prefix("##"); - - in_codeblock = _in_codeblock(doc_line, in_codeblock, &codeblock_begins); - - if (in_codeblock) { - int i = 0; - for (; i < codeblock_begins; i++) { - if (doc_line[i] != ' ') { - break; - } - } - doc_line = doc_line.substr(i); - } else { - doc_line = doc_line.strip_edges(); - } - String line_join = (in_codeblock) ? "\n" : " "; - doc = (doc.is_empty()) ? doc_line : doc + line_join + doc_line; + String doc_line = comments[line].comment.trim_prefix("##"); + doc += _process_doc_line(doc_line, doc, space_prefix, state); line++; } @@ -3391,7 +3469,7 @@ void GDScriptParser::get_class_doc_comment(int p_line, String &p_brief, String & ERR_FAIL_COND(!p_brief.is_empty() || !p_desc.is_empty() || p_tutorials.size() != 0); int line = p_line; - bool in_codeblock = false; + DocLineState state = DOC_LINE_NORMAL; enum Mode { BRIEF, DESC, @@ -3409,96 +3487,87 @@ void GDScriptParser::get_class_doc_comment(int p_line, String &p_brief, String & } } - int codeblock_begins = 0; + String space_prefix; + if (comments.has(line) && comments[line].comment.begins_with("##")) { + int i = 2; + for (; i < comments[line].comment.length(); i++) { + if (comments[line].comment[i] != ' ') { + break; + } + } + space_prefix = String(" ").repeat(i - 2); + } + while (comments.has(line)) { if (!comments[line].new_line || !comments[line].comment.begins_with("##")) { break; } - String title, link; // For tutorials. String doc_line = comments[line++].comment.trim_prefix("##"); - String stripped_line = doc_line.strip_edges(); - - // Set the read mode. - if (stripped_line.is_empty() && mode == BRIEF && !p_brief.is_empty()) { - mode = DESC; - continue; - - } else if (stripped_line.begins_with("@tutorial")) { - int begin_scan = String("@tutorial").length(); - if (begin_scan >= stripped_line.length()) { - continue; // invalid syntax. - } - - if (stripped_line[begin_scan] == ':') { // No title. - // Syntax: ## @tutorial: https://godotengine.org/ // The title argument is optional. - title = ""; - link = stripped_line.trim_prefix("@tutorial:").strip_edges(); - - } else { - /* Syntax: - * @tutorial ( The Title Here ) : https://the.url/ - * ^ open ^ close ^ colon ^ url - */ - int open_bracket_pos = begin_scan, close_bracket_pos = 0; - while (open_bracket_pos < stripped_line.length() && (stripped_line[open_bracket_pos] == ' ' || stripped_line[open_bracket_pos] == '\t')) { - open_bracket_pos++; - } - if (open_bracket_pos == stripped_line.length() || stripped_line[open_bracket_pos++] != '(') { - continue; // invalid syntax. - } - close_bracket_pos = open_bracket_pos; - while (close_bracket_pos < stripped_line.length() && stripped_line[close_bracket_pos] != ')') { - close_bracket_pos++; - } - if (close_bracket_pos == stripped_line.length()) { - continue; // invalid syntax. - } + String title, link; // For tutorials. - int colon_pos = close_bracket_pos + 1; - while (colon_pos < stripped_line.length() && (stripped_line[colon_pos] == ' ' || stripped_line[colon_pos] == '\t')) { - colon_pos++; + if (state == DOC_LINE_NORMAL) { + // Set the read mode. + String stripped_line = doc_line.strip_edges(); + if (stripped_line.is_empty()) { + if (mode == BRIEF && !p_brief.is_empty()) { + mode = DESC; } - if (colon_pos == stripped_line.length() || stripped_line[colon_pos++] != ':') { - continue; // invalid syntax. + continue; + } else if (stripped_line.begins_with("@tutorial")) { + int begin_scan = String("@tutorial").length(); + if (begin_scan >= stripped_line.length()) { + continue; // Invalid syntax. } - title = stripped_line.substr(open_bracket_pos, close_bracket_pos - open_bracket_pos).strip_edges(); - link = stripped_line.substr(colon_pos).strip_edges(); - } - - mode = TUTORIALS; - in_codeblock = false; - } else if (stripped_line.is_empty()) { - continue; - } else { - // Tutorial docs are single line, we need a @tag after it. - if (mode == TUTORIALS) { - mode = DONE; - } + if (stripped_line[begin_scan] == ':') { // No title. + // Syntax: ## @tutorial: https://godotengine.org/ // The title argument is optional. + title = ""; + link = stripped_line.trim_prefix("@tutorial:").strip_edges(); + } else { + /* Syntax: + * @tutorial ( The Title Here ) : https://the.url/ + * ^ open ^ close ^ colon ^ url + */ + int open_bracket_pos = begin_scan, close_bracket_pos = 0; + while (open_bracket_pos < stripped_line.length() && (stripped_line[open_bracket_pos] == ' ' || stripped_line[open_bracket_pos] == '\t')) { + open_bracket_pos++; + } + if (open_bracket_pos == stripped_line.length() || stripped_line[open_bracket_pos++] != '(') { + continue; // Invalid syntax. + } + close_bracket_pos = open_bracket_pos; + while (close_bracket_pos < stripped_line.length() && stripped_line[close_bracket_pos] != ')') { + close_bracket_pos++; + } + if (close_bracket_pos == stripped_line.length()) { + continue; // Invalid syntax. + } - in_codeblock = _in_codeblock(doc_line, in_codeblock, &codeblock_begins); - } + int colon_pos = close_bracket_pos + 1; + while (colon_pos < stripped_line.length() && (stripped_line[colon_pos] == ' ' || stripped_line[colon_pos] == '\t')) { + colon_pos++; + } + if (colon_pos == stripped_line.length() || stripped_line[colon_pos++] != ':') { + continue; // Invalid syntax. + } - if (in_codeblock) { - int i = 0; - for (; i < codeblock_begins; i++) { - if (doc_line[i] != ' ') { - break; + title = stripped_line.substr(open_bracket_pos, close_bracket_pos - open_bracket_pos).strip_edges(); + link = stripped_line.substr(colon_pos).strip_edges(); } + + mode = TUTORIALS; + } else if (mode == TUTORIALS) { // Tutorial docs are single line, we need a @tag after it. + mode = DONE; } - doc_line = doc_line.substr(i); - } else { - doc_line = stripped_line; } - String line_join = (in_codeblock) ? "\n" : " "; switch (mode) { case BRIEF: - p_brief = (p_brief.length() == 0) ? doc_line : p_brief + line_join + doc_line; + p_brief += _process_doc_line(doc_line, p_brief, space_prefix, state); break; case DESC: - p_desc = (p_desc.length() == 0) ? doc_line : p_desc + line_join + doc_line; + p_desc += _process_doc_line(doc_line, p_desc, space_prefix, state); break; case TUTORIALS: p_tutorials.append(Pair<String, String>(title, link)); @@ -3507,6 +3576,7 @@ void GDScriptParser::get_class_doc_comment(int p_line, String &p_brief, String & break; } } + if (current_class->members.size() > 0) { const ClassNode::Member &m = current_class->members[0]; int first_member_line = m.get_line(); diff --git a/modules/glslang/glslang_resource_limits.h b/modules/glslang/glslang_resource_limits.h index 94ac607576..8340e63096 100644 --- a/modules/glslang/glslang_resource_limits.h +++ b/modules/glslang/glslang_resource_limits.h @@ -141,15 +141,15 @@ const TBuiltInResource DefaultTBuiltInResource = { /* .maxDualSourceDrawBuffersEXT = */ 1, /* .limits = */ { - /* .nonInductiveForLoops = */ true, - /* .whileLoops = */ true, - /* .doWhileLoops = */ true, - /* .generalUniformIndexing = */ true, - /* .generalAttributeMatrixVectorIndexing = */ true, - /* .generalVaryingIndexing = */ true, - /* .generalSamplerIndexing = */ true, - /* .generalVariableIndexing = */ true, - /* .generalConstantMatrixVectorIndexing = */ true, + /* .nonInductiveForLoops = */ 1, + /* .whileLoops = */ 1, + /* .doWhileLoops = */ 1, + /* .generalUniformIndexing = */ 1, + /* .generalAttributeMatrixVectorIndexing = */ 1, + /* .generalVaryingIndexing = */ 1, + /* .generalSamplerIndexing = */ 1, + /* .generalVariableIndexing = */ 1, + /* .generalConstantMatrixVectorIndexing = */ 1, } }; diff --git a/modules/gltf/doc_classes/GLTFPhysicsBody.xml b/modules/gltf/doc_classes/GLTFPhysicsBody.xml index 054bd2fc85..5d21deff05 100644 --- a/modules/gltf/doc_classes/GLTFPhysicsBody.xml +++ b/modules/gltf/doc_classes/GLTFPhysicsBody.xml @@ -44,9 +44,9 @@ <member name="body_type" type="String" setter="set_body_type" getter="get_body_type" default=""static""> The type of the body. Valid values are "static", "kinematic", "character", "rigid", "vehicle", and "trigger". </member> - <member name="inertia" type="Vector3" setter="set_inertia" getter="get_inertia" default="Vector3(0, 0, 0)"> - The principle axes of the inertia tensor of the physics body, in kilogram meter squared (kg⋅m²). This is only used when the body type is "rigid" or "vehicle". - This is written to and read from the GLTF file as a 3x3 matrix, but is exposed as a Vector3 since Godot only supports principal axis inertia values. When converted to a Godot [RigidBody3D] node, if this value is zero, then the inertia will be calculated automatically. + <member name="inertia_tensor" type="Basis" setter="set_inertia_tensor" getter="get_inertia_tensor" default="Basis(0, 0, 0, 0, 0, 0, 0, 0, 0)"> + The inertia tensor of the physics body, in kilogram meter squared (kg⋅m²). This is only used when the body type is "rigid" or "vehicle". + When converted to a Godot [RigidBody3D] node, if this value is zero, then the inertia will be calculated automatically. </member> <member name="linear_velocity" type="Vector3" setter="set_linear_velocity" getter="get_linear_velocity" default="Vector3(0, 0, 0)"> The linear velocity of the physics body, in meters per second. This is only used when the body type is "rigid" or "vehicle". diff --git a/modules/gltf/doc_classes/GLTFSkeleton.xml b/modules/gltf/doc_classes/GLTFSkeleton.xml index eb06249e45..8073db3ce9 100644 --- a/modules/gltf/doc_classes/GLTFSkeleton.xml +++ b/modules/gltf/doc_classes/GLTFSkeleton.xml @@ -21,6 +21,7 @@ <method name="get_godot_bone_node"> <return type="Dictionary" /> <description> + Returns a [Dictionary] that maps skeleton bone indices to the indices of GLTF nodes. This property is unused during import, and only set during export. In a GLTF file, a bone is a node, so Godot converts skeleton bones to GLTF nodes. </description> </method> <method name="get_godot_skeleton"> @@ -37,6 +38,7 @@ <return type="void" /> <param index="0" name="godot_bone_node" type="Dictionary" /> <description> + Sets a [Dictionary] that maps skeleton bone indices to the indices of GLTF nodes. This property is unused during import, and only set during export. In a GLTF file, a bone is a node, so Godot converts skeleton bones to GLTF nodes. </description> </method> <method name="set_unique_names"> diff --git a/modules/gltf/extensions/physics/gltf_physics_body.cpp b/modules/gltf/extensions/physics/gltf_physics_body.cpp index a187fc53a1..3b0fad064a 100644 --- a/modules/gltf/extensions/physics/gltf_physics_body.cpp +++ b/modules/gltf/extensions/physics/gltf_physics_body.cpp @@ -48,14 +48,14 @@ void GLTFPhysicsBody::_bind_methods() { ClassDB::bind_method(D_METHOD("set_linear_velocity", "linear_velocity"), &GLTFPhysicsBody::set_linear_velocity); ClassDB::bind_method(D_METHOD("get_angular_velocity"), &GLTFPhysicsBody::get_angular_velocity); ClassDB::bind_method(D_METHOD("set_angular_velocity", "angular_velocity"), &GLTFPhysicsBody::set_angular_velocity); - ClassDB::bind_method(D_METHOD("get_inertia"), &GLTFPhysicsBody::get_inertia); - ClassDB::bind_method(D_METHOD("set_inertia", "inertia"), &GLTFPhysicsBody::set_inertia); + ClassDB::bind_method(D_METHOD("get_inertia_tensor"), &GLTFPhysicsBody::get_inertia_tensor); + ClassDB::bind_method(D_METHOD("set_inertia_tensor", "inertia_tensor"), &GLTFPhysicsBody::set_inertia_tensor); ADD_PROPERTY(PropertyInfo(Variant::STRING, "body_type"), "set_body_type", "get_body_type"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mass"), "set_mass", "get_mass"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "linear_velocity"), "set_linear_velocity", "get_linear_velocity"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "angular_velocity"), "set_angular_velocity", "get_angular_velocity"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "inertia"), "set_inertia", "get_inertia"); + ADD_PROPERTY(PropertyInfo(Variant::BASIS, "inertia_tensor"), "set_inertia_tensor", "get_inertia_tensor"); } String GLTFPhysicsBody::get_body_type() const { @@ -90,12 +90,12 @@ void GLTFPhysicsBody::set_angular_velocity(Vector3 p_angular_velocity) { angular_velocity = p_angular_velocity; } -Vector3 GLTFPhysicsBody::get_inertia() const { - return inertia; +Basis GLTFPhysicsBody::get_inertia_tensor() const { + return inertia_tensor; } -void GLTFPhysicsBody::set_inertia(Vector3 p_inertia) { - inertia = p_inertia; +void GLTFPhysicsBody::set_inertia_tensor(Basis p_inertia_tensor) { + inertia_tensor = p_inertia_tensor; } Ref<GLTFPhysicsBody> GLTFPhysicsBody::from_node(const CollisionObject3D *p_body_node) { @@ -111,7 +111,8 @@ Ref<GLTFPhysicsBody> GLTFPhysicsBody::from_node(const CollisionObject3D *p_body_ physics_body->mass = body->get_mass(); physics_body->linear_velocity = body->get_linear_velocity(); physics_body->angular_velocity = body->get_angular_velocity(); - physics_body->inertia = body->get_inertia(); + Vector3 inertia_diagonal = body->get_inertia(); + physics_body->inertia_tensor = Basis(inertia_diagonal.x, 0, 0, 0, inertia_diagonal.y, 0, 0, 0, inertia_diagonal.z); if (body->get_center_of_mass() != Vector3()) { WARN_PRINT("GLTFPhysicsBody: This rigid body has a center of mass offset from the origin, which will be ignored when exporting to GLTF."); } @@ -142,7 +143,7 @@ CollisionObject3D *GLTFPhysicsBody::to_node() const { body->set_mass(mass); body->set_linear_velocity(linear_velocity); body->set_angular_velocity(angular_velocity); - body->set_inertia(inertia); + body->set_inertia(inertia_tensor.get_main_diagonal()); body->set_center_of_mass_mode(RigidBody3D::CENTER_OF_MASS_MODE_CUSTOM); return body; } @@ -151,7 +152,7 @@ CollisionObject3D *GLTFPhysicsBody::to_node() const { body->set_mass(mass); body->set_linear_velocity(linear_velocity); body->set_angular_velocity(angular_velocity); - body->set_inertia(inertia); + body->set_inertia(inertia_tensor.get_main_diagonal()); body->set_center_of_mass_mode(RigidBody3D::CENTER_OF_MASS_MODE_CUSTOM); return body; } @@ -196,7 +197,7 @@ Ref<GLTFPhysicsBody> GLTFPhysicsBody::from_dictionary(const Dictionary p_diction const Array &arr = p_dictionary["inertiaTensor"]; if (arr.size() == 9) { // Only use the diagonal elements of the inertia tensor matrix (principal axes). - physics_body->set_inertia(Vector3(arr[0], arr[4], arr[8])); + physics_body->set_inertia_tensor(Basis(arr[0], arr[1], arr[2], arr[3], arr[4], arr[5], arr[6], arr[7], arr[8])); } else { ERR_PRINT("Error parsing GLTF physics body: The inertia tensor must be a 3x3 matrix (9 number array)."); } @@ -229,13 +230,19 @@ Dictionary GLTFPhysicsBody::to_dictionary() const { velocity_array[2] = angular_velocity.z; d["angularVelocity"] = velocity_array; } - if (inertia != Vector3()) { + if (inertia_tensor != Basis(0, 0, 0, 0, 0, 0, 0, 0, 0)) { Array inertia_array; inertia_array.resize(9); inertia_array.fill(0.0); - inertia_array[0] = inertia.x; - inertia_array[4] = inertia.y; - inertia_array[8] = inertia.z; + inertia_array[0] = inertia_tensor[0][0]; + inertia_array[1] = inertia_tensor[0][1]; + inertia_array[2] = inertia_tensor[0][2]; + inertia_array[3] = inertia_tensor[1][0]; + inertia_array[4] = inertia_tensor[1][1]; + inertia_array[5] = inertia_tensor[1][2]; + inertia_array[6] = inertia_tensor[2][0]; + inertia_array[7] = inertia_tensor[2][1]; + inertia_array[8] = inertia_tensor[2][2]; d["inertiaTensor"] = inertia_array; } return d; diff --git a/modules/gltf/extensions/physics/gltf_physics_body.h b/modules/gltf/extensions/physics/gltf_physics_body.h index 1562c65b2b..5fedb4f111 100644 --- a/modules/gltf/extensions/physics/gltf_physics_body.h +++ b/modules/gltf/extensions/physics/gltf_physics_body.h @@ -47,7 +47,7 @@ private: real_t mass = 1.0; Vector3 linear_velocity = Vector3(); Vector3 angular_velocity = Vector3(); - Vector3 inertia = Vector3(); + Basis inertia_tensor = Basis(0, 0, 0, 0, 0, 0, 0, 0, 0); public: String get_body_type() const; @@ -62,8 +62,8 @@ public: Vector3 get_angular_velocity() const; void set_angular_velocity(Vector3 p_angular_velocity); - Vector3 get_inertia() const; - void set_inertia(Vector3 p_inertia); + Basis get_inertia_tensor() const; + void set_inertia_tensor(Basis p_inertia_tensor); static Ref<GLTFPhysicsBody> from_node(const CollisionObject3D *p_body_node); CollisionObject3D *to_node() const; diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 20b36fc377..53f696ba1b 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -1576,7 +1576,10 @@ CSharpInstance *CSharpInstance::create_for_managed_type(Object *p_owner, CSharpS instance->_reference_owner_unsafe(); } - p_script->instances.insert(p_owner); + { + MutexLock lock(CSharpLanguage::get_singleton()->get_script_instances_mutex()); + p_script->instances.insert(p_owner); + } return instance; } diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs index 13eb3bf1ad..27963be00f 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs @@ -279,12 +279,19 @@ namespace GodotTools.Build [DisallowNull] string configuration, [DisallowNull] string platform, [DisallowNull] string runtimeIdentifier, - [DisallowNull] string publishOutputDir + [DisallowNull] string publishOutputDir, + bool includeDebugSymbols = true ) { var buildInfo = new BuildInfo(GodotSharpDirs.ProjectSlnPath, GodotSharpDirs.ProjectCsProjPath, configuration, runtimeIdentifier, publishOutputDir, restore: true, rebuild: false, onlyClean: false); + if (!includeDebugSymbols) + { + buildInfo.CustomProperties.Add("DebugType=None"); + buildInfo.CustomProperties.Add("DebugSymbols=false"); + } + buildInfo.CustomProperties.Add($"GodotTargetPlatform={platform}"); if (Internal.GodotIsRealTDouble()) @@ -308,9 +315,10 @@ namespace GodotTools.Build [DisallowNull] string configuration, [DisallowNull] string platform, [DisallowNull] string runtimeIdentifier, - string publishOutputDir + string publishOutputDir, + bool includeDebugSymbols = true ) => PublishProjectBlocking(CreatePublishBuildInfo(configuration, - platform, runtimeIdentifier, publishOutputDir)); + platform, runtimeIdentifier, publishOutputDir, includeDebugSymbols)); public static bool EditorBuildCallback() { diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs index d550c36b82..d7d484d166 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs @@ -41,6 +41,12 @@ namespace GodotTools.Build startInfo.EnvironmentVariables["DOTNET_CLI_UI_LANGUAGE"] = ((string)editorSettings.GetSetting("interface/editor/editor_language")).Replace('_', '-'); + if (OperatingSystem.IsWindows()) + { + startInfo.StandardOutputEncoding = Encoding.UTF8; + startInfo.StandardErrorEncoding = Encoding.UTF8; + } + // Needed when running from Developer Command Prompt for VS RemovePlatformVariable(startInfo.EnvironmentVariables); @@ -105,6 +111,12 @@ namespace GodotTools.Build startInfo.EnvironmentVariables["DOTNET_CLI_UI_LANGUAGE"] = ((string)editorSettings.GetSetting("interface/editor/editor_language")).Replace('_', '-'); + if (OperatingSystem.IsWindows()) + { + startInfo.StandardOutputEncoding = Encoding.UTF8; + startInfo.StandardErrorEncoding = Encoding.UTF8; + } + // Needed when running from Developer Command Prompt for VS RemovePlatformVariable(startInfo.EnvironmentVariables); diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/DotNetFinder.cs b/modules/mono/editor/GodotTools/GodotTools/Build/DotNetFinder.cs index b437c7e742..cfe79cf3e1 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Build/DotNetFinder.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Build/DotNetFinder.cs @@ -4,6 +4,7 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Runtime.InteropServices; +using System.Text; using JetBrains.Annotations; using OS = GodotTools.Utils.OS; @@ -58,6 +59,11 @@ namespace GodotTools.Build RedirectStandardOutput = true }; + if (OperatingSystem.IsWindows()) + { + process.StartInfo.StandardOutputEncoding = Encoding.UTF8; + } + process.StartInfo.EnvironmentVariables["DOTNET_CLI_UI_LANGUAGE"] = "en-US"; var lines = new List<string>(); diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs index 6837b617e0..27c2676dd0 100644 --- a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs +++ b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs @@ -1,7 +1,6 @@ using Godot; using System; using System.Collections.Generic; -using System.Diagnostics; using System.IO; using System.Linq; using GodotTools.Build; @@ -35,6 +34,17 @@ namespace GodotTools.Export } }, { "default_value", false } + }, + new Godot.Collections.Dictionary() + { + { + "option", new Godot.Collections.Dictionary() + { + { "name", "dotnet/include_debug_symbols" }, + { "type", (int)Variant.Type.Bool } + } + }, + { "default_value", true } } }; } @@ -110,11 +120,10 @@ namespace GodotTools.Export throw new NotImplementedException("Target platform not yet implemented."); } - string outputDir = new FileInfo(path).Directory?.FullName ?? - throw new FileNotFoundException("Output base directory not found."); - string buildConfig = isDebug ? "ExportDebug" : "ExportRelease"; + bool includeDebugSymbols = (bool)GetOption("dotnet/include_debug_symbols"); + var archs = new List<string>(); if (features.Contains("x86_64")) { @@ -151,7 +160,7 @@ namespace GodotTools.Export // Create temporary publish output directory string publishOutputTempDir = Path.Combine(Path.GetTempPath(), "godot-publish-dotnet", - $"{Process.GetCurrentProcess().Id}-{buildConfig}-{runtimeIdentifier}"); + $"{System.Environment.ProcessId}-{buildConfig}-{runtimeIdentifier}"); _tempFolders.Add(publishOutputTempDir); @@ -161,7 +170,7 @@ namespace GodotTools.Export // Execute dotnet publish if (!BuildManager.PublishProjectBlocking(buildConfig, platform, - runtimeIdentifier, publishOutputTempDir)) + runtimeIdentifier, publishOutputTempDir, includeDebugSymbols)) { throw new InvalidOperationException("Failed to build project."); } @@ -215,7 +224,7 @@ namespace GodotTools.Export { base._ExportEnd(); - string aotTempDir = Path.Combine(Path.GetTempPath(), $"godot-aot-{Process.GetCurrentProcess().Id}"); + string aotTempDir = Path.Combine(Path.GetTempPath(), $"godot-aot-{System.Environment.ProcessId}"); if (Directory.Exists(aotTempDir)) Directory.Delete(aotTempDir, recursive: true); diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index 6b52c8eaaf..e4999a90c8 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -1375,6 +1375,10 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str output.append("/// </summary>\n"); } + + if (class_doc->is_deprecated) { + output.append("[Obsolete(\"This class is deprecated.\")]\n"); + } } // We generate a `GodotClassName` attribute if the engine class name is not the same as the @@ -1426,6 +1430,10 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str output.append(INDENT1 "/// </summary>"); } + + if (iconstant.const_doc->is_deprecated) { + output.append(MEMBER_BEGIN "[Obsolete(\"This constant is deprecated.\")]"); + } } output.append(MEMBER_BEGIN "public const long "); @@ -1470,6 +1478,10 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str output.append(INDENT2 "/// </summary>\n"); } + + if (iconstant.const_doc->is_deprecated) { + output.append(INDENT2 "[Obsolete(\"This enum member is deprecated.\")]\n"); + } } output.append(INDENT2); @@ -1867,6 +1879,10 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte p_output.append(INDENT1 "/// </summary>"); } + + if (p_iprop.prop_doc->is_deprecated) { + p_output.append(MEMBER_BEGIN "[Obsolete(\"This property is deprecated.\")]"); + } } p_output.append(MEMBER_BEGIN "public "); @@ -2102,6 +2118,10 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf p_output.append(INDENT1 "/// </summary>"); } + + if (p_imethod.method_doc->is_deprecated) { + p_output.append(MEMBER_BEGIN "[Obsolete(\"This method is deprecated.\")]"); + } } if (default_args_doc.get_string_length()) { @@ -2314,6 +2334,10 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf p_output.append(INDENT1 "/// </summary>"); } + + if (p_isignal.method_doc->is_deprecated) { + p_output.append(MEMBER_BEGIN "[Obsolete(\"This signal is deprecated.\")]"); + } } if (p_isignal.is_deprecated) { @@ -2865,7 +2889,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() { itype.cs_out = "%5return (%2)%0(%1);"; - itype.c_arg_in = "(void*)%s"; + itype.c_arg_in = "&%s"; itype.c_type = "IntPtr"; itype.c_type_in = itype.c_type; itype.c_type_out = "GodotObject"; diff --git a/modules/mono/icons/CSharpScript.svg b/modules/mono/icons/CSharpScript.svg index 0b2cc840f8..1e1ec96857 100644 --- a/modules/mono/icons/CSharpScript.svg +++ b/modules/mono/icons/CSharpScript.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 1046.4c-1.6569 0-3 1.3431-3 3s1.3431 3 3 3h1v-2h-1c-.55228 0-1-.4478-1-1 0-.5523.44772-1 1-1h1v-2zm1-9-.56445 2.2578c-.23643.076-.46689.1692-.68945.2793l-1.9883-1.1933-1.4141 1.414 1.1953 1.9942c-.11191.2211-.20723.4502-.28516.6855l-2.2539.5625v2h5.2715c-.17677-.3037-.27041-.6486-.27148-1 .0000096-1.1046.89543-2 2-2s2 .8954 2 2c-.0004817.3512-.093442.6961-.26953 1h5.2695v-2l-2.2578-.5645c-.07594-.2357-.1693-.4655-.2793-.6875l1.1934-1.9902-1.4141-1.414-1.9941 1.1953c-.22113-.1119-.45028-.2073-.68555-.2852l-.5625-2.2539zm4 9c-.71466-.0001-1.3751.3811-1.7324 1-.35727.6188-.35727 1.3812 0 2 .35733.6189 1.0178 1.0001 1.7324 1h-2v2h2c.71466.0001 1.3751-.3811 1.7324-1 .35727-.6188.35727-1.3812 0-2-.35733-.6189-1.0178-1.0001-1.7324-1h2v-2z" fill="#e0e0e0" transform="translate(0 -1036.4)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M6 10a3 3 0 1 0 0 6h1v-2H6a1 1 0 0 1 0-2h1v-2zm1-9-.564 2.258a4.91 4.91 0 0 0-.69.28L3.758 2.343 2.344 3.758l1.195 1.994-.285.685L1 7v2h5.27a2 2 0 1 1 3.46 0H15V7l-2.258-.565a5.007 5.007 0 0 0-.28-.687l1.194-1.99-1.414-1.414-1.994 1.195a4.998 4.998 0 0 0-.686-.285L9 1zm4 9a2 2 0 1 0 0 4H9v2h2a2 2 0 1 0 0-4h2v-2z" fill="#e0e0e0"/></svg> diff --git a/modules/text_server_adv/thorvg_svg_in_ot.cpp b/modules/text_server_adv/thorvg_svg_in_ot.cpp index 5eb5e6b51e..3e6a81c84e 100644 --- a/modules/text_server_adv/thorvg_svg_in_ot.cpp +++ b/modules/text_server_adv/thorvg_svg_in_ot.cpp @@ -127,7 +127,7 @@ FT_Error tvg_svg_in_ot_preset_slot(FT_GlyphSlot p_slot, FT_Bool p_cache, FT_Poin xml_body += vformat("</%s>", parser->get_node_name()); } } - String temp_xml_str = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 0 0\">" + xml_body; + String temp_xml_str = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1 1\">" + xml_body; CharString temp_xml = temp_xml_str.utf8(); std::unique_ptr<tvg::Picture> picture = tvg::Picture::gen(); diff --git a/modules/text_server_fb/thorvg_svg_in_ot.cpp b/modules/text_server_fb/thorvg_svg_in_ot.cpp index 3d809002a1..4c781a5c85 100644 --- a/modules/text_server_fb/thorvg_svg_in_ot.cpp +++ b/modules/text_server_fb/thorvg_svg_in_ot.cpp @@ -127,7 +127,7 @@ FT_Error tvg_svg_in_ot_preset_slot(FT_GlyphSlot p_slot, FT_Bool p_cache, FT_Poin xml_body += vformat("</%s>", parser->get_node_name()); } } - String temp_xml_str = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 0 0\">" + xml_body; + String temp_xml_str = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1 1\">" + xml_body; CharString temp_xml = temp_xml_str.utf8(); std::unique_ptr<tvg::Picture> picture = tvg::Picture::gen(); |