feat: modules moved and engine moved to submodule

This commit is contained in:
Jan van der Weide 2025-04-12 18:40:44 +02:00
parent dfb5e645cd
commit c33d2130cc
5136 changed files with 225275 additions and 64485 deletions

View file

@ -66,7 +66,7 @@ void Collada::Vertex::fix_unit_scale(const Collada &p_state) {
static String _uri_to_id(const String &p_uri) {
if (p_uri.begins_with("#")) {
return p_uri.substr(1, p_uri.size() - 1);
return p_uri.substr(1);
} else {
return p_uri;
}
@ -208,7 +208,6 @@ Vector<float> Collada::AnimationTrack::get_value_at_time(float p_time) const {
Vector<float> ret;
ret.resize(16);
Transform3D tr;
// i wonder why collada matrices are transposed, given that's opposed to opengl..
ret.write[0] = interp.basis.rows[0][0];
ret.write[1] = interp.basis.rows[0][1];
@ -289,7 +288,7 @@ void Collada::_parse_image(XMLParser &p_parser) {
String path = p_parser.get_named_attribute_value("source").strip_edges();
if (!path.contains("://") && path.is_relative_path()) {
// path is relative to file being loaded, so convert to a resource path
image.path = ProjectSettings::get_singleton()->localize_path(state.local_path.get_base_dir().path_join(path.uri_decode()));
image.path = ProjectSettings::get_singleton()->localize_path(state.local_path.get_base_dir().path_join(path.uri_file_decode()));
}
} else {
while (p_parser.read() == OK) {
@ -298,7 +297,7 @@ void Collada::_parse_image(XMLParser &p_parser) {
if (name == "init_from") {
p_parser.read();
String path = p_parser.get_node_data().strip_edges().uri_decode();
String path = p_parser.get_node_data().strip_edges().uri_file_decode();
if (!path.contains("://") && path.is_relative_path()) {
// path is relative to file being loaded, so convert to a resource path
@ -1373,7 +1372,7 @@ Collada::Node *Collada::_parse_visual_instance_camera(XMLParser &p_parser) {
cam->camera = _uri_to_id(p_parser.get_named_attribute_value_safe("url"));
if (state.up_axis == Vector3::AXIS_Z) { //collada weirdness
cam->post_transform.basis.rotate(Vector3(1, 0, 0), -Math_PI * 0.5);
cam->post_transform.basis.rotate(Vector3(1, 0, 0), -Math::PI * 0.5);
}
if (p_parser.is_empty()) { //nothing else to parse...
@ -1394,7 +1393,7 @@ Collada::Node *Collada::_parse_visual_instance_light(XMLParser &p_parser) {
cam->light = _uri_to_id(p_parser.get_named_attribute_value_safe("url"));
if (state.up_axis == Vector3::AXIS_Z) { //collada weirdness
cam->post_transform.basis.rotate(Vector3(1, 0, 0), -Math_PI * 0.5);
cam->post_transform.basis.rotate(Vector3(1, 0, 0), -Math::PI * 0.5);
}
if (p_parser.is_empty()) { //nothing else to parse...
@ -1812,9 +1811,9 @@ void Collada::_parse_animation(XMLParser &p_parser) {
track.target = target.get_slicec('/', 0);
track.param = target.get_slicec('/', 1);
if (track.param.contains_char('.')) {
track.component = track.param.get_slice(".", 1).to_upper();
track.component = track.param.get_slicec('.', 1).to_upper();
}
track.param = track.param.get_slice(".", 0);
track.param = track.param.get_slicec('.', 0);
if (names.size() > 1 && track.component.is_empty()) {
//this is a guess because the collada spec is ambiguous here...
//i suppose if you have many names (outputs) you can't use a component and i should abide to that.
@ -2347,9 +2346,9 @@ Error Collada::load(const String &p_path, int p_flags) {
{
//version
String version = parser.get_named_attribute_value("version");
state.version.major = version.get_slice(".", 0).to_int();
state.version.minor = version.get_slice(".", 1).to_int();
state.version.rev = version.get_slice(".", 2).to_int();
state.version.major = version.get_slicec('.', 0).to_int();
state.version.minor = version.get_slicec('.', 1).to_int();
state.version.rev = version.get_slicec('.', 2).to_int();
COLLADA_PRINT("Collada VERSION: " + version);
}
@ -2379,6 +2378,3 @@ Error Collada::load(const String &p_path, int p_flags) {
_optimize();
return OK;
}
Collada::Collada() {
}

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef COLLADA_H
#define COLLADA_H
#pragma once
#include "core/io/xml_parser.h"
@ -57,7 +56,6 @@ public:
int uv_idx = 0;
String texture;
Color color;
Channel() {}
};
Channel diffuse, specular, emission, bump;
@ -117,8 +115,6 @@ public:
float spot_angle = 45;
float spot_exp = 1;
LightData() {}
};
struct MeshData {
@ -154,8 +150,6 @@ public:
bool found_double_sided = false;
bool double_sided = true;
MeshData() {}
};
struct CurveData {
@ -171,8 +165,6 @@ public:
HashMap<String, Source> sources;
HashMap<String, String> control_vertices;
CurveData() {}
};
struct SkinControllerData {
@ -185,7 +177,6 @@ public:
Vector<String> sarray; //maybe for names
Vector<float> array;
int stride = 1;
Source() {}
};
HashMap<String, Source> sources;
@ -208,8 +199,6 @@ public:
} weights;
HashMap<String, Transform3D> bone_rest_map;
SkinControllerData() {}
};
struct MorphControllerData {
@ -220,13 +209,11 @@ public:
int stride = 1;
Vector<String> sarray; //maybe for names
Vector<float> array;
Source() {}
};
HashMap<String, Source> sources;
HashMap<String, String> targets;
MorphControllerData() {}
};
struct Vertex {
@ -304,8 +291,6 @@ public:
return uid < p_vert.uid;
}
}
Vertex() {}
};
struct Node {
@ -351,7 +336,6 @@ public:
bool ignore_anim = false;
Node() {}
virtual ~Node() {
for (int i = 0; i < children.size(); i++) {
memdelete(children[i]);
@ -413,8 +397,6 @@ public:
float begin = 0;
float end = 1;
Vector<String> tracks;
AnimationClip() {}
};
struct AnimationTrack {
@ -440,15 +422,11 @@ public:
Point2 in_tangent;
Point2 out_tangent;
InterpolationType interp_type = INTERP_LINEAR;
Key() {}
};
Vector<float> get_value_at_time(float p_time) const;
Vector<Key> keys;
AnimationTrack() {}
};
/****************/
@ -506,14 +484,10 @@ public:
HashMap<String, Vector<int>> by_id_tracks;
float animation_length = 0;
State() {}
} state;
Error load(const String &p_path, int p_flags = 0);
Collada();
Transform3D fix_transform(const Transform3D &p_transform);
Transform3D get_root_transform() const;
@ -570,5 +544,3 @@ private: // private stuff
void _optimize();
};
#endif // COLLADA_H

View file

@ -706,7 +706,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ImporterMesh> &p
}
}
if (weights.size() == 0 || total == 0) { //if nothing, add a weight to bone 0
if (weights.is_empty() || total == 0) { //if nothing, add a weight to bone 0
//no weights assigned
Collada::Vertex::Weight w;
w.bone_idx = 0;
@ -1278,7 +1278,7 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
mesh_unique_names.insert(name);
mesh->set_name(name);
Error err = _create_mesh_surfaces(morphs.size() == 0, mesh, ng2->material_map, meshdata, apply_xform, bone_remap, skin, morph, morphs, p_use_compression, use_mesh_builtin_materials);
Error err = _create_mesh_surfaces(morphs.is_empty(), mesh, ng2->material_map, meshdata, apply_xform, bone_remap, skin, morph, morphs, p_use_compression, use_mesh_builtin_materials);
ERR_FAIL_COND_V_MSG(err, err, "Cannot create mesh surface.");
mesh_cache[meshid] = mesh;
@ -1642,22 +1642,22 @@ void ColladaImport::create_animation(int p_clip, bool p_import_value_tracks) {
}
for (int i = 0; i < snapshots.size(); i++) {
for (List<int>::Element *ET = nm.anim_tracks.front(); ET; ET = ET->next()) {
for (const int track_id : nm.anim_tracks) {
//apply tracks
if (p_clip == -1) {
if (track_filter.has(ET->get())) {
if (track_filter.has(track_id)) {
continue;
}
} else {
if (!track_filter.has(ET->get())) {
if (!track_filter.has(track_id)) {
continue;
}
}
found_anim = true;
const Collada::AnimationTrack &at = collada.state.animation_tracks[ET->get()];
const Collada::AnimationTrack &at = collada.state.animation_tracks[track_id];
int xform_idx = -1;
for (int j = 0; j < cn->xform_list.size(); j++) {
@ -1855,6 +1855,3 @@ Node *EditorSceneFormatImporterCollada::import_scene(const String &p_path, uint3
return state.scene;
}
EditorSceneFormatImporterCollada::EditorSceneFormatImporterCollada() {
}

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef EDITOR_IMPORT_COLLADA_H
#define EDITOR_IMPORT_COLLADA_H
#pragma once
#include "editor/import/3d/resource_importer_scene.h"
@ -39,8 +38,4 @@ class EditorSceneFormatImporterCollada : public EditorSceneFormatImporter {
public:
virtual void get_extensions(List<String> *r_extensions) const override;
virtual Node *import_scene(const String &p_path, uint32_t p_flags, const HashMap<StringName, Variant> &p_options, List<String> *r_missing_deps = nullptr, Error *r_err = nullptr) override;
EditorSceneFormatImporterCollada();
};
#endif // EDITOR_IMPORT_COLLADA_H

View file

@ -245,6 +245,3 @@ void PostImportPluginSkeletonRenamer::internal_process(InternalImportCategory p_
}
}
}
PostImportPluginSkeletonRenamer::PostImportPluginSkeletonRenamer() {
}

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef POST_IMPORT_PLUGIN_SKELETON_RENAMER_H
#define POST_IMPORT_PLUGIN_SKELETON_RENAMER_H
#pragma once
#include "resource_importer_scene.h"
@ -41,8 +40,4 @@ public:
virtual void internal_process(InternalImportCategory p_category, Node *p_base_scene, Node *p_node, Ref<Resource> p_resource, const Dictionary &p_options) override;
void _internal_process(InternalImportCategory p_category, Node *p_base_scene, Node *p_node, Ref<Resource> p_resource, const Dictionary &p_options, const HashMap<String, String> &p_rename_map);
PostImportPluginSkeletonRenamer();
};
#endif // POST_IMPORT_PLUGIN_SKELETON_RENAMER_H

View file

@ -972,6 +972,3 @@ void PostImportPluginSkeletonRestFixer::internal_process(InternalImportCategory
memdelete(prof_skeleton);
}
}
PostImportPluginSkeletonRestFixer::PostImportPluginSkeletonRestFixer() {
}

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef POST_IMPORT_PLUGIN_SKELETON_REST_FIXER_H
#define POST_IMPORT_PLUGIN_SKELETON_REST_FIXER_H
#pragma once
#include "resource_importer_scene.h"
@ -40,8 +39,4 @@ public:
virtual void get_internal_import_options(InternalImportCategory p_category, List<ResourceImporter::ImportOption> *r_options) override;
virtual Variant get_internal_option_visibility(InternalImportCategory p_category, const String &p_scene_import_type, const String &p_option, const HashMap<StringName, Variant> &p_options) const override;
virtual void internal_process(InternalImportCategory p_category, Node *p_base_scene, Node *p_node, Ref<Resource> p_resource, const Dictionary &p_options) override;
PostImportPluginSkeletonRestFixer();
};
#endif // POST_IMPORT_PLUGIN_SKELETON_REST_FIXER_H

View file

@ -153,6 +153,3 @@ void PostImportPluginSkeletonTrackOrganizer::internal_process(InternalImportCate
}
}
}
PostImportPluginSkeletonTrackOrganizer::PostImportPluginSkeletonTrackOrganizer() {
}

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef POST_IMPORT_PLUGIN_SKELETON_TRACK_ORGANIZER_H
#define POST_IMPORT_PLUGIN_SKELETON_TRACK_ORGANIZER_H
#pragma once
#include "resource_importer_scene.h"
@ -39,8 +38,4 @@ class PostImportPluginSkeletonTrackOrganizer : public EditorScenePostImportPlugi
public:
virtual void get_internal_import_options(InternalImportCategory p_category, List<ResourceImporter::ImportOption> *r_options) override;
virtual void internal_process(InternalImportCategory p_category, Node *p_base_scene, Node *p_node, Ref<Resource> p_resource, const Dictionary &p_options) override;
PostImportPluginSkeletonTrackOrganizer();
};
#endif // POST_IMPORT_PLUGIN_SKELETON_TRACK_ORGANIZER_H

View file

@ -119,7 +119,7 @@ static Error _parse_material_library(const String &p_path, HashMap<String, Ref<S
//normal
ERR_FAIL_COND_V(current.is_null(), ERR_FILE_CORRUPT);
String p = l.replace("map_Kd", "").replace("\\", "/").strip_edges();
String p = l.replace("map_Kd", "").replace_char('\\', '/').strip_edges();
String path;
if (p.is_absolute_path()) {
path = p;
@ -139,7 +139,7 @@ static Error _parse_material_library(const String &p_path, HashMap<String, Ref<S
//normal
ERR_FAIL_COND_V(current.is_null(), ERR_FILE_CORRUPT);
String p = l.replace("map_Ks", "").replace("\\", "/").strip_edges();
String p = l.replace("map_Ks", "").replace_char('\\', '/').strip_edges();
String path;
if (p.is_absolute_path()) {
path = p;
@ -159,7 +159,7 @@ static Error _parse_material_library(const String &p_path, HashMap<String, Ref<S
//normal
ERR_FAIL_COND_V(current.is_null(), ERR_FILE_CORRUPT);
String p = l.replace("map_Ns", "").replace("\\", "/").strip_edges();
String p = l.replace("map_Ns", "").replace_char('\\', '/').strip_edges();
String path;
if (p.is_absolute_path()) {
path = p;
@ -178,7 +178,7 @@ static Error _parse_material_library(const String &p_path, HashMap<String, Ref<S
//normal
ERR_FAIL_COND_V(current.is_null(), ERR_FILE_CORRUPT);
String p = l.replace("map_bump", "").replace("\\", "/").strip_edges();
String p = l.replace("map_bump", "").replace_char('\\', '/').strip_edges();
String path = base_path.path_join(p);
Ref<Texture2D> texture = ResourceLoader::load(path);
@ -365,7 +365,7 @@ static Error _parse_obj(const String &p_path, List<Ref<ImporterMesh>> &r_meshes,
face[1] = face[2];
}
} else if (l.begins_with("s ")) { //smoothing
String what = l.substr(2, l.length()).strip_edges();
String what = l.substr(2).strip_edges();
bool do_smooth;
if (what == "off") {
do_smooth = false;
@ -402,7 +402,7 @@ static Error _parse_obj(const String &p_path, List<Ref<ImporterMesh>> &r_meshes,
//groups are too annoying
if (surf_tool->get_vertex_array().size()) {
//another group going on, commit it
if (normals.size() == 0) {
if (normals.is_empty()) {
surf_tool->generate_normals();
}
@ -476,7 +476,7 @@ static Error _parse_obj(const String &p_path, List<Ref<ImporterMesh>> &r_meshes,
}
if (l.begins_with("o ")) {
name = l.substr(2, l.length()).strip_edges();
name = l.substr(2).strip_edges();
}
if (l.begins_with("usemtl ")) {
@ -484,7 +484,7 @@ static Error _parse_obj(const String &p_path, List<Ref<ImporterMesh>> &r_meshes,
}
if (l.begins_with("g ")) {
current_group = l.substr(2, l.length()).strip_edges();
current_group = l.substr(2).strip_edges();
}
} else if (l.begins_with("mtllib ")) { //parse material
@ -584,9 +584,6 @@ void EditorOBJImporter::get_extensions(List<String> *r_extensions) const {
r_extensions->push_back("obj");
}
EditorOBJImporter::EditorOBJImporter() {
}
////////////////////////////////////////////////////
String ResourceImporterOBJ::get_importer_name() const {
@ -682,6 +679,3 @@ Error ResourceImporterOBJ::import(ResourceUID::ID p_source_id, const String &p_s
return OK;
}
ResourceImporterOBJ::ResourceImporterOBJ() {
}

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef RESOURCE_IMPORTER_OBJ_H
#define RESOURCE_IMPORTER_OBJ_H
#pragma once
#include "resource_importer_scene.h"
@ -39,8 +38,6 @@ class EditorOBJImporter : public EditorSceneFormatImporter {
public:
virtual void get_extensions(List<String> *r_extensions) const override;
virtual Node *import_scene(const String &p_path, uint32_t p_flags, const HashMap<StringName, Variant> &p_options, List<String> *r_missing_deps, Error *r_err = nullptr) override;
EditorOBJImporter();
};
class ResourceImporterOBJ : public ResourceImporter {
@ -61,8 +58,4 @@ public:
virtual bool get_option_visibility(const String &p_path, const String &p_option, const HashMap<StringName, Variant> &p_options) const override;
virtual Error import(ResourceUID::ID p_source_id, const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) override;
ResourceImporterOBJ();
};
#endif // RESOURCE_IMPORTER_OBJ_H

View file

@ -40,7 +40,7 @@
#include "editor/import/3d/scene_import_settings.h"
#include "scene/3d/importer_mesh_instance_3d.h"
#include "scene/3d/mesh_instance_3d.h"
#include "scene/3d/navigation_region_3d.h"
#include "scene/3d/navigation/navigation_region_3d.h"
#include "scene/3d/occluder_instance_3d.h"
#include "scene/3d/physics/area_3d.h"
#include "scene/3d/physics/collision_shape_3d.h"
@ -146,9 +146,6 @@ void EditorScenePostImport::init(const String &p_source_file) {
source_file = p_source_file;
}
EditorScenePostImport::EditorScenePostImport() {
}
///////////////////////////////////////////////////////
Variant EditorScenePostImportPlugin::get_option_value(const StringName &p_name) const {
@ -435,7 +432,7 @@ static String _fixstr(const String &p_what, const String &p_str) {
what = what.substr(0, what.length() - 1);
}
String end = p_what.substr(what.length(), p_what.length() - what.length());
String end = p_what.substr(what.length());
if (what.containsn("$" + p_str)) { // Blender and other stuff.
return what.replace("$" + p_str, "") + end;
@ -829,7 +826,7 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, HashMap<R
SeparationRayShape3D *rayShape = memnew(SeparationRayShape3D);
rayShape->set_length(1);
colshape->set_shape(rayShape);
Object::cast_to<Node3D>(sb)->rotate_x(Math_PI / 2);
Object::cast_to<Node3D>(sb)->rotate_x(Math::PI / 2);
} else if (empty_draw_type == "IMAGE") {
WorldBoundaryShape3D *world_boundary_shape = memnew(WorldBoundaryShape3D);
colshape->set_shape(world_boundary_shape);
@ -1306,9 +1303,9 @@ Node *ResourceImporterScene::_post_fix_animations(Node *p_node, Node *p_root, co
Dictionary anim_settings = p_animation_data[name];
{
int slices_count = anim_settings["slices/amount"];
int slice_count = anim_settings["slices/amount"];
for (int i = 0; i < slices_count; i++) {
for (int i = 0; i < slice_count; i++) {
String slice_name = anim_settings["slice_" + itos(i + 1) + "/name"];
int from_frame = anim_settings["slice_" + itos(i + 1) + "/start_frame"];
int end_frame = anim_settings["slice_" + itos(i + 1) + "/end_frame"];
@ -1534,8 +1531,26 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, HashMap<
if (matdata.has("use_external/enabled") && bool(matdata["use_external/enabled"]) && matdata.has("use_external/path")) {
String path = matdata["use_external/path"];
Ref<Material> external_mat = ResourceLoader::load(path);
if (external_mat.is_null()) {
if (matdata.has("use_external/fallback_path")) {
String fallback_save_path = matdata["use_external/fallback_path"];
if (!fallback_save_path.is_empty()) {
external_mat = ResourceLoader::load(fallback_save_path);
if (external_mat.is_valid()) {
path = fallback_save_path;
}
}
}
}
if (external_mat.is_valid()) {
m->set_surface_material(i, external_mat);
if (!path.begins_with("uid://")) {
const ResourceUID::ID id = ResourceLoader::get_resource_uid(path);
if (id != ResourceUID::INVALID_ID) {
matdata["use_external/path"] = ResourceUID::get_singleton()->id_to_text(id);
}
}
matdata["use_external/fallback_path"] = external_mat->get_path();
}
}
}
@ -1787,13 +1802,14 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, HashMap<
}
Ref<Animation> ResourceImporterScene::_save_animation_to_file(Ref<Animation> anim, bool p_save_to_file, const String &p_save_to_path, bool p_keep_custom_tracks) {
if (!p_save_to_file || !p_save_to_path.is_resource_file()) {
String res_path = ResourceUID::ensure_path(p_save_to_path);
if (!p_save_to_file || !res_path.is_resource_file()) {
return anim;
}
if (FileAccess::exists(p_save_to_path) && p_keep_custom_tracks) {
if (FileAccess::exists(res_path) && p_keep_custom_tracks) {
// Copy custom animation tracks from previously imported files.
Ref<Animation> old_anim = ResourceLoader::load(p_save_to_path, "Animation", ResourceFormatLoader::CACHE_MODE_IGNORE);
Ref<Animation> old_anim = ResourceLoader::load(res_path, "Animation", ResourceFormatLoader::CACHE_MODE_IGNORE);
if (old_anim.is_valid()) {
for (int i = 0; i < old_anim->get_track_count(); i++) {
if (!old_anim->track_is_imported(i)) {
@ -1804,16 +1820,21 @@ Ref<Animation> ResourceImporterScene::_save_animation_to_file(Ref<Animation> ani
}
}
if (ResourceCache::has(p_save_to_path)) {
Ref<Animation> old_anim = ResourceCache::get_ref(p_save_to_path);
if (ResourceCache::has(res_path)) {
Ref<Animation> old_anim = ResourceCache::get_ref(res_path);
if (old_anim.is_valid()) {
old_anim->copy_from(anim);
anim = old_anim;
}
}
anim->set_path(p_save_to_path, true); // Set path to save externally.
Error err = ResourceSaver::save(anim, p_save_to_path, ResourceSaver::FLAG_CHANGE_PATH);
ERR_FAIL_COND_V_MSG(err != OK, anim, "Saving of animation failed: " + p_save_to_path);
anim->set_path(res_path, true); // Set path to save externally.
Error err = ResourceSaver::save(anim, res_path, ResourceSaver::FLAG_CHANGE_PATH);
ERR_FAIL_COND_V_MSG(err != OK, anim, "Saving of animation failed: " + res_path);
if (p_save_to_path.begins_with("uid://")) {
// slow
ResourceSaver::set_uid(res_path, ResourceUID::get_singleton()->text_to_id(p_save_to_path));
}
return anim;
}
@ -2044,6 +2065,7 @@ void ResourceImporterScene::get_internal_import_options(InternalImportCategory p
case INTERNAL_IMPORT_CATEGORY_MESH: {
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "save_to_file/enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "save_to_file/path", PROPERTY_HINT_SAVE_FILE, "*.res,*.tres"), ""));
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "save_to_file/fallback_path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), ""));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "generate/shadow_meshes", PROPERTY_HINT_ENUM, "Default,Enable,Disable"), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "generate/lightmap_uv", PROPERTY_HINT_ENUM, "Default,Enable,Disable"), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "generate/lods", PROPERTY_HINT_ENUM, "Default,Enable,Disable"), 0));
@ -2052,11 +2074,13 @@ void ResourceImporterScene::get_internal_import_options(InternalImportCategory p
case INTERNAL_IMPORT_CATEGORY_MATERIAL: {
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "use_external/enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "use_external/path", PROPERTY_HINT_FILE, "*.material,*.res,*.tres"), ""));
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "use_external/fallback_path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), ""));
} break;
case INTERNAL_IMPORT_CATEGORY_ANIMATION: {
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "settings/loop_mode", PROPERTY_HINT_ENUM, "None,Linear,Pingpong"), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "save_to_file/enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "save_to_file/path", PROPERTY_HINT_SAVE_FILE, "*.res,*.tres"), ""));
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "save_to_file/path", PROPERTY_HINT_SAVE_FILE, "*.res,*.anim,*.tres"), ""));
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "save_to_file/fallback_path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), ""));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "save_to_file/keep_custom_tracks"), ""));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slices/amount", PROPERTY_HINT_RANGE, "0,256,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 0));
@ -2066,7 +2090,8 @@ void ResourceImporterScene::get_internal_import_options(InternalImportCategory p
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slice_" + itos(i + 1) + "/end_frame"), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slice_" + itos(i + 1) + "/loop_mode", PROPERTY_HINT_ENUM, "None,Linear,Pingpong"), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "slice_" + itos(i + 1) + "/save_to_file/enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "slice_" + itos(i + 1) + "/save_to_file/path", PROPERTY_HINT_SAVE_FILE, ".res,*.tres"), ""));
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "slice_" + itos(i + 1) + "/save_to_file/path", PROPERTY_HINT_SAVE_FILE, "*.res,*.anim,*.tres"), ""));
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "slice_" + itos(i + 1) + "/save_to_file/fallback_path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), ""));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "slice_" + itos(i + 1) + "/save_to_file/keep_custom_tracks"), false));
}
} break;
@ -2211,7 +2236,7 @@ bool ResourceImporterScene::get_internal_option_visibility(InternalImportCategor
}
if (p_option.begins_with("slice_")) {
int max_slice = p_options["slices/amount"];
int slice = p_option.get_slice("_", 1).to_int() - 1;
int slice = p_option.get_slicec('_', 1).to_int() - 1;
if (slice >= max_slice) {
return false;
}
@ -2530,7 +2555,7 @@ Node *ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_
if (bool(mesh_settings.get("save_to_file/enabled", false))) {
save_to_file = mesh_settings.get("save_to_file/path", String());
if (!save_to_file.is_resource_file()) {
if (!ResourceUID::ensure_path(save_to_file).is_resource_file()) {
save_to_file = "";
}
}
@ -2584,16 +2609,24 @@ Node *ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_
src_mesh_node->get_mesh()->optimize_indices();
if (!save_to_file.is_empty()) {
Ref<Mesh> existing = ResourceCache::get_ref(save_to_file);
String save_res_path = ResourceUID::ensure_path(save_to_file);
Ref<Mesh> existing = ResourceCache::get_ref(save_res_path);
if (existing.is_valid()) {
//if somehow an existing one is useful, create
existing->reset_state();
}
mesh = src_mesh_node->get_mesh()->get_mesh(existing);
ResourceSaver::save(mesh, save_to_file); //override
Error err = ResourceSaver::save(mesh, save_res_path); //override
if (err != OK) {
WARN_PRINT(vformat("Failed to save mesh %s to '%s'.", mesh->get_name(), save_res_path));
}
if (err == OK && save_to_file.begins_with("uid://")) {
// slow
ResourceSaver::set_uid(save_res_path, ResourceUID::get_singleton()->text_to_id(save_to_file));
}
mesh->set_path(save_to_file, true); //takeover existing, if needed
mesh->set_path(save_res_path, true); //takeover existing, if needed
} else {
mesh = src_mesh_node->get_mesh()->get_mesh();
@ -2871,14 +2904,65 @@ Node *ResourceImporterScene::pre_import(const String &p_source_file, const HashM
return scene;
}
Error ResourceImporterScene::_check_resource_save_paths(const Dictionary &p_data) {
Array keys = p_data.keys();
for (int i = 0; i < keys.size(); i++) {
const Dictionary &settings = p_data[keys[i]];
static Error convert_path_to_uid(ResourceUID::ID p_source_id, const String &p_hash_str, Dictionary &p_settings, const String &p_path_key, const String &p_fallback_path_key) {
const String &raw_save_path = p_settings[p_path_key];
String save_path = ResourceUID::ensure_path(raw_save_path);
if (raw_save_path.begins_with("uid://")) {
if (save_path.is_empty() || !DirAccess::exists(save_path.get_base_dir())) {
if (p_settings.has(p_fallback_path_key)) {
String fallback_save_path = p_settings[p_fallback_path_key];
if (!fallback_save_path.is_empty() && DirAccess::exists(fallback_save_path.get_base_dir())) {
save_path = fallback_save_path;
ResourceUID::get_singleton()->add_id(ResourceUID::get_singleton()->text_to_id(raw_save_path), save_path);
}
}
} else {
p_settings[p_fallback_path_key] = save_path;
}
}
ERR_FAIL_COND_V(!save_path.is_empty() && !DirAccess::exists(save_path.get_base_dir()), ERR_FILE_BAD_PATH);
if (!save_path.is_empty() && !raw_save_path.begins_with("uid://")) {
const ResourceUID::ID id = ResourceLoader::get_resource_uid(save_path);
if (id != ResourceUID::INVALID_ID) {
p_settings[p_path_key] = ResourceUID::get_singleton()->id_to_text(id);
} else {
ResourceUID::ID save_id = hash64_murmur3_64(p_hash_str.hash64(), p_source_id) & 0x7FFFFFFFFFFFFFFF;
if (ResourceUID::get_singleton()->has_id(save_id)) {
if (save_path != ResourceUID::get_singleton()->get_id_path(save_id)) {
// The user has specified a path which does not match the default UID.
save_id = ResourceUID::get_singleton()->create_id_for_path(save_path);
}
}
p_settings[p_path_key] = ResourceUID::get_singleton()->id_to_text(save_id);
ResourceUID::get_singleton()->add_id(save_id, save_path);
}
p_settings[p_fallback_path_key] = save_path;
}
return OK;
}
Error ResourceImporterScene::_check_resource_save_paths(ResourceUID::ID p_source_id, const String &p_hash_suffix, const Dictionary &p_data) {
for (const KeyValue<Variant, Variant> &kv : p_data) {
Dictionary settings = kv.value;
if (bool(settings.get("save_to_file/enabled", false)) && settings.has("save_to_file/path")) {
const String save_path = ResourceUID::ensure_path(settings["save_to_file/path"]);
ERR_FAIL_COND_V(!save_path.is_empty() && !DirAccess::exists(save_path.get_base_dir()), ERR_FILE_BAD_PATH);
String to_hash = kv.key.operator String() + p_hash_suffix;
Error ret = convert_path_to_uid(p_source_id, to_hash, settings, "save_to_file/path", "save_to_file/fallback_path");
ERR_FAIL_COND_V_MSG(ret != OK, ret, vformat("Resource save path %s not valid. Ensure parent directory has been created.", settings.has("save_to_file/path")));
}
if (settings.has("slices/amount")) {
int slice_count = settings["slices/amount"];
for (int si = 0; si < slice_count; si++) {
if (bool(settings.get("slice_" + itos(si + 1) + "/save_to_file/enabled", false)) &&
settings.has("slice_" + itos(si + 1) + "/save_to_file/path")) {
String to_hash = kv.key.operator String() + p_hash_suffix + itos(si + 1);
Error ret = convert_path_to_uid(p_source_id, to_hash, settings,
"slice_" + itos(si + 1) + "/save_to_file/path",
"slice_" + itos(si + 1) + "/save_to_file/fallback_path");
ERR_FAIL_COND_V_MSG(ret != OK, ret, vformat("Slice save path %s not valid. Ensure parent directory has been created.", settings.has("save_to_file/path")));
}
}
}
}
@ -2943,14 +3027,14 @@ Error ResourceImporterScene::import(ResourceUID::ID p_source_id, const String &p
// Check whether any of the meshes or animations have nonexistent save paths
// and if they do, fail the import immediately.
if (subresources.has("meshes")) {
err = _check_resource_save_paths(subresources["meshes"]);
err = _check_resource_save_paths(p_source_id, "m", subresources["meshes"]);
if (err != OK) {
return err;
}
}
if (subresources.has("animations")) {
err = _check_resource_save_paths(subresources["animations"]);
err = _check_resource_save_paths(p_source_id, "a", subresources["animations"]);
if (err != OK) {
return err;
}

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef RESOURCE_IMPORTER_SCENE_H
#define RESOURCE_IMPORTER_SCENE_H
#pragma once
#include "core/error/error_macros.h"
#include "core/io/resource_importer.h"
@ -81,8 +80,6 @@ public:
virtual void get_import_options(const String &p_path, List<ResourceImporter::ImportOption> *r_options);
virtual Variant get_option_visibility(const String &p_path, const String &p_scene_import_type, const String &p_option, const HashMap<StringName, Variant> &p_options);
virtual void handle_compatibility_options(HashMap<StringName, Variant> &p_import_params) const {}
EditorSceneFormatImporter() {}
};
class EditorScenePostImport : public RefCounted {
@ -99,7 +96,6 @@ public:
String get_source_file() const;
virtual Node *post_import(Node *p_scene);
virtual void init(const String &p_source_file);
EditorScenePostImport();
};
class EditorScenePostImportPlugin : public RefCounted {
@ -151,8 +147,6 @@ public:
virtual void pre_process(Node *p_scene, const HashMap<StringName, Variant> &p_options);
virtual void post_process(Node *p_scene, const HashMap<StringName, Variant> &p_options);
EditorScenePostImportPlugin() {}
};
VARIANT_ENUM_CAST(EditorScenePostImportPlugin::InternalImportCategory)
@ -216,7 +210,7 @@ class ResourceImporterScene : public ResourceImporter {
SHAPE_TYPE_AUTOMATIC,
};
static Error _check_resource_save_paths(const Dictionary &p_data);
static Error _check_resource_save_paths(ResourceUID::ID p_source_id, const String &p_hash_suffix, const Dictionary &p_data);
Array _get_skinned_pose_transforms(ImporterMeshInstance3D *p_src_mesh_node);
void _replace_owner(Node *p_node, Node *p_scene, Node *p_new_owner);
Node *_generate_meshes(Node *p_node, const Dictionary &p_mesh_data, bool p_generate_lods, bool p_create_shadow_meshes, LightBakeMode p_light_bake_mode, float p_lightmap_texel_size, const Vector<uint8_t> &p_src_lightmap_cache, Vector<Vector<uint8_t>> &r_lightmap_caches);
@ -518,10 +512,8 @@ Transform3D ResourceImporterScene::get_collision_shapes_transform(const M &p_opt
}
if (p_options.has(SNAME("primitive/rotation"))) {
transform.basis = Basis::from_euler(p_options[SNAME("primitive/rotation")].operator Vector3() * (Math_PI / 180.0));
transform.basis = Basis::from_euler(p_options[SNAME("primitive/rotation")].operator Vector3() * (Math::PI / 180.0));
}
}
return transform;
}
#endif // RESOURCE_IMPORTER_SCENE_H

View file

@ -744,8 +744,8 @@ void SceneImportSettingsDialog::open_settings(const String &p_path, const String
selected_id = "";
selected_type = "";
cam_rot_x = -Math_PI / 4;
cam_rot_y = -Math_PI / 4;
cam_rot_x = -Math::PI / 4;
cam_rot_y = -Math::PI / 4;
cam_zoom = 1;
{
@ -1204,7 +1204,7 @@ void SceneImportSettingsDialog::_viewport_input(const Ref<InputEvent> &p_input)
if (mm.is_valid() && (mm->get_button_mask().has_flag(MouseButtonMask::LEFT))) {
(*rot_x) -= mm->get_relative().y * 0.01 * EDSCALE;
(*rot_y) -= mm->get_relative().x * 0.01 * EDSCALE;
(*rot_x) = CLAMP((*rot_x), -Math_PI / 2, Math_PI / 2);
(*rot_x) = CLAMP((*rot_x), -Math::PI / 2, Math::PI / 2);
_update_camera();
}
if (mm.is_valid() && DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_CURSOR_SHAPE)) {
@ -1585,6 +1585,10 @@ void SceneImportSettingsDialog::_save_dir_confirm() {
continue; //ignore
}
String path = item->get_text(1);
String uid_path = path;
if (path.begins_with("uid://")) {
path = ResourceUID::uid_to_path(uid_path);
}
if (!path.is_resource_file()) {
continue;
}
@ -1601,9 +1605,11 @@ void SceneImportSettingsDialog::_save_dir_confirm() {
EditorNode::get_singleton()->add_io_error(TTR("Can't make material external to file, write error:") + "\n\t" + path);
continue;
}
uid_path = ResourceUID::path_to_uid(path);
md.settings["use_external/enabled"] = true;
md.settings["use_external/path"] = path;
md.settings["use_external/path"] = uid_path;
md.settings["use_external/fallback_path"] = path;
} break;
case ACTION_CHOOSE_MESH_SAVE_PATHS: {
@ -1611,14 +1617,16 @@ void SceneImportSettingsDialog::_save_dir_confirm() {
MeshData &md = mesh_map[id];
md.settings["save_to_file/enabled"] = true;
md.settings["save_to_file/path"] = path;
md.settings["save_to_file/path"] = uid_path;
md.settings["save_to_file/fallback_path"] = path;
} break;
case ACTION_CHOOSE_ANIMATION_SAVE_PATHS: {
ERR_CONTINUE(!animation_map.has(id));
AnimationData &ad = animation_map[id];
ad.settings["save_to_file/enabled"] = true;
ad.settings["save_to_file/path"] = path;
ad.settings["save_to_file/path"] = uid_path;
ad.settings["save_to_file/fallback_path"] = path;
} break;
}
@ -1716,6 +1724,7 @@ SceneImportSettingsDialog::SceneImportSettingsDialog() {
animation_play_button = memnew(Button);
animation_hbox->add_child(animation_play_button);
animation_play_button->set_flat(true);
animation_play_button->set_accessibility_name(TTRC("Play"));
animation_play_button->set_focus_mode(Control::FOCUS_NONE);
animation_play_button->set_shortcut(ED_SHORTCUT("scene_import_settings/play_selected_animation", TTRC("Selected Animation Play/Pause"), Key::SPACE));
animation_play_button->connect(SceneStringName(pressed), callable_mp(this, &SceneImportSettingsDialog::_play_animation));
@ -1723,6 +1732,7 @@ SceneImportSettingsDialog::SceneImportSettingsDialog() {
animation_stop_button = memnew(Button);
animation_hbox->add_child(animation_stop_button);
animation_stop_button->set_flat(true);
animation_stop_button->set_accessibility_name(TTRC("Stop"));
animation_stop_button->set_focus_mode(Control::FOCUS_NONE);
animation_stop_button->set_tooltip_text(TTR("Selected Animation Stop"));
animation_stop_button->connect(SceneStringName(pressed), callable_mp(this, &SceneImportSettingsDialog::_stop_current_animation));
@ -1735,6 +1745,7 @@ SceneImportSettingsDialog::SceneImportSettingsDialog() {
animation_slider->set_step(1.0 / 100.0);
animation_slider->set_value_no_signal(0.0);
animation_slider->set_focus_mode(Control::FOCUS_NONE);
animation_slider->set_accessibility_name(TTRC("Animation"));
animation_slider->connect(SceneStringName(value_changed), callable_mp(this, &SceneImportSettingsDialog::_animation_slider_value_changed));
animation_toggle_skeleton_visibility = memnew(Button);
@ -1743,6 +1754,7 @@ SceneImportSettingsDialog::SceneImportSettingsDialog() {
animation_toggle_skeleton_visibility->set_theme_type_variation("FlatButton");
animation_toggle_skeleton_visibility->set_focus_mode(Control::FOCUS_NONE);
animation_toggle_skeleton_visibility->set_tooltip_text(TTR("Toggle Animation Skeleton Visibility"));
animation_toggle_skeleton_visibility->set_accessibility_name(TTRC("Skeleton Visibility"));
animation_toggle_skeleton_visibility->connect(SceneStringName(pressed), callable_mp(this, &SceneImportSettingsDialog::_animation_update_skeleton_visibility));
@ -1763,6 +1775,7 @@ SceneImportSettingsDialog::SceneImportSettingsDialog() {
light_rotate_switch->set_toggle_mode(true);
light_rotate_switch->set_pressed(true);
light_rotate_switch->set_tooltip_text(TTR("Rotate Lights With Model"));
light_rotate_switch->set_accessibility_name(TTRC("Rotate Lights With Model"));
light_rotate_switch->connect(SceneStringName(pressed), callable_mp(this, &SceneImportSettingsDialog::_on_light_rotate_switch_pressed));
vb_light->add_child(light_rotate_switch);
@ -1771,6 +1784,7 @@ SceneImportSettingsDialog::SceneImportSettingsDialog() {
light_1_switch->set_toggle_mode(true);
light_1_switch->set_pressed(true);
light_1_switch->set_tooltip_text(TTR("Primary Light"));
light_1_switch->set_accessibility_name(TTRC("Primary Light"));
light_1_switch->connect(SceneStringName(pressed), callable_mp(this, &SceneImportSettingsDialog::_on_light_1_switch_pressed));
vb_light->add_child(light_1_switch);
@ -1779,6 +1793,7 @@ SceneImportSettingsDialog::SceneImportSettingsDialog() {
light_2_switch->set_toggle_mode(true);
light_2_switch->set_pressed(true);
light_2_switch->set_tooltip_text(TTR("Secondary Light"));
light_2_switch->set_accessibility_name(TTRC("Secondary Light"));
light_2_switch->connect(SceneStringName(pressed), callable_mp(this, &SceneImportSettingsDialog::_on_light_2_switch_pressed));
vb_light->add_child(light_2_switch);
@ -1883,6 +1898,9 @@ SceneImportSettingsDialog::SceneImportSettingsDialog() {
inspector = memnew(EditorInspector);
inspector->set_custom_minimum_size(Size2(300 * EDSCALE, 0));
inspector->connect(SNAME("property_edited"), callable_mp(this, &SceneImportSettingsDialog::_inspector_property_edited));
// Display the same tooltips as in the Import dock.
inspector->set_object_class(ResourceImporterScene::get_class_static());
inspector->set_use_doc_hints(true);
property_split->add_child(inspector);

View file

@ -28,8 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef SCENE_IMPORT_SETTINGS_H
#define SCENE_IMPORT_SETTINGS_H
#pragma once
#include "editor/import/3d/resource_importer_scene.h"
#include "scene/3d/camera_3d.h"
@ -129,8 +128,8 @@ class SceneImportSettingsDialog : public ConfirmationDialog {
TreeItem *mesh_node = nullptr;
TreeItem *material_node = nullptr;
float cam_rot_x = -Math_PI / 4;
float cam_rot_y = -Math_PI / 4;
float cam_rot_x = -Math::PI / 4;
float cam_rot_y = -Math::PI / 4;
float cam_zoom = 1;
HashMap<StringName, Variant> settings;
@ -144,8 +143,8 @@ class SceneImportSettingsDialog : public ConfirmationDialog {
TreeItem *scene_node = nullptr;
TreeItem *mesh_node = nullptr;
float cam_rot_x = -Math_PI / 4;
float cam_rot_y = -Math_PI / 4;
float cam_rot_x = -Math::PI / 4;
float cam_rot_y = -Math::PI / 4;
float cam_zoom = 1;
HashMap<StringName, Variant> settings;
};
@ -251,5 +250,3 @@ public:
SceneImportSettingsDialog();
~SceneImportSettingsDialog();
};
#endif // SCENE_IMPORT_SETTINGS_H