summaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/gdscript/gdscript_editor.cpp15
-rw-r--r--modules/gdscript/gdscript_parser.cpp288
-rw-r--r--modules/glslang/glslang_resource_limits.h18
-rw-r--r--modules/gltf/doc_classes/GLTFPhysicsBody.xml6
-rw-r--r--modules/gltf/doc_classes/GLTFSkeleton.xml2
-rw-r--r--modules/gltf/extensions/physics/gltf_physics_body.cpp37
-rw-r--r--modules/gltf/extensions/physics/gltf_physics_body.h6
-rw-r--r--modules/mono/csharp_script.cpp5
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/BuildManager.cs14
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs12
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/DotNetFinder.cs6
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs23
-rw-r--r--modules/mono/editor/bindings_generator.cpp26
-rw-r--r--modules/mono/icons/CSharpScript.svg2
-rw-r--r--modules/text_server_adv/thorvg_svg_in_ot.cpp2
-rw-r--r--modules/text_server_fb/thorvg_svg_in_ot.cpp2
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="&quot;static&quot;">
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();