diff options
Diffstat (limited to 'modules')
13 files changed, 231 insertions, 206 deletions
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 258f1a80f7..57a29cc81e 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -1111,21 +1111,27 @@ bool GDScript::inherits_script(const Ref<Script> &p_script) const { GDScript *GDScript::find_class(const String &p_qualified_name) { String first = p_qualified_name.get_slice("::", 0); + Vector<String> class_names; GDScript *result = nullptr; + // Empty initial name means start here. if (first.is_empty() || first == name) { + class_names = p_qualified_name.split("::"); result = this; - } else if (first == get_root_script()->path) { + } else if (p_qualified_name.begins_with(get_root_script()->path)) { + // Script path could have a class path separator("::") in it. + class_names = p_qualified_name.trim_prefix(get_root_script()->path).split("::"); result = get_root_script(); } else if (HashMap<StringName, Ref<GDScript>>::Iterator E = subclasses.find(first)) { + class_names = p_qualified_name.split("::"); result = E->value.ptr(); } else if (_owner != nullptr) { // Check parent scope. return _owner->find_class(p_qualified_name); } - int name_count = p_qualified_name.get_slice_count("::"); - for (int i = 1; result != nullptr && i < name_count; i++) { - String current_name = p_qualified_name.get_slice("::", i); + // Starts at index 1 because index 0 was handled above. + for (int i = 1; result != nullptr && i < class_names.size(); i++) { + String current_name = class_names[i]; if (HashMap<StringName, Ref<GDScript>>::Iterator E = result->subclasses.find(current_name)) { result = E->value.ptr(); } else { @@ -1137,11 +1143,12 @@ GDScript *GDScript::find_class(const String &p_qualified_name) { return result; } -bool GDScript::is_subclass(const GDScript *p_script) { +bool GDScript::has_class(const GDScript *p_script) { String fqn = p_script->fully_qualified_name; - if (!fqn.is_empty() && fqn != fully_qualified_name && fqn.begins_with(fully_qualified_name)) { - String fqn_rest = fqn.substr(fully_qualified_name.length()); - return find_class(fqn_rest) == p_script; + if (fully_qualified_name.is_empty() && fqn.get_slice("::", 0).is_empty()) { + return p_script == this; + } else if (fqn.begins_with(fully_qualified_name)) { + return p_script == find_class(fqn.trim_prefix(fully_qualified_name)); } return false; } @@ -2592,8 +2599,7 @@ Ref<GDScript> GDScriptLanguage::get_script_by_fully_qualified_name(const String SelfList<GDScript> *elem = script_list.first(); while (elem) { GDScript *scr = elem->self(); - scr = scr->find_class(p_name); - if (scr != nullptr) { + if (scr->fully_qualified_name == p_name) { return scr; } elem = elem->next(); diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index 7911ea47ec..332d18f720 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -187,7 +187,7 @@ public: bool inherits_script(const Ref<Script> &p_script) const override; GDScript *find_class(const String &p_qualified_name); - bool is_subclass(const GDScript *p_script); + bool has_class(const GDScript *p_script); GDScript *get_root_script(); bool is_root_script() const { return _owner == nullptr; } String get_fully_qualified_name() const { return fully_qualified_name; } diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 30ac1f29b1..3bbe71fb90 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -996,7 +996,9 @@ void GDScriptAnalyzer::resolve_class_member(GDScriptParser::ClassNode *p_class, check_class_member_name_conflict(p_class, member.enum_value.identifier->name, member.enum_value.parent_enum); if (member.enum_value.index > 0) { - member.enum_value.value = member.enum_value.parent_enum->values[member.enum_value.index - 1].value + 1; + const GDScriptParser::EnumNode::Value &prev_value = member.enum_value.parent_enum->values[member.enum_value.index - 1]; + resolve_class_member(p_class, prev_value.identifier->name, member.enum_value.identifier); + member.enum_value.value = prev_value.value + 1; } else { member.enum_value.value = 0; } @@ -3146,6 +3148,16 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod case GDScriptParser::ClassNode::Member::FUNCTION: p_identifier->set_datatype(make_callable_type(member.function->info)); break; + case GDScriptParser::ClassNode::Member::CLASS: + if (p_base != nullptr && p_base->is_constant) { + Error err = OK; + GDScript *scr = GDScriptCache::get_full_script(base.script_path, err).ptr(); + ERR_FAIL_COND_MSG(err != OK, "Error while getting subscript full script."); + scr = scr->find_class(p_identifier->get_datatype().class_type->fqcn); + p_identifier->reduced_value = scr; + p_identifier->is_constant = true; + } + break; default: break; // Type already set. } @@ -3994,37 +4006,27 @@ GDScriptParser::DataType GDScriptAnalyzer::type_from_variant(const Variant &p_va result.kind = GDScriptParser::DataType::CLASS; // This might be an inner class, so we want to get the parser for the root. // But still get the inner class from that tree. - GDScript *current = gds.ptr(); - List<StringName> class_chain; - while (current->_owner) { - // Push to front so it's in reverse. - class_chain.push_front(current->name); - current = current->_owner; - } - - Ref<GDScriptParserRef> ref = get_parser_for(current->get_path()); + String script_path = gds->get_script_path(); + Ref<GDScriptParserRef> ref = get_parser_for(script_path); if (ref.is_null()) { - push_error("Could not find script in path.", p_source); + push_error(vformat(R"(Could not find script "%s".)", script_path), p_source); GDScriptParser::DataType error_type; error_type.kind = GDScriptParser::DataType::VARIANT; return error_type; } - ref->raise_status(GDScriptParserRef::INHERITANCE_SOLVED); - - GDScriptParser::ClassNode *found = ref->get_parser()->head; - - for (const StringName &E : class_chain) { - if (!found->has_member(E)) { - return GDScriptParser::DataType(); - } - - if (found->get_member(E).type != GDScriptParser::ClassNode::Member::CLASS) { - return GDScriptParser::DataType(); + Error err = ref->raise_status(GDScriptParserRef::INHERITANCE_SOLVED); + GDScriptParser::ClassNode *found = nullptr; + if (err == OK) { + found = ref->get_parser()->find_class(gds->fully_qualified_name); + if (found != nullptr) { + err = resolve_class_inheritance(found, p_source); } - - resolve_class_member(found, E, p_source); - - found = found->get_member(E).m_class; + } + if (err || found == nullptr) { + push_error(vformat(R"(Could not resolve script "%s".)", script_path), p_source); + GDScriptParser::DataType error_type; + error_type.kind = GDScriptParser::DataType::VARIANT; + return error_type; } result.class_type = found; diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index 4740b9b5a9..50588110c4 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -117,8 +117,7 @@ GDScriptDataType GDScriptCompiler::_gdtype_from_datatype(const GDScriptParser::D result.builtin_type = p_datatype.builtin_type; result.native_type = p_datatype.native_type; - String root_name = p_datatype.class_type->fqcn.get_slice("::", 0); - bool is_local_class = !root_name.is_empty() && root_name == main_script->fully_qualified_name; + bool is_local_class = parser->has_class(p_datatype.class_type); Ref<GDScript> script; if (is_local_class) { @@ -2300,7 +2299,7 @@ Error GDScriptCompiler::_populate_class_members(GDScript *p_script, const GDScri return ERR_COMPILATION_FAILED; } - if (base.ptr() == main_script || main_script->is_subclass(base.ptr())) { + if (main_script->has_class(base.ptr())) { Error err = _populate_class_members(base.ptr(), p_class->base_type.class_type, p_keep_state); if (err) { return err; diff --git a/modules/gdscript/tests/scripts/analyzer/features/inner_class_constant_assignment.gd b/modules/gdscript/tests/scripts/analyzer/features/inner_class_constant_assignment.gd new file mode 100644 index 0000000000..ed5fb18b73 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/inner_class_constant_assignment.gd @@ -0,0 +1,7 @@ +const External = preload("inner_class_constant_assignment_external.notest.gd") +const ExternalInnerClass = External.InnerClass + +func test(): + var inst_external: ExternalInnerClass = ExternalInnerClass.new() + inst_external.x = 4.0 + print(inst_external.x) diff --git a/modules/gdscript/tests/scripts/analyzer/features/inner_class_constant_assignment.out b/modules/gdscript/tests/scripts/analyzer/features/inner_class_constant_assignment.out new file mode 100644 index 0000000000..15666c46ad --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/inner_class_constant_assignment.out @@ -0,0 +1,2 @@ +GDTEST_OK +4 diff --git a/modules/gdscript/tests/scripts/analyzer/features/inner_class_constant_assignment_external.notest.gd b/modules/gdscript/tests/scripts/analyzer/features/inner_class_constant_assignment_external.notest.gd new file mode 100644 index 0000000000..788c99d469 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/features/inner_class_constant_assignment_external.notest.gd @@ -0,0 +1,2 @@ +class InnerClass: + var x: = 3.0 diff --git a/modules/gdscript/tests/scripts/analyzer/features/out_of_order.gd b/modules/gdscript/tests/scripts/analyzer/features/out_of_order.gd index 069e54c528..11349cc916 100644 --- a/modules/gdscript/tests/scripts/analyzer/features/out_of_order.gd +++ b/modules/gdscript/tests/scripts/analyzer/features/out_of_order.gd @@ -42,7 +42,8 @@ const c2 := EV2 enum { EV1 = 42, - EV2 = EV3 + 1 + UNUSED = EV3, + EV2 } enum { diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index f4db576b0c..d858f76b28 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -3384,177 +3384,179 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> p_state) { if (!material->get_name().is_empty()) { d["name"] = _gen_unique_name(p_state, material->get_name()); } + Ref<BaseMaterial3D> base_material = material; - if (base_material.is_valid()) { - Dictionary mr; - { - Array arr; - const Color c = base_material->get_albedo().srgb_to_linear(); - arr.push_back(c.r); - arr.push_back(c.g); - arr.push_back(c.b); - arr.push_back(c.a); - mr["baseColorFactor"] = arr; + if (base_material.is_null()) { + materials.push_back(d); + continue; + } + + Dictionary mr; + { + Array arr; + const Color c = base_material->get_albedo().srgb_to_linear(); + arr.push_back(c.r); + arr.push_back(c.g); + arr.push_back(c.b); + arr.push_back(c.a); + mr["baseColorFactor"] = arr; + } + { + Dictionary bct; + Ref<Texture2D> albedo_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_ALBEDO); + GLTFTextureIndex gltf_texture_index = -1; + + if (albedo_texture.is_valid() && albedo_texture->get_image().is_valid()) { + albedo_texture->set_name(material->get_name() + "_albedo"); + gltf_texture_index = _set_texture(p_state, albedo_texture, base_material->get_texture_filter(), base_material->get_flag(BaseMaterial3D::FLAG_USE_TEXTURE_REPEAT)); } - { - Dictionary bct; - if (base_material.is_valid()) { - Ref<Texture2D> albedo_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_ALBEDO); - GLTFTextureIndex gltf_texture_index = -1; - - if (albedo_texture.is_valid() && albedo_texture->get_image().is_valid()) { - albedo_texture->set_name(material->get_name() + "_albedo"); - gltf_texture_index = _set_texture(p_state, albedo_texture, base_material->get_texture_filter(), base_material->get_flag(BaseMaterial3D::FLAG_USE_TEXTURE_REPEAT)); - } - if (gltf_texture_index != -1) { - bct["index"] = gltf_texture_index; - Dictionary extensions = _serialize_texture_transform_uv1(material); - if (!extensions.is_empty()) { - bct["extensions"] = extensions; - p_state->use_khr_texture_transform = true; - } - mr["baseColorTexture"] = bct; - } + if (gltf_texture_index != -1) { + bct["index"] = gltf_texture_index; + Dictionary extensions = _serialize_texture_transform_uv1(material); + if (!extensions.is_empty()) { + bct["extensions"] = extensions; + p_state->use_khr_texture_transform = true; + } + mr["baseColorTexture"] = bct; + } + } + + mr["metallicFactor"] = base_material->get_metallic(); + mr["roughnessFactor"] = base_material->get_roughness(); + bool has_roughness = base_material->get_texture(BaseMaterial3D::TEXTURE_ROUGHNESS).is_valid() && base_material->get_texture(BaseMaterial3D::TEXTURE_ROUGHNESS)->get_image().is_valid(); + bool has_ao = base_material->get_feature(BaseMaterial3D::FEATURE_AMBIENT_OCCLUSION) && base_material->get_texture(BaseMaterial3D::TEXTURE_AMBIENT_OCCLUSION).is_valid(); + bool has_metalness = base_material->get_texture(BaseMaterial3D::TEXTURE_METALLIC).is_valid() && base_material->get_texture(BaseMaterial3D::TEXTURE_METALLIC)->get_image().is_valid(); + if (has_ao || has_roughness || has_metalness) { + Dictionary mrt; + Ref<Texture2D> roughness_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_ROUGHNESS); + BaseMaterial3D::TextureChannel roughness_channel = base_material->get_roughness_texture_channel(); + Ref<Texture2D> metallic_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_METALLIC); + BaseMaterial3D::TextureChannel metalness_channel = base_material->get_metallic_texture_channel(); + Ref<Texture2D> ao_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_AMBIENT_OCCLUSION); + BaseMaterial3D::TextureChannel ao_channel = base_material->get_ao_texture_channel(); + Ref<ImageTexture> orm_texture; + orm_texture.instantiate(); + Ref<Image> orm_image; + orm_image.instantiate(); + int32_t height = 0; + int32_t width = 0; + Ref<Image> ao_image; + if (has_ao) { + height = ao_texture->get_height(); + width = ao_texture->get_width(); + ao_image = ao_texture->get_image(); + Ref<ImageTexture> img_tex = ao_image; + if (img_tex.is_valid()) { + ao_image = img_tex->get_image(); + } + if (ao_image->is_compressed()) { + ao_image->decompress(); + } + } + Ref<Image> roughness_image; + if (has_roughness) { + height = roughness_texture->get_height(); + width = roughness_texture->get_width(); + roughness_image = roughness_texture->get_image(); + Ref<ImageTexture> img_tex = roughness_image; + if (img_tex.is_valid()) { + roughness_image = img_tex->get_image(); + } + if (roughness_image->is_compressed()) { + roughness_image->decompress(); } } - if (base_material.is_valid()) { - mr["metallicFactor"] = base_material->get_metallic(); - mr["roughnessFactor"] = base_material->get_roughness(); - bool has_roughness = base_material->get_texture(BaseMaterial3D::TEXTURE_ROUGHNESS).is_valid() && base_material->get_texture(BaseMaterial3D::TEXTURE_ROUGHNESS)->get_image().is_valid(); - bool has_ao = base_material->get_feature(BaseMaterial3D::FEATURE_AMBIENT_OCCLUSION) && base_material->get_texture(BaseMaterial3D::TEXTURE_AMBIENT_OCCLUSION).is_valid(); - bool has_metalness = base_material->get_texture(BaseMaterial3D::TEXTURE_METALLIC).is_valid() && base_material->get_texture(BaseMaterial3D::TEXTURE_METALLIC)->get_image().is_valid(); - if (has_ao || has_roughness || has_metalness) { - Dictionary mrt; - Ref<Texture2D> roughness_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_ROUGHNESS); - BaseMaterial3D::TextureChannel roughness_channel = base_material->get_roughness_texture_channel(); - Ref<Texture2D> metallic_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_METALLIC); - BaseMaterial3D::TextureChannel metalness_channel = base_material->get_metallic_texture_channel(); - Ref<Texture2D> ao_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_AMBIENT_OCCLUSION); - BaseMaterial3D::TextureChannel ao_channel = base_material->get_ao_texture_channel(); - Ref<ImageTexture> orm_texture; - orm_texture.instantiate(); - Ref<Image> orm_image; - orm_image.instantiate(); - int32_t height = 0; - int32_t width = 0; - Ref<Image> ao_image; + Ref<Image> metallness_image; + if (has_metalness) { + height = metallic_texture->get_height(); + width = metallic_texture->get_width(); + metallness_image = metallic_texture->get_image(); + Ref<ImageTexture> img_tex = metallness_image; + if (img_tex.is_valid()) { + metallness_image = img_tex->get_image(); + } + if (metallness_image->is_compressed()) { + metallness_image->decompress(); + } + } + Ref<Texture2D> albedo_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_ALBEDO); + if (albedo_texture.is_valid() && albedo_texture->get_image().is_valid()) { + height = albedo_texture->get_height(); + width = albedo_texture->get_width(); + } + orm_image->initialize_data(width, height, false, Image::FORMAT_RGBA8); + if (ao_image.is_valid() && ao_image->get_size() != Vector2(width, height)) { + ao_image->resize(width, height, Image::INTERPOLATE_LANCZOS); + } + if (roughness_image.is_valid() && roughness_image->get_size() != Vector2(width, height)) { + roughness_image->resize(width, height, Image::INTERPOLATE_LANCZOS); + } + if (metallness_image.is_valid() && metallness_image->get_size() != Vector2(width, height)) { + metallness_image->resize(width, height, Image::INTERPOLATE_LANCZOS); + } + for (int32_t h = 0; h < height; h++) { + for (int32_t w = 0; w < width; w++) { + Color c = Color(1.0f, 1.0f, 1.0f); if (has_ao) { - height = ao_texture->get_height(); - width = ao_texture->get_width(); - ao_image = ao_texture->get_image(); - Ref<ImageTexture> img_tex = ao_image; - if (img_tex.is_valid()) { - ao_image = img_tex->get_image(); - } - if (ao_image->is_compressed()) { - ao_image->decompress(); + if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_RED == ao_channel) { + c.r = ao_image->get_pixel(w, h).r; + } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_GREEN == ao_channel) { + c.r = ao_image->get_pixel(w, h).g; + } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_BLUE == ao_channel) { + c.r = ao_image->get_pixel(w, h).b; + } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_ALPHA == ao_channel) { + c.r = ao_image->get_pixel(w, h).a; } } - Ref<Image> roughness_image; if (has_roughness) { - height = roughness_texture->get_height(); - width = roughness_texture->get_width(); - roughness_image = roughness_texture->get_image(); - Ref<ImageTexture> img_tex = roughness_image; - if (img_tex.is_valid()) { - roughness_image = img_tex->get_image(); - } - if (roughness_image->is_compressed()) { - roughness_image->decompress(); + if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_RED == roughness_channel) { + c.g = roughness_image->get_pixel(w, h).r; + } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_GREEN == roughness_channel) { + c.g = roughness_image->get_pixel(w, h).g; + } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_BLUE == roughness_channel) { + c.g = roughness_image->get_pixel(w, h).b; + } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_ALPHA == roughness_channel) { + c.g = roughness_image->get_pixel(w, h).a; } } - Ref<Image> metallness_image; if (has_metalness) { - height = metallic_texture->get_height(); - width = metallic_texture->get_width(); - metallness_image = metallic_texture->get_image(); - Ref<ImageTexture> img_tex = metallness_image; - if (img_tex.is_valid()) { - metallness_image = img_tex->get_image(); - } - if (metallness_image->is_compressed()) { - metallness_image->decompress(); - } - } - Ref<Texture2D> albedo_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_ALBEDO); - if (albedo_texture.is_valid() && albedo_texture->get_image().is_valid()) { - height = albedo_texture->get_height(); - width = albedo_texture->get_width(); - } - orm_image->initialize_data(width, height, false, Image::FORMAT_RGBA8); - if (ao_image.is_valid() && ao_image->get_size() != Vector2(width, height)) { - ao_image->resize(width, height, Image::INTERPOLATE_LANCZOS); - } - if (roughness_image.is_valid() && roughness_image->get_size() != Vector2(width, height)) { - roughness_image->resize(width, height, Image::INTERPOLATE_LANCZOS); - } - if (metallness_image.is_valid() && metallness_image->get_size() != Vector2(width, height)) { - metallness_image->resize(width, height, Image::INTERPOLATE_LANCZOS); - } - for (int32_t h = 0; h < height; h++) { - for (int32_t w = 0; w < width; w++) { - Color c = Color(1.0f, 1.0f, 1.0f); - if (has_ao) { - if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_RED == ao_channel) { - c.r = ao_image->get_pixel(w, h).r; - } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_GREEN == ao_channel) { - c.r = ao_image->get_pixel(w, h).g; - } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_BLUE == ao_channel) { - c.r = ao_image->get_pixel(w, h).b; - } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_ALPHA == ao_channel) { - c.r = ao_image->get_pixel(w, h).a; - } - } - if (has_roughness) { - if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_RED == roughness_channel) { - c.g = roughness_image->get_pixel(w, h).r; - } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_GREEN == roughness_channel) { - c.g = roughness_image->get_pixel(w, h).g; - } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_BLUE == roughness_channel) { - c.g = roughness_image->get_pixel(w, h).b; - } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_ALPHA == roughness_channel) { - c.g = roughness_image->get_pixel(w, h).a; - } - } - if (has_metalness) { - if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_RED == metalness_channel) { - c.b = metallness_image->get_pixel(w, h).r; - } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_GREEN == metalness_channel) { - c.b = metallness_image->get_pixel(w, h).g; - } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_BLUE == metalness_channel) { - c.b = metallness_image->get_pixel(w, h).b; - } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_ALPHA == metalness_channel) { - c.b = metallness_image->get_pixel(w, h).a; - } - } - orm_image->set_pixel(w, h, c); - } - } - orm_image->generate_mipmaps(); - orm_texture->set_image(orm_image); - GLTFTextureIndex orm_texture_index = -1; - if (has_ao || has_roughness || has_metalness) { - orm_texture->set_name(material->get_name() + "_orm"); - orm_texture_index = _set_texture(p_state, orm_texture, base_material->get_texture_filter(), base_material->get_flag(BaseMaterial3D::FLAG_USE_TEXTURE_REPEAT)); - } - if (has_ao) { - Dictionary occt; - occt["index"] = orm_texture_index; - d["occlusionTexture"] = occt; - } - if (has_roughness || has_metalness) { - mrt["index"] = orm_texture_index; - Dictionary extensions = _serialize_texture_transform_uv1(material); - if (!extensions.is_empty()) { - mrt["extensions"] = extensions; - p_state->use_khr_texture_transform = true; + if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_RED == metalness_channel) { + c.b = metallness_image->get_pixel(w, h).r; + } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_GREEN == metalness_channel) { + c.b = metallness_image->get_pixel(w, h).g; + } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_BLUE == metalness_channel) { + c.b = metallness_image->get_pixel(w, h).b; + } else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_ALPHA == metalness_channel) { + c.b = metallness_image->get_pixel(w, h).a; } - mr["metallicRoughnessTexture"] = mrt; } + orm_image->set_pixel(w, h, c); } } - d["pbrMetallicRoughness"] = mr; + orm_image->generate_mipmaps(); + orm_texture->set_image(orm_image); + GLTFTextureIndex orm_texture_index = -1; + if (has_ao || has_roughness || has_metalness) { + orm_texture->set_name(material->get_name() + "_orm"); + orm_texture_index = _set_texture(p_state, orm_texture, base_material->get_texture_filter(), base_material->get_flag(BaseMaterial3D::FLAG_USE_TEXTURE_REPEAT)); + } + if (has_ao) { + Dictionary occt; + occt["index"] = orm_texture_index; + d["occlusionTexture"] = occt; + } + if (has_roughness || has_metalness) { + mrt["index"] = orm_texture_index; + Dictionary extensions = _serialize_texture_transform_uv1(material); + if (!extensions.is_empty()) { + mrt["extensions"] = extensions; + p_state->use_khr_texture_transform = true; + } + mr["metallicRoughnessTexture"] = mrt; + } } + + d["pbrMetallicRoughness"] = mr; if (base_material->get_feature(BaseMaterial3D::FEATURE_NORMAL_MAPPING)) { Dictionary nt; Ref<ImageTexture> tex; @@ -3607,6 +3609,7 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> p_state) { arr.push_back(c.b); d["emissiveFactor"] = arr; } + if (base_material->get_feature(BaseMaterial3D::FEATURE_EMISSION)) { Dictionary et; Ref<Texture2D> emission_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_EMISSION); @@ -3621,16 +3624,19 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> p_state) { d["emissiveTexture"] = et; } } + const bool ds = base_material->get_cull_mode() == BaseMaterial3D::CULL_DISABLED; if (ds) { d["doubleSided"] = ds; } + if (base_material->get_transparency() == BaseMaterial3D::TRANSPARENCY_ALPHA_SCISSOR) { d["alphaMode"] = "MASK"; d["alphaCutoff"] = base_material->get_alpha_scissor_threshold(); } else if (base_material->get_transparency() != BaseMaterial3D::TRANSPARENCY_DISABLED) { d["alphaMode"] = "BLEND"; } + materials.push_back(d); } if (!materials.size()) { diff --git a/modules/openxr/editor/openxr_action_map_editor.cpp b/modules/openxr/editor/openxr_action_map_editor.cpp index a2c33a91c4..844423afc0 100644 --- a/modules/openxr/editor/openxr_action_map_editor.cpp +++ b/modules/openxr/editor/openxr_action_map_editor.cpp @@ -57,7 +57,7 @@ void OpenXRActionMapEditor::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { for (int i = 0; i < tabs->get_child_count(); i++) { - Control *tab = static_cast<Control *>(tabs->get_child(i)); + Control *tab = Object::cast_to<Control>(tabs->get_child(i)); if (tab) { tab->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("Tree"))); } @@ -208,7 +208,7 @@ void OpenXRActionMapEditor::_on_remove_action_set(Object *p_action_set_editor) { void OpenXRActionMapEditor::_on_action_removed() { for (int i = 0; i < tabs->get_tab_count(); i++) { // First tab won't be an interaction profile editor, but being thorough.. - OpenXRInteractionProfileEditorBase *interaction_profile_editor = static_cast<OpenXRInteractionProfileEditorBase *>(tabs->get_tab_control(i)); + OpenXRInteractionProfileEditorBase *interaction_profile_editor = Object::cast_to<OpenXRInteractionProfileEditorBase>(tabs->get_tab_control(i)); if (interaction_profile_editor) { } } @@ -309,7 +309,7 @@ void OpenXRActionMapEditor::_on_tabs_tab_changed(int p_tab) { } void OpenXRActionMapEditor::_on_tab_button_pressed(int p_tab) { - OpenXRInteractionProfileEditorBase *interaction_profile_editor = static_cast<OpenXRInteractionProfileEditorBase *>(tabs->get_tab_control(p_tab)); + OpenXRInteractionProfileEditorBase *interaction_profile_editor = Object::cast_to<OpenXRInteractionProfileEditorBase>(tabs->get_tab_control(p_tab)); ERR_FAIL_NULL(interaction_profile_editor); undo_redo->create_action(TTR("Remove interaction profile")); @@ -375,9 +375,9 @@ void OpenXRActionMapEditor::_clear_action_map() { child->queue_free(); } - for (int i = 0; i < tabs->get_tab_count(); i++) { + for (int i = tabs->get_tab_count() - 1; i >= 0; --i) { // First tab won't be an interaction profile editor, but being thorough.. - OpenXRInteractionProfileEditorBase *interaction_profile_editor = static_cast<OpenXRInteractionProfileEditorBase *>(tabs->get_tab_control(i)); + OpenXRInteractionProfileEditorBase *interaction_profile_editor = Object::cast_to<OpenXRInteractionProfileEditorBase>(tabs->get_tab_control(i)); if (interaction_profile_editor) { tabs->remove_child(interaction_profile_editor); interaction_profile_editor->queue_free(); diff --git a/modules/openxr/editor/openxr_interaction_profile_editor.cpp b/modules/openxr/editor/openxr_interaction_profile_editor.cpp index 3eca1967f5..ee73f6a5cd 100644 --- a/modules/openxr/editor/openxr_interaction_profile_editor.cpp +++ b/modules/openxr/editor/openxr_interaction_profile_editor.cpp @@ -308,7 +308,7 @@ void OpenXRInteractionProfileEditor::_update_interaction_profile() { void OpenXRInteractionProfileEditor::_theme_changed() { for (int i = 0; i < main_hb->get_child_count(); i++) { - Control *panel = static_cast<Control *>(main_hb->get_child(i)); + Control *panel = Object::cast_to<Control>(main_hb->get_child(i)); if (panel) { panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("TabContainer"))); } diff --git a/modules/openxr/editor/openxr_select_action_dialog.cpp b/modules/openxr/editor/openxr_select_action_dialog.cpp index 5f018291d5..c4b2ef95c5 100644 --- a/modules/openxr/editor/openxr_select_action_dialog.cpp +++ b/modules/openxr/editor/openxr_select_action_dialog.cpp @@ -47,7 +47,7 @@ void OpenXRSelectActionDialog::_notification(int p_what) { void OpenXRSelectActionDialog::_on_select_action(const String p_action) { if (selected_action != "") { NodePath button_path = action_buttons[selected_action]; - Button *button = static_cast<Button *>(get_node(button_path)); + Button *button = Object::cast_to<Button>(get_node(button_path)); if (button != nullptr) { button->set_flat(true); } @@ -57,7 +57,7 @@ void OpenXRSelectActionDialog::_on_select_action(const String p_action) { if (selected_action != "") { NodePath button_path = action_buttons[selected_action]; - Button *button = static_cast<Button *>(get_node(button_path)); + Button *button = Object::cast_to<Button>(get_node(button_path)); if (button != nullptr) { button->set_flat(false); } diff --git a/modules/openxr/editor/openxr_select_interaction_profile_dialog.cpp b/modules/openxr/editor/openxr_select_interaction_profile_dialog.cpp index 6ce26a62db..b871840cb2 100644 --- a/modules/openxr/editor/openxr_select_interaction_profile_dialog.cpp +++ b/modules/openxr/editor/openxr_select_interaction_profile_dialog.cpp @@ -46,7 +46,7 @@ void OpenXRSelectInteractionProfileDialog::_notification(int p_what) { void OpenXRSelectInteractionProfileDialog::_on_select_interaction_profile(const String p_interaction_profile) { if (selected_interaction_profile != "") { NodePath button_path = ip_buttons[selected_interaction_profile]; - Button *button = static_cast<Button *>(get_node(button_path)); + Button *button = Object::cast_to<Button>(get_node(button_path)); if (button != nullptr) { button->set_flat(true); } @@ -56,7 +56,7 @@ void OpenXRSelectInteractionProfileDialog::_on_select_interaction_profile(const if (selected_interaction_profile != "") { NodePath button_path = ip_buttons[selected_interaction_profile]; - Button *button = static_cast<Button *>(get_node(button_path)); + Button *button = Object::cast_to<Button>(get_node(button_path)); if (button != nullptr) { button->set_flat(false); } |