diff options
Diffstat (limited to 'modules')
| -rw-r--r-- | modules/csg/csg_gizmos.cpp | 10 | ||||
| -rw-r--r-- | modules/fbx/data/fbx_mesh_data.cpp | 4 | ||||
| -rw-r--r-- | modules/gdscript/gdscript_analyzer.cpp | 43 | ||||
| -rw-r--r-- | modules/gdscript/gdscript_compiler.cpp | 86 | ||||
| -rw-r--r-- | modules/gdscript/gdscript_editor.cpp | 50 | ||||
| -rw-r--r-- | modules/gdscript/gdscript_parser.cpp | 10 | ||||
| -rw-r--r-- | modules/gdscript/gdscript_parser.h | 2 | ||||
| -rw-r--r-- | modules/gdscript/gdscript_vm.cpp | 7 | ||||
| -rw-r--r-- | modules/gltf/gltf_document.cpp | 51 | ||||
| -rw-r--r-- | modules/gltf/gltf_document.h | 1 | ||||
| -rw-r--r-- | modules/lightmapper_rd/lightmapper_rd.cpp | 6 | ||||
| -rw-r--r-- | modules/mbedtls/SCsub | 6 | ||||
| -rw-r--r-- | modules/text_server_adv/text_server_adv.cpp | 58 | ||||
| -rw-r--r-- | modules/text_server_adv/text_server_adv.h | 5 | ||||
| -rw-r--r-- | modules/text_server_fb/text_server_fb.cpp | 24 | ||||
| -rw-r--r-- | modules/text_server_fb/text_server_fb.h | 4 | ||||
| -rw-r--r-- | modules/websocket/websocket_server.cpp | 2 |
17 files changed, 273 insertions, 96 deletions
diff --git a/modules/csg/csg_gizmos.cpp b/modules/csg/csg_gizmos.cpp index 71891c8704..f6e09067d2 100644 --- a/modules/csg/csg_gizmos.cpp +++ b/modules/csg/csg_gizmos.cpp @@ -343,6 +343,16 @@ void CSGShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { p_gizmo->add_lines(lines, material); p_gizmo->add_collision_segments(lines); + Array csg_meshes = cs->get_meshes(); + if (csg_meshes.size() != 2) { + return; + } + + Ref<Mesh> csg_mesh = csg_meshes[1]; + if (csg_mesh.is_valid()) { + p_gizmo->add_collision_triangles(csg_mesh->generate_triangle_mesh()); + } + if (p_gizmo->is_selected()) { // Draw a translucent representation of the CSG node Ref<ArrayMesh> mesh = memnew(ArrayMesh); diff --git a/modules/fbx/data/fbx_mesh_data.cpp b/modules/fbx/data/fbx_mesh_data.cpp index 2b29f4d97e..643a74f83e 100644 --- a/modules/fbx/data/fbx_mesh_data.cpp +++ b/modules/fbx/data/fbx_mesh_data.cpp @@ -1092,7 +1092,7 @@ HashMap<int, R> FBXMeshData::extract_per_vertex_data( const int vertex_index = get_vertex_from_polygon_vertex(p_mesh_indices, polygon_vertex_index); ERR_FAIL_COND_V_MSG(vertex_index < 0, (HashMap<int, R>()), "FBX file corrupted: #ERR05"); ERR_FAIL_COND_V_MSG(vertex_index >= p_vertex_count, (HashMap<int, R>()), "FBX file corrupted: #ERR06"); - const int index_to_direct = p_mapping_data.index[polygon_vertex_index]; + const int index_to_direct = get_vertex_from_polygon_vertex(p_mapping_data.index, polygon_vertex_index); T value = p_mapping_data.data[index_to_direct]; aggregate_vertex_data[vertex_index].push_back({ polygon_id, value }); } @@ -1297,7 +1297,7 @@ HashMap<int, T> FBXMeshData::extract_per_polygon( } else { ERR_FAIL_INDEX_V_MSG(polygon_index, (int)p_fbx_data.index.size(), (HashMap<int, T>()), "FBX file is corrupted: #ERR62"); - const int index_to_direct = p_fbx_data.index[polygon_index]; + const int index_to_direct = get_vertex_from_polygon_vertex(p_fbx_data.index, polygon_index); T value = p_fbx_data.data[index_to_direct]; aggregate_polygon_data[polygon_index].push_back(value); } diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 0bf4f5e1f1..3a79190149 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -1868,13 +1868,14 @@ void GDScriptAnalyzer::reduce_assignment(GDScriptParser::AssignmentNode *p_assig push_error("Cannot assign a new value to a constant.", p_assignment->assignee); } - if (!assignee_type.is_variant() && assigned_value_type.is_hard_type()) { - bool compatible = true; - GDScriptParser::DataType op_type = assigned_value_type; - if (p_assignment->operation != GDScriptParser::AssignmentNode::OP_NONE) { - op_type = get_operation_type(p_assignment->variant_op, assignee_type, assigned_value_type, compatible, p_assignment->assigned_value); - } + bool compatible = true; + GDScriptParser::DataType op_type = assigned_value_type; + if (p_assignment->operation != GDScriptParser::AssignmentNode::OP_NONE) { + op_type = get_operation_type(p_assignment->variant_op, assignee_type, assigned_value_type, compatible, p_assignment->assigned_value); + } + p_assignment->set_datatype(op_type); + if (!assignee_type.is_variant() && assigned_value_type.is_hard_type()) { if (compatible) { compatible = is_type_compatible(assignee_type, op_type, true); if (!compatible) { @@ -1899,7 +1900,7 @@ void GDScriptAnalyzer::reduce_assignment(GDScriptParser::AssignmentNode *p_assig if (assignee_type.has_no_type() || assigned_value_type.is_variant()) { mark_node_unsafe(p_assignment); - if (assignee_type.is_hard_type()) { + if (assignee_type.is_hard_type() && !assignee_type.is_variant()) { p_assignment->use_conversion_assign = true; } } @@ -3787,6 +3788,7 @@ GDScriptParser::DataType GDScriptAnalyzer::get_operation_type(Variant::Operator // Unary version. GDScriptParser::DataType nil_type; nil_type.builtin_type = Variant::NIL; + nil_type.type_source = GDScriptParser::DataType::ANNOTATED_INFERRED; return get_operation_type(p_operation, p_a, nil_type, r_valid, p_source); } @@ -3796,20 +3798,31 @@ GDScriptParser::DataType GDScriptAnalyzer::get_operation_type(Variant::Operator Variant::Type a_type = p_a.builtin_type; Variant::Type b_type = p_b.builtin_type; - Variant::ValidatedOperatorEvaluator op_eval = Variant::get_validated_operator_evaluator(p_operation, a_type, b_type); - if (op_eval == nullptr) { + bool hard_operation = p_a.is_hard_type() && p_b.is_hard_type(); + bool validated = op_eval != nullptr; + + if (hard_operation && !validated) { r_valid = false; return result; + } else if (hard_operation && validated) { + r_valid = true; + result.type_source = GDScriptParser::DataType::ANNOTATED_INFERRED; + result.kind = GDScriptParser::DataType::BUILTIN; + result.builtin_type = Variant::get_operator_return_type(p_operation, a_type, b_type); + } else if (!hard_operation && !validated) { + r_valid = true; + result.type_source = GDScriptParser::DataType::UNDETECTED; + result.kind = GDScriptParser::DataType::VARIANT; + result.builtin_type = Variant::NIL; + } else if (!hard_operation && validated) { + r_valid = true; + result.type_source = GDScriptParser::DataType::INFERRED; + result.kind = GDScriptParser::DataType::BUILTIN; + result.builtin_type = Variant::get_operator_return_type(p_operation, a_type, b_type); } - r_valid = true; - result.type_source = GDScriptParser::DataType::ANNOTATED_INFERRED; - - result.kind = GDScriptParser::DataType::BUILTIN; - result.builtin_type = Variant::get_operator_return_type(p_operation, a_type, b_type); - return result; } diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index af5ada513c..117ca68c18 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -882,7 +882,13 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code #endif /* Find chain of sets */ - StringName assign_property; + StringName assign_class_member_property; + + GDScriptCodeGenerator::Address target_member_property; + bool is_member_property = false; + bool member_property_has_setter = false; + bool member_property_is_in_setter = false; + StringName member_property_setter_function; List<const GDScriptParser::SubscriptNode *> chain; @@ -892,11 +898,20 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code while (true) { chain.push_back(n); if (n->base->type != GDScriptParser::Node::SUBSCRIPT) { - // Check for a built-in property. + // Check for a property. if (n->base->type == GDScriptParser::Node::IDENTIFIER) { GDScriptParser::IdentifierNode *identifier = static_cast<GDScriptParser::IdentifierNode *>(n->base); - if (_is_class_member_property(codegen, identifier->name)) { - assign_property = identifier->name; + StringName var_name = identifier->name; + if (_is_class_member_property(codegen, var_name)) { + assign_class_member_property = var_name; + } else if (!codegen.locals.has(var_name) && codegen.script->member_indices.has(var_name)) { + is_member_property = true; + member_property_setter_function = codegen.script->member_indices[var_name].setter; + member_property_has_setter = member_property_setter_function != StringName(); + member_property_is_in_setter = member_property_has_setter && member_property_setter_function == codegen.function_name; + target_member_property.mode = GDScriptCodeGenerator::Address::MEMBER; + target_member_property.address = codegen.script->member_indices[var_name].index; + target_member_property.type = codegen.script->member_indices[var_name].data_type; } } break; @@ -969,17 +984,19 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code // Perform operator if any. if (assignment->operation != GDScriptParser::AssignmentNode::OP_NONE) { + GDScriptCodeGenerator::Address op_result = codegen.add_temporary(_gdtype_from_datatype(assignment->get_datatype())); GDScriptCodeGenerator::Address value = codegen.add_temporary(_gdtype_from_datatype(subscript->get_datatype())); if (subscript->is_attribute) { gen->write_get_named(value, name, prev_base); } else { gen->write_get(value, key, prev_base); } - gen->write_binary_operator(value, assignment->variant_op, value, assigned); + gen->write_binary_operator(op_result, assignment->variant_op, value, assigned); + gen->pop_temporary(); if (assigned.mode == GDScriptCodeGenerator::Address::TEMPORARY) { gen->pop_temporary(); } - assigned = value; + assigned = op_result; } // Perform assignment. @@ -1013,10 +1030,20 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code assigned = info.base; } - // If this is a local member, also assign to it. + // If this is a class member property, also assign to it. // This allow things like: position.x += 2.0 - if (assign_property != StringName()) { - gen->write_set_member(assigned, assign_property); + if (assign_class_member_property != StringName()) { + gen->write_set_member(assigned, assign_class_member_property); + } + // Same as above but for members + if (is_member_property) { + if (member_property_has_setter && !member_property_is_in_setter) { + Vector<GDScriptCodeGenerator::Address> args; + args.push_back(assigned); + gen->write_call(GDScriptCodeGenerator::Address(), GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::SELF), member_property_setter_function, args); + } else { + gen->write_assign(target_member_property, assigned); + } } if (assigned.mode == GDScriptCodeGenerator::Address::TEMPORARY) { @@ -1035,8 +1062,8 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code StringName name = static_cast<GDScriptParser::IdentifierNode *>(assignment->assignee)->name; if (has_operation) { - GDScriptCodeGenerator::Address op_result = codegen.add_temporary(); - GDScriptCodeGenerator::Address member = codegen.add_temporary(); + GDScriptCodeGenerator::Address op_result = codegen.add_temporary(_gdtype_from_datatype(assignment->get_datatype())); + GDScriptCodeGenerator::Address member = codegen.add_temporary(_gdtype_from_datatype(assignment->assignee->get_datatype())); gen->write_get_member(member, name); gen->write_binary_operator(op_result, assignment->variant_op, member, assigned_value); gen->pop_temporary(); // Pop member temp. @@ -1053,29 +1080,26 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code } } else { // Regular assignment. - GDScriptCodeGenerator::Address target; - + ERR_FAIL_COND_V_MSG(assignment->assignee->type != GDScriptParser::Node::IDENTIFIER, GDScriptCodeGenerator::Address(), "Expected the assignee to be an identifier here."); + GDScriptCodeGenerator::Address member; + bool is_member = false; bool has_setter = false; bool is_in_setter = false; StringName setter_function; - if (assignment->assignee->type == GDScriptParser::Node::IDENTIFIER) { - StringName var_name = static_cast<const GDScriptParser::IdentifierNode *>(assignment->assignee)->name; - if (!codegen.locals.has(var_name) && codegen.script->member_indices.has(var_name)) { - setter_function = codegen.script->member_indices[var_name].setter; - if (setter_function != StringName()) { - has_setter = true; - is_in_setter = setter_function == codegen.function_name; - target.mode = GDScriptCodeGenerator::Address::MEMBER; - target.address = codegen.script->member_indices[var_name].index; - } - } + StringName var_name = static_cast<const GDScriptParser::IdentifierNode *>(assignment->assignee)->name; + if (!codegen.locals.has(var_name) && codegen.script->member_indices.has(var_name)) { + is_member = true; + setter_function = codegen.script->member_indices[var_name].setter; + has_setter = setter_function != StringName(); + is_in_setter = has_setter && setter_function == codegen.function_name; + member.mode = GDScriptCodeGenerator::Address::MEMBER; + member.address = codegen.script->member_indices[var_name].index; + member.type = codegen.script->member_indices[var_name].data_type; } - if (has_setter) { - if (!is_in_setter) { - // Store stack slot for the temp value. - target = codegen.add_temporary(_gdtype_from_datatype(assignment->assignee->get_datatype())); - } + GDScriptCodeGenerator::Address target; + if (is_member) { + target = member; // _parse_expression could call its getter, but we want to know the actual address } else { target = _parse_expression(codegen, r_error, assignment->assignee); if (r_error) { @@ -1092,7 +1116,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code bool has_operation = assignment->operation != GDScriptParser::AssignmentNode::OP_NONE; if (has_operation) { // Perform operation. - GDScriptCodeGenerator::Address op_result = codegen.add_temporary(); + GDScriptCodeGenerator::Address op_result = codegen.add_temporary(_gdtype_from_datatype(assignment->get_datatype())); GDScriptCodeGenerator::Address og_value = _parse_expression(codegen, r_error, assignment->assignee); gen->write_binary_operator(op_result, assignment->variant_op, og_value, assigned_value); to_assign = op_result; @@ -2069,7 +2093,7 @@ GDScriptFunction *GDScriptCompiler::_parse_function(Error &r_error, GDScript *p_ if (p_func) { // if no return statement -> return type is void not unresolved Variant if (p_func->body->has_return) { - gd_function->return_type = _gdtype_from_datatype(p_func->get_datatype()); + gd_function->return_type = _gdtype_from_datatype(p_func->get_datatype(), p_script); } else { gd_function->return_type = GDScriptDataType(); gd_function->return_type.has_type = true; diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index 9db76861ff..7c27a096e7 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -580,12 +580,50 @@ static String _make_arguments_hint(const GDScriptParser::FunctionNode *p_functio if (par->default_value) { String def_val = "<unknown>"; - if (par->default_value->type == GDScriptParser::Node::LITERAL) { - const GDScriptParser::LiteralNode *literal = static_cast<const GDScriptParser::LiteralNode *>(par->default_value); - def_val = literal->value.get_construct_string(); - } else if (par->default_value->type == GDScriptParser::Node::IDENTIFIER) { - const GDScriptParser::IdentifierNode *id = static_cast<const GDScriptParser::IdentifierNode *>(par->default_value); - def_val = id->name.operator String(); + switch (par->default_value->type) { + case GDScriptParser::Node::LITERAL: { + const GDScriptParser::LiteralNode *literal = static_cast<const GDScriptParser::LiteralNode *>(par->default_value); + def_val = literal->value.get_construct_string(); + } break; + case GDScriptParser::Node::IDENTIFIER: { + const GDScriptParser::IdentifierNode *id = static_cast<const GDScriptParser::IdentifierNode *>(par->default_value); + def_val = id->name.operator String(); + } break; + case GDScriptParser::Node::CALL: { + const GDScriptParser::CallNode *call = static_cast<const GDScriptParser::CallNode *>(par->default_value); + if (call->is_constant && call->reduced) { + def_val = call->function_name.operator String() + call->reduced_value.operator String(); + } + } break; + case GDScriptParser::Node::ARRAY: { + const GDScriptParser::ArrayNode *arr = static_cast<const GDScriptParser::ArrayNode *>(par->default_value); + if (arr->is_constant && arr->reduced) { + def_val = arr->reduced_value.operator String(); + } + } break; + case GDScriptParser::Node::DICTIONARY: { + const GDScriptParser::DictionaryNode *dict = static_cast<const GDScriptParser::DictionaryNode *>(par->default_value); + if (dict->is_constant && dict->reduced) { + def_val = dict->reduced_value.operator String(); + } + } break; + case GDScriptParser::Node::SUBSCRIPT: { + const GDScriptParser::SubscriptNode *sub = static_cast<const GDScriptParser::SubscriptNode *>(par->default_value); + if (sub->is_constant) { + if (sub->datatype.kind == GDScriptParser::DataType::ENUM_VALUE) { + def_val = sub->get_datatype().to_string(); + } else if (sub->reduced) { + const Variant::Type vt = sub->reduced_value.get_type(); + if (vt == Variant::Type::NIL || vt == Variant::Type::FLOAT || vt == Variant::Type::INT || vt == Variant::Type::STRING || vt == Variant::Type::STRING_NAME || vt == Variant::Type::BOOL || vt == Variant::Type::NODE_PATH) { + def_val = sub->reduced_value.operator String(); + } else { + def_val = sub->get_datatype().to_string() + sub->reduced_value.operator String(); + } + } + } + } break; + default: + break; } arghint += " = " + def_val; } diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 2faf0febca..432d31f78f 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -817,6 +817,8 @@ void GDScriptParser::parse_class_body(bool p_is_multiline) { class_end = true; break; default: + // Display a completion with identifiers. + make_completion_context(COMPLETION_IDENTIFIER, nullptr); push_error(vformat(R"(Unexpected "%s" in class body.)", current.get_name())); advance(); break; @@ -3537,12 +3539,12 @@ bool GDScriptParser::export_annotations(const AnnotationNode *p_annotation, Node variable->export_info.hint = PROPERTY_HINT_ENUM; String enum_hint_string; - for (const Map<StringName, int>::Element *E = export_type.enum_values.front(); E; E = E->next()) { - enum_hint_string += E->key().operator String().capitalize().xml_escape(); + for (OrderedHashMap<StringName, int>::Element E = export_type.enum_values.front(); E; E = E.next()) { + enum_hint_string += E.key().operator String().capitalize().xml_escape(); enum_hint_string += ":"; - enum_hint_string += String::num_int64(E->get()).xml_escape(); + enum_hint_string += String::num_int64(E.value()).xml_escape(); - if (E->next()) { + if (E.next()) { enum_hint_string += ","; } } diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index bf0f670905..e4311d2d5e 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -133,7 +133,7 @@ public: ClassNode *class_type = nullptr; MethodInfo method_info; // For callable/signals. - Map<StringName, int> enum_values; // For enums. + OrderedHashMap<StringName, int> enum_values; // For enums. _FORCE_INLINE_ bool is_set() const { return kind != UNRESOLVED; } _FORCE_INLINE_ bool has_no_type() const { return type_source == UNDETECTED; } diff --git a/modules/gdscript/gdscript_vm.cpp b/modules/gdscript/gdscript_vm.cpp index 014a2ad3b8..e0facaf61d 100644 --- a/modules/gdscript/gdscript_vm.cpp +++ b/modules/gdscript/gdscript_vm.cpp @@ -488,7 +488,12 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a memnew_placement(&stack[i + 3], Variant(*p_args[i])); continue; } - + // If types already match, don't call Variant::construct(). Constructors of some types + // (e.g. packed arrays) do copies, whereas they pass by reference when inside a Variant. + if (argument_types[i].is_type(*p_args[i], false)) { + memnew_placement(&stack[i + 3], Variant(*p_args[i])); + continue; + } if (!argument_types[i].is_type(*p_args[i], true)) { r_err.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_err.argument = i; diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index 0d41ff025e..5a931ed839 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -6901,78 +6901,83 @@ Error GLTFDocument::append_from_buffer(PackedByteArray p_bytes, String p_base_pa Error GLTFDocument::_parse_gltf_state(Ref<GLTFState> state, const String &p_search_path, float p_bake_fps) { Error err; - /* STEP 0 PARSE SCENE */ + + /* PARSE EXTENSIONS */ + err = _parse_gltf_extensions(state); + ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); + + /* PARSE SCENE */ err = _parse_scenes(state); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); - /* STEP 1 PARSE NODES */ + /* PARSE NODES */ err = _parse_nodes(state); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); - /* STEP 2 PARSE BUFFERS */ + /* PARSE BUFFERS */ err = _parse_buffers(state, p_search_path); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); - /* STEP 3 PARSE BUFFER VIEWS */ + /* PARSE BUFFER VIEWS */ err = _parse_buffer_views(state); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); - /* STEP 4 PARSE ACCESSORS */ + /* PARSE ACCESSORS */ err = _parse_accessors(state); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); - /* STEP 5 PARSE IMAGES */ + /* PARSE IMAGES */ err = _parse_images(state, p_search_path); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); - /* STEP 6 PARSE TEXTURES */ + /* PARSE TEXTURES */ err = _parse_textures(state); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); - /* STEP 7 PARSE TEXTURES */ + /* PARSE TEXTURES */ err = _parse_materials(state); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); - /* STEP 9 PARSE SKINS */ + /* PARSE SKINS */ err = _parse_skins(state); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); - /* STEP 10 DETERMINE SKELETONS */ + /* DETERMINE SKELETONS */ err = _determine_skeletons(state); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); - /* STEP 11 CREATE SKELETONS */ + /* CREATE SKELETONS */ err = _create_skeletons(state); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); - /* STEP 12 CREATE SKINS */ + /* CREATE SKINS */ err = _create_skins(state); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); - /* STEP 13 PARSE MESHES (we have enough info now) */ + /* PARSE MESHES (we have enough info now) */ err = _parse_meshes(state); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); - /* STEP 14 PARSE LIGHTS */ + /* PARSE LIGHTS */ err = _parse_lights(state); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); - /* STEP 15 PARSE CAMERAS */ + /* PARSE CAMERAS */ err = _parse_cameras(state); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); - /* STEP 16 PARSE ANIMATIONS */ + /* PARSE ANIMATIONS */ err = _parse_animations(state); ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); - /* STEP 17 ASSIGN SCENE NAMES */ + /* ASSIGN SCENE NAMES */ _assign_scene_names(state); Node3D *root = memnew(Node3D); @@ -6999,3 +7004,15 @@ Error GLTFDocument::append_from_file(String p_path, Ref<GLTFState> r_state, uint ERR_FAIL_COND_V(err != OK, ERR_PARSE_ERROR); return err; } + +Error GLTFDocument::_parse_gltf_extensions(Ref<GLTFState> state) { + ERR_FAIL_NULL_V(state, ERR_PARSE_ERROR); + if (state->json.has("extensionsRequired") && state->json["extensionsRequired"].get_type() == Variant::ARRAY) { + Array extensions_required = state->json["extensionsRequired"]; + if (extensions_required.find("KHR_draco_mesh_compression") != -1) { + ERR_PRINT("glTF2 extension KHR_draco_mesh_compression is not supported."); + return ERR_UNAVAILABLE; + } + } + return OK; +} diff --git a/modules/gltf/gltf_document.h b/modules/gltf/gltf_document.h index 8f8f5b410a..c0649e0129 100644 --- a/modules/gltf/gltf_document.h +++ b/modules/gltf/gltf_document.h @@ -392,6 +392,7 @@ public: public: Error _parse_gltf_state(Ref<GLTFState> state, const String &p_search_path, float p_bake_fps); + Error _parse_gltf_extensions(Ref<GLTFState> state); void _process_mesh_instances(Ref<GLTFState> state, Node *scene_root); void _generate_scene_node(Ref<GLTFState> state, Node *scene_parent, Node3D *scene_root, diff --git a/modules/lightmapper_rd/lightmapper_rd.cpp b/modules/lightmapper_rd/lightmapper_rd.cpp index 5d5b2ed6cb..11715040c2 100644 --- a/modules/lightmapper_rd/lightmapper_rd.cpp +++ b/modules/lightmapper_rd/lightmapper_rd.cpp @@ -775,11 +775,7 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d } else { panorama_tex.instantiate(); panorama_tex->create(8, 8, false, Image::FORMAT_RGBAF); - for (int i = 0; i < 8; i++) { - for (int j = 0; j < 8; j++) { - panorama_tex->set_pixel(i, j, Color(0, 0, 0, 1)); - } - } + panorama_tex->fill(Color(0, 0, 0, 1)); } RD::TextureFormat tfp; diff --git a/modules/mbedtls/SCsub b/modules/mbedtls/SCsub index 4fcbe8fb43..9133fdef35 100644 --- a/modules/mbedtls/SCsub +++ b/modules/mbedtls/SCsub @@ -29,6 +29,7 @@ if env["builtin_mbedtls"]: "cipher_wrap.c", "cmac.c", "ctr_drbg.c", + "constant_time.c", "debug.c", "des.c", "dhm.c", @@ -48,8 +49,9 @@ if env["builtin_mbedtls"]: "md4.c", "md5.c", "md.c", - "md_wrap.c", "memory_buffer_alloc.c", + "mps_reader.c", + "mps_trace.c", "net_sockets.c", "nist_kw.c", "oid.c", @@ -75,9 +77,11 @@ if env["builtin_mbedtls"]: "ssl_ciphersuites.c", "ssl_cli.c", "ssl_cookie.c", + "ssl_msg.c", "ssl_srv.c", "ssl_ticket.c", "ssl_tls.c", + "ssl_tls13_keys.c", "threading.c", "timing.c", "version.c", diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index f1945f62cb..f9997a437f 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -2573,7 +2573,7 @@ int32_t TextServerAdvanced::font_get_glyph_index(RID p_font_rid, int p_size, cha return FT_Get_Char_Index(fd->cache[size]->face, p_char); } } else { - return 0; + return (int32_t)p_char; } #else return (int32_t)p_char; @@ -2841,6 +2841,24 @@ Vector<String> TextServerAdvanced::font_get_script_support_overrides(RID p_font_ return out; } +void TextServerAdvanced::font_set_opentype_feature_overrides(RID p_font_rid, const Dictionary &p_overrides) { + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND(!fd); + + MutexLock lock(fd->mutex); + Vector2i size = _get_size(fd, 16); + ERR_FAIL_COND(!_ensure_cache_for_size(fd, size)); + fd->feature_overrides = p_overrides; +} + +Dictionary TextServerAdvanced::font_get_opentype_feature_overrides(RID p_font_rid) const { + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND_V(!fd, Dictionary()); + + MutexLock lock(fd->mutex); + return fd->feature_overrides; +} + Dictionary TextServerAdvanced::font_supported_feature_list(RID p_font_rid) const { FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, Dictionary()); @@ -3668,6 +3686,12 @@ float TextServerAdvanced::shaped_text_tab_align(RID p_shaped, const PackedFloat3 const_cast<TextServerAdvanced *>(this)->shaped_text_update_breaks(p_shaped); } + for (int i = 0; i < p_tab_stops.size(); i++) { + if (p_tab_stops[i] <= 0) { + return 0.f; + } + } + int tab_index = 0; float off = 0.f; @@ -4231,6 +4255,24 @@ Glyph TextServerAdvanced::_shape_single_glyph(ShapedTextDataAdvanced *p_sd, char return gl; } +_FORCE_INLINE_ void TextServerAdvanced::_add_featuers(const Dictionary &p_source, Vector<hb_feature_t> &r_ftrs) { + for (const Variant *ftr = p_source.next(nullptr); ftr != nullptr; ftr = p_source.next(ftr)) { + int32_t values = p_source[*ftr]; + if (values >= 0) { + hb_feature_t feature; + if (ftr->get_type() == Variant::STRING) { + feature.tag = name_to_tag(*ftr); + } else { + feature.tag = *ftr; + } + feature.value = values; + feature.start = 0; + feature.end = -1; + r_ftrs.push_back(feature); + } + } +} + void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int32_t p_start, int32_t p_end, hb_script_t p_script, hb_direction_t p_direction, Vector<RID> p_fonts, int p_span, int p_fb_index) { int fs = p_sd->spans[p_span].font_size; if (p_fb_index >= p_fonts.size()) { @@ -4287,17 +4329,9 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int32_t p_star hb_buffer_add_utf32(p_sd->hb_buffer, (const uint32_t *)p_sd->text.ptr(), p_sd->text.length(), p_start, p_end - p_start); Vector<hb_feature_t> ftrs; - for (const Variant *ftr = p_sd->spans[p_span].features.next(nullptr); ftr != nullptr; ftr = p_sd->spans[p_span].features.next(ftr)) { - double values = p_sd->spans[p_span].features[*ftr]; - if (values >= 0) { - hb_feature_t feature; - feature.tag = *ftr; - feature.value = values; - feature.start = 0; - feature.end = -1; - ftrs.push_back(feature); - } - } + _add_featuers(font_get_opentype_feature_overrides(f), ftrs); + _add_featuers(p_sd->spans[p_span].features, ftrs); + hb_shape(hb_font, p_sd->hb_buffer, ftrs.is_empty() ? nullptr : &ftrs[0], ftrs.size()); unsigned int glyph_count = 0; diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h index fb9446da9f..6ff9817dcf 100644 --- a/modules/text_server_adv/text_server_adv.h +++ b/modules/text_server_adv/text_server_adv.h @@ -187,6 +187,7 @@ class TextServerAdvanced : public TextServer { Set<uint32_t> supported_scripts; Dictionary supported_features; Dictionary supported_varaitions; + Dictionary feature_overrides; // Language/script support override. Map<String, bool> language_support_overrides; @@ -272,6 +273,7 @@ class TextServerAdvanced : public TextServer { bool _shape_substr(ShapedTextDataAdvanced *p_new_sd, const ShapedTextDataAdvanced *p_sd, int p_start, int p_length) const; void _shape_run(ShapedTextDataAdvanced *p_sd, int32_t p_start, int32_t p_end, hb_script_t p_script, hb_direction_t p_direction, Vector<RID> p_fonts, int p_span, int p_fb_index); Glyph _shape_single_glyph(ShapedTextDataAdvanced *p_sd, char32_t p_char, hb_script_t p_script, hb_direction_t p_direction, RID p_font, int p_font_size); + _FORCE_INLINE_ void _add_featuers(const Dictionary &p_source, Vector<hb_feature_t> &r_ftrs); // HarfBuzz bitmap font interface. @@ -447,6 +449,9 @@ public: virtual void font_remove_script_support_override(RID p_font_rid, const String &p_script) override; virtual Vector<String> font_get_script_support_overrides(RID p_font_rid) override; + virtual void font_set_opentype_feature_overrides(RID p_font_rid, const Dictionary &p_overrides) override; + virtual Dictionary font_get_opentype_feature_overrides(RID p_font_rid) const override; + virtual Dictionary font_supported_feature_list(RID p_font_rid) const override; virtual Dictionary font_supported_variation_list(RID p_font_rid) const override; diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp index 1f7c5427be..f28d174c5c 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -1995,6 +1995,24 @@ Vector<String> TextServerFallback::font_get_script_support_overrides(RID p_font_ return out; } +void TextServerFallback::font_set_opentype_feature_overrides(RID p_font_rid, const Dictionary &p_overrides) { + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND(!fd); + + MutexLock lock(fd->mutex); + Vector2i size = _get_size(fd, 16); + ERR_FAIL_COND(!_ensure_cache_for_size(fd, size)); + fd->feature_overrides = p_overrides; +} + +Dictionary TextServerFallback::font_get_opentype_feature_overrides(RID p_font_rid) const { + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND_V(!fd, Dictionary()); + + MutexLock lock(fd->mutex); + return fd->feature_overrides; +} + Dictionary TextServerFallback::font_supported_feature_list(RID p_font_rid) const { return Dictionary(); } @@ -2665,6 +2683,12 @@ float TextServerFallback::shaped_text_tab_align(RID p_shaped, const PackedFloat3 const_cast<TextServerFallback *>(this)->shaped_text_update_breaks(p_shaped); } + for (int i = 0; i < p_tab_stops.size(); i++) { + if (p_tab_stops[i] <= 0) { + return 0.f; + } + } + int tab_index = 0; float off = 0.f; diff --git a/modules/text_server_fb/text_server_fb.h b/modules/text_server_fb/text_server_fb.h index d47fa44f8f..9d1be50b04 100644 --- a/modules/text_server_fb/text_server_fb.h +++ b/modules/text_server_fb/text_server_fb.h @@ -150,6 +150,7 @@ class TextServerFallback : public TextServer { bool face_init = false; Dictionary supported_varaitions; + Dictionary feature_overrides; // Language/script support override. Map<String, bool> language_support_overrides; @@ -357,6 +358,9 @@ public: virtual void font_remove_script_support_override(RID p_font_rid, const String &p_script) override; virtual Vector<String> font_get_script_support_overrides(RID p_font_rid) override; + virtual void font_set_opentype_feature_overrides(RID p_font_rid, const Dictionary &p_overrides) override; + virtual Dictionary font_get_opentype_feature_overrides(RID p_font_rid) const override; + virtual Dictionary font_supported_feature_list(RID p_font_rid) const override; virtual Dictionary font_supported_variation_list(RID p_font_rid) const override; diff --git a/modules/websocket/websocket_server.cpp b/modules/websocket/websocket_server.cpp index b7249e4243..b3f0140b80 100644 --- a/modules/websocket/websocket_server.cpp +++ b/modules/websocket/websocket_server.cpp @@ -67,7 +67,7 @@ void WebSocketServer::_bind_methods() { ClassDB::bind_method(D_METHOD("get_handshake_timeout"), &WebSocketServer::get_handshake_timeout); ClassDB::bind_method(D_METHOD("set_handshake_timeout", "timeout"), &WebSocketServer::set_handshake_timeout); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "handshake_timeout"), "set_handshake_timeout", "get_handshake_timeout"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "handshake_timeout"), "set_handshake_timeout", "get_handshake_timeout"); ADD_SIGNAL(MethodInfo("client_close_request", PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::INT, "code"), PropertyInfo(Variant::STRING, "reason"))); ADD_SIGNAL(MethodInfo("client_disconnected", PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::BOOL, "was_clean_close"))); |