diff options
author | Juan Linietsky <reduzio@gmail.com> | 2016-05-27 14:18:40 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2016-05-27 14:19:11 -0300 |
commit | 8be2fabbe5cd846bac5e5a38e55f3fb70e73f2da (patch) | |
tree | a3e932282cdafdd13c4f02bdf21f72f9846adcbe | |
parent | eb7227a20b27e91c6e2adfb1ded738f2dd7e453b (diff) |
Changed import workflow
-Rearrange favorites in fs dock with drag and drop
-Removed import -> sub-scene, moved to scenetree contextual menu
-Removed import -> re-import , moved and integrated to FS dock
-Added ability in FS dock to re-import more than one resource
simultaneously
-Added ability to drag from native filesystem explorer to Godot, only
works on Windows though
-Removed scene reimport merge options, never worked well. Eventually
merging materials should be re-added
-Added ability to set custom root node type when importing scenes
-Re-Import is now automatic, can be configured back to manual in editor
settings
-Added resource previews in property list for many resource types
54 files changed, 1258 insertions, 636 deletions
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index abb1082256..b547dc0e85 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -243,6 +243,7 @@ Ref<ResourceImportMetadata> ResourceLoader::load_import_metadata(const String &p break; } + return ret; } diff --git a/core/object.cpp b/core/object.cpp index 3cfc0329bc..d7878fd623 100644 --- a/core/object.cpp +++ b/core/object.cpp @@ -1756,6 +1756,7 @@ bool Object::is_queued_for_deletion() const { void Object::set_edited(bool p_edited) { _edited=p_edited; + _edited_version++; } bool Object::is_edited() const { @@ -1763,6 +1764,11 @@ bool Object::is_edited() const { return _edited; } + +uint32_t Object::get_edited_version() const { + + return _edited_version; +} #endif Object::Object() { @@ -1778,6 +1784,7 @@ Object::Object() { #ifdef TOOLS_ENABLED _edited=false; + _edited_version=0; #endif #ifdef DEBUG_ENABLED diff --git a/core/object.h b/core/object.h index 3945d1d0ba..4ed78d3226 100644 --- a/core/object.h +++ b/core/object.h @@ -388,6 +388,7 @@ friend void postinitialize_handler(Object*); bool _can_translate; #ifdef TOOLS_ENABLED bool _edited; + uint32_t _edited_version; #endif ScriptInstance *script_instance; RefPtr script; @@ -589,6 +590,7 @@ public: #ifdef TOOLS_ENABLED void set_edited(bool p_edited); bool is_edited() const; + uint32_t get_edited_version() const; //this function is used to check when something changed beyond a point, it's used mainly for generating previews #endif void set_script_instance(ScriptInstance *p_instance); diff --git a/core/os/main_loop.cpp b/core/os/main_loop.cpp index 310bbaa3b8..e5feebfbfc 100644 --- a/core/os/main_loop.cpp +++ b/core/os/main_loop.cpp @@ -43,6 +43,7 @@ void MainLoop::_bind_methods() { BIND_VMETHOD( MethodInfo("_initialize") ); BIND_VMETHOD( MethodInfo("_iteration",PropertyInfo(Variant::REAL,"delta")) ); BIND_VMETHOD( MethodInfo("_idle",PropertyInfo(Variant::REAL,"delta")) ); + BIND_VMETHOD( MethodInfo("_drop_files",PropertyInfo(Variant::STRING_ARRAY,"files"),PropertyInfo(Variant::INT,"screen")) ); BIND_VMETHOD( MethodInfo("_finalize") ); BIND_CONSTANT(NOTIFICATION_WM_MOUSE_ENTER); @@ -108,6 +109,15 @@ bool MainLoop::idle(float p_time) { return false; } + +void MainLoop::drop_files(const Vector<String>& p_files,int p_from_screen) { + + + if (get_script_instance()) + get_script_instance()->call("_drop_files",p_files,p_from_screen); + +} + void MainLoop::finish() { if (get_script_instance()) { diff --git a/core/os/main_loop.h b/core/os/main_loop.h index a34014983e..57185d9d3d 100644 --- a/core/os/main_loop.h +++ b/core/os/main_loop.h @@ -64,6 +64,8 @@ public: virtual bool idle(float p_time); virtual void finish(); + virtual void drop_files(const Vector<String>& p_files,int p_from_screen=0); + void set_init_script(const Ref<Script>& p_init_script); MainLoop(); diff --git a/core/resource.cpp b/core/resource.cpp index 672e64b1bb..b7a5bad4b8 100644 --- a/core/resource.cpp +++ b/core/resource.cpp @@ -330,6 +330,31 @@ Ref<ResourceImportMetadata> Resource::get_import_metadata() const { } +#ifdef TOOLS_ENABLED + +uint32_t Resource::hash_edited_version() const { + + uint32_t hash = hash_djb2_one_32(get_edited_version()); + + List<PropertyInfo> plist; + get_property_list(&plist); + + for (List<PropertyInfo>::Element *E=plist.front();E;E=E->next()) { + + if (E->get().type==Variant::OBJECT && E->get().hint==PROPERTY_HINT_RESOURCE_TYPE) { + RES res = get(E->get().name); + if (res.is_valid()) { + hash = hash_djb2_one_32(res->hash_edited_version(),hash); + } + } + } + + return hash; + +} + +#endif + Resource::Resource() { @@ -341,6 +366,8 @@ Resource::Resource() { } + + Resource::~Resource() { if (path_cache!="") diff --git a/core/resource.h b/core/resource.h index 8bcdd6b4b7..958414f62b 100644 --- a/core/resource.h +++ b/core/resource.h @@ -142,8 +142,12 @@ public: Ref<ResourceImportMetadata> get_import_metadata() const; + + #ifdef TOOLS_ENABLED + uint32_t hash_edited_version() const; + virtual void set_last_modified_time(uint64_t p_time) { last_modified_time=p_time; } uint64_t get_last_modified_time() const { return last_modified_time; } diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index c7b2d65a13..79465638d1 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -4737,10 +4737,10 @@ void RasterizerGLES2::_update_shader( Shader* p_shader) const { } -void RasterizerGLES2::_add_geometry( const Geometry* p_geometry, const InstanceData *p_instance, const Geometry *p_geometry_cmp, const GeometryOwner *p_owner) { +void RasterizerGLES2::_add_geometry( const Geometry* p_geometry, const InstanceData *p_instance, const Geometry *p_geometry_cmp, const GeometryOwner *p_owner,int p_material) { Material *m=NULL; - RID m_src=p_instance->material_override.is_valid() ? p_instance->material_override : p_geometry->material; + RID m_src=p_instance->material_override.is_valid() ? p_instance->material_override :(p_material>=0?p_instance->materials[p_material]:p_geometry->material); #ifdef DEBUG_ENABLED if (current_debug==VS::SCENARIO_DEBUG_OVERDRAW) { @@ -4988,8 +4988,9 @@ void RasterizerGLES2::add_mesh( const RID& p_mesh, const InstanceData *p_data) { for (int i=0;i<ssize;i++) { + int mat_idx = p_data->materials[i].is_valid() ? i : -1; Surface *s = mesh->surfaces[i]; - _add_geometry(s,p_data,s,NULL); + _add_geometry(s,p_data,s,NULL,mat_idx); } mesh->last_pass=frame; diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h index b52918c02f..35efedc9c8 100644 --- a/drivers/gles2/rasterizer_gles2.h +++ b/drivers/gles2/rasterizer_gles2.h @@ -1070,7 +1070,7 @@ class RasterizerGLES2 : public Rasterizer { Plane camera_plane; - void _add_geometry( const Geometry* p_geometry, const InstanceData *p_instance, const Geometry *p_geometry_cmp, const GeometryOwner *p_owner); + void _add_geometry( const Geometry* p_geometry, const InstanceData *p_instance, const Geometry *p_geometry_cmp, const GeometryOwner *p_owner,int p_material=-1); void _render_list_forward(RenderList *p_render_list,const Transform& p_view_transform,const Transform& p_view_transform_inverse, const CameraMatrix& p_projection,bool p_reverse_cull=false,bool p_fragment_light=false,bool p_alpha_pass=false); //void _setup_light(LightInstance* p_instance, int p_idx); diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index c9c7780a2a..bf8b0ee6b5 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -724,6 +724,32 @@ LRESULT OS_Windows::WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam) { } } break; + case WM_DROPFILES: { + + HDROP hDropInfo = NULL; + hDropInfo = (HDROP) wParam; + const int buffsize=4096; + wchar_t buf[buffsize]; + + int fcount = DragQueryFileW(hDropInfo, 0xFFFFFFFF,NULL,0); + + Vector<String> files; + + for(int i=0;i<fcount;i++) { + + DragQueryFileW(hDropInfo, i, buf, buffsize); + String file=buf; + files.push_back(file); + } + + if (files.size() && main_loop) { + main_loop->drop_files(files,0); + } + + + } break; + + default: { @@ -1035,6 +1061,8 @@ void OS_Windows::initialize(const VideoMode& p_desired,int p_video_driver,int p_ _ensure_data_dir(); + DragAcceptFiles(hWnd,true); + } diff --git a/scene/3d/mesh_instance.cpp b/scene/3d/mesh_instance.cpp index cfe273fa20..ef956e8ad9 100644 --- a/scene/3d/mesh_instance.cpp +++ b/scene/3d/mesh_instance.cpp @@ -31,8 +31,8 @@ #include "skeleton.h" #include "physics_body.h" #include "body_shape.h" - - +#include "scene/scene_string_names.h" +#include "core_string_names.h" bool MeshInstance::_set(const StringName& p_name, const Variant& p_value) { //this is not _too_ bad performance wise, really. it only arrives here if the property was not set anywhere else. @@ -43,13 +43,22 @@ bool MeshInstance::_set(const StringName& p_name, const Variant& p_value) { Map<StringName,MorphTrack>::Element *E = morph_tracks.find(p_name); - if (!E) - return false; + if (E) { + E->get().value=p_value; + VisualServer::get_singleton()->instance_set_morph_target_weight(get_instance(),E->get().idx,E->get().value); + return true; + } - E->get().value=p_value; - VisualServer::get_singleton()->instance_set_morph_target_weight(get_instance(),E->get().idx,E->get().value); + if (p_name.operator String().begins_with("material/")) { + int idx = p_name.operator String().get_slicec('/',1).to_int(); + if (idx>=materials.size() || idx<0) + return false; - return true; + set_surface_material(idx,p_value); + return true; + } + + return false; } bool MeshInstance::_get(const StringName& p_name,Variant &r_ret) const { @@ -59,12 +68,19 @@ bool MeshInstance::_get(const StringName& p_name,Variant &r_ret) const { return false; const Map<StringName,MorphTrack>::Element *E = morph_tracks.find(p_name); - if (!E) - return false; - - r_ret = E->get().value; + if (E) { + r_ret = E->get().value; + return true; + } - return true; + if (p_name.operator String().begins_with("material/")) { + int idx = p_name.operator String().get_slicec('/',1).to_int(); + if (idx>=materials.size() || idx<0) + return false; + r_ret=materials[idx]; + return true; + } + return false; } void MeshInstance::_get_property_list( List<PropertyInfo> *p_list) const { @@ -80,6 +96,12 @@ void MeshInstance::_get_property_list( List<PropertyInfo> *p_list) const { for(List<String>::Element *E=ls.front();E;E=E->next()) { p_list->push_back( PropertyInfo(Variant::REAL,E->get(),PROPERTY_HINT_RANGE,"0,1,0.01")); } + + if (mesh.is_valid()) { + for(int i=0;i<mesh->get_surface_count();i++) { + p_list->push_back( PropertyInfo(Variant::OBJECT, "material/"+itos(i), PROPERTY_HINT_RESOURCE_TYPE, "Material")); + } + } } @@ -87,6 +109,14 @@ void MeshInstance::_get_property_list( List<PropertyInfo> *p_list) const { void MeshInstance::set_mesh(const Ref<Mesh>& p_mesh) { + if (mesh==p_mesh) + return; + + if (mesh.is_valid()) { + mesh->disconnect(CoreStringNames::get_singleton()->changed,this,SceneStringNames::get_singleton()->_mesh_changed); + materials.clear(); + } + mesh=p_mesh; morph_tracks.clear(); @@ -100,13 +130,17 @@ void MeshInstance::set_mesh(const Ref<Mesh>& p_mesh) { mt.value=0; morph_tracks["morph/"+String(mesh->get_morph_target_name(i))]=mt; } + + mesh->connect(CoreStringNames::get_singleton()->changed,this,SceneStringNames::get_singleton()->_mesh_changed); + materials.resize(mesh->get_surface_count()); + set_base(mesh->get_rid()); } else { set_base(RID()); } - _change_notify("mesh"); + _change_notify(); } Ref<Mesh> MeshInstance::get_mesh() const { @@ -232,6 +266,32 @@ void MeshInstance::_notification(int p_what) { } +void MeshInstance::set_surface_material(int p_surface,const Ref<Material>& p_material) { + + ERR_FAIL_INDEX(p_surface,materials.size()); + + materials[p_surface]=p_material; + + if (materials[p_surface].is_valid()) + VS::get_singleton()->instance_set_surface_material(get_instance(),p_surface,materials[p_surface]->get_rid()); + else + VS::get_singleton()->instance_set_surface_material(get_instance(),p_surface,RID()); + +} + +Ref<Material> MeshInstance::get_surface_material(int p_surface) const { + + ERR_FAIL_INDEX_V(p_surface,materials.size(),Ref<Material>()); + + return materials[p_surface]; +} + + +void MeshInstance::_mesh_changed() { + + materials.resize( mesh->get_surface_count() ); +} + void MeshInstance::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_mesh","mesh:Mesh"),&MeshInstance::set_mesh); @@ -243,6 +303,7 @@ void MeshInstance::_bind_methods() { ObjectTypeDB::set_method_flags("MeshInstance","create_trimesh_collision",METHOD_FLAGS_DEFAULT); ObjectTypeDB::bind_method(_MD("create_convex_collision"),&MeshInstance::create_convex_collision); ObjectTypeDB::set_method_flags("MeshInstance","create_convex_collision",METHOD_FLAGS_DEFAULT); + ObjectTypeDB::bind_method(_MD("_mesh_changed"),&MeshInstance::_mesh_changed); ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "mesh/mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh" ), _SCS("set_mesh"), _SCS("get_mesh")); ADD_PROPERTY( PropertyInfo (Variant::NODE_PATH, "mesh/skeleton"), _SCS("set_skeleton_path"), _SCS("get_skeleton_path")); } diff --git a/scene/3d/mesh_instance.h b/scene/3d/mesh_instance.h index 7c605c2d6d..fd8faf38b4 100644 --- a/scene/3d/mesh_instance.h +++ b/scene/3d/mesh_instance.h @@ -50,7 +50,9 @@ class MeshInstance : public GeometryInstance { }; Map<StringName,MorphTrack> morph_tracks; + Vector<Ref<Material> > materials; + void _mesh_changed(); void _resolve_skeleton_path(); protected: @@ -69,6 +71,9 @@ public: void set_skeleton_path(const NodePath& p_skeleton); NodePath get_skeleton_path(); + void set_surface_material(int p_surface,const Ref<Material>& p_material); + Ref<Material> get_surface_material(int p_surface) const; + Node* create_trimesh_collision_node(); void create_trimesh_collision(); diff --git a/scene/main/scene_main_loop.cpp b/scene/main/scene_main_loop.cpp index 24fe1e1bb3..d7f22c3228 100644 --- a/scene/main/scene_main_loop.cpp +++ b/scene/main/scene_main_loop.cpp @@ -1593,6 +1593,14 @@ void SceneTree::_live_edit_reparent_node_func(const NodePath& p_at,const NodePat #endif + + +void SceneTree::drop_files(const Vector<String>& p_files,int p_from_screen) { + + emit_signal("files_dropped",p_files,p_from_screen); + MainLoop::drop_files(p_files,p_from_screen); +} + void SceneTree::_bind_methods() { @@ -1666,6 +1674,8 @@ void SceneTree::_bind_methods() { ADD_SIGNAL( MethodInfo("idle_frame")); ADD_SIGNAL( MethodInfo("fixed_frame")); + ADD_SIGNAL( MethodInfo("files_dropped",PropertyInfo(Variant::STRING_ARRAY,"files"),PropertyInfo(Variant::INT,"screen")) ); + BIND_CONSTANT( GROUP_CALL_DEFAULT ); BIND_CONSTANT( GROUP_CALL_REVERSE ); BIND_CONSTANT( GROUP_CALL_REALTIME ); diff --git a/scene/main/scene_main_loop.h b/scene/main/scene_main_loop.h index b6a015c9ed..5fc9e0c1ae 100644 --- a/scene/main/scene_main_loop.h +++ b/scene/main/scene_main_loop.h @@ -344,6 +344,7 @@ public: static SceneTree* get_singleton() { return singleton; } + void drop_files(const Vector<String>& p_files,int p_from_screen=0); SceneTree(); ~SceneTree(); diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 09c0a21f53..e6356d3366 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -30,7 +30,6 @@ #include "scene/resources/concave_polygon_shape.h" #include "scene/resources/convex_polygon_shape.h" #include "surface_tool.h" - static const char*_array_name[]={ "vertex_array", "normal_array", @@ -288,6 +287,7 @@ void Mesh::add_surface(PrimitiveType p_primitive,const Array& p_arrays,const Arr triangle_mesh=Ref<TriangleMesh>(); _change_notify(); + emit_changed(); } @@ -387,6 +387,7 @@ void Mesh::surface_remove(int p_idx) { triangle_mesh=Ref<TriangleMesh>(); _recompute_aabb(); _change_notify(); + emit_changed(); } @@ -491,6 +492,8 @@ void Mesh::add_surface_from_mesh_data(const Geometry::MeshData& p_mesh_data) { surfaces.push_back(s); _change_notify(); + + emit_changed(); } RID Mesh::get_rid() const { diff --git a/scene/scene_string_names.cpp b/scene/scene_string_names.cpp index 7e8dd41ed9..164ae55c9f 100644 --- a/scene/scene_string_names.cpp +++ b/scene/scene_string_names.cpp @@ -176,4 +176,11 @@ SceneStringNames::SceneStringNames() { path_pp=NodePath(".."); _default=StaticCString::create("default"); + + for(int i=0;i<MAX_MATERIALS;i++) { + + mesh_materials[i]="material/"+itos(i); + } + + _mesh_changed=StaticCString::create("_mesh_changed"); } diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h index 7143bd539f..32e51ce8f4 100644 --- a/scene/scene_string_names.h +++ b/scene/scene_string_names.h @@ -186,6 +186,12 @@ public: StringName node_configuration_warning_changed; + enum { + MAX_MATERIALS=32 + }; + StringName mesh_materials[MAX_MATERIALS]; + StringName _mesh_changed; + }; diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index e3d1b14835..f1ad685879 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -542,6 +542,7 @@ public: RID skeleton; RID material_override; RID sampled_light; + Vector<RID> materials; Vector<RID> light_instances; Vector<float> morph_values; BakedLightData *baked_light; diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index 6b5f1ba353..b3721268bf 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -398,7 +398,7 @@ void VisualServerRaster::mesh_add_custom_surface(RID p_mesh,const Variant& p_dat void VisualServerRaster::mesh_add_surface(RID p_mesh,PrimitiveType p_primitive,const Array& p_arrays,const Array& p_blend_shapes,bool p_alpha_sort) { VS_CHANGED; - _dependency_queue_update(p_mesh,true); + _dependency_queue_update(p_mesh,true,true); rasterizer->mesh_add_surface(p_mesh,p_primitive,p_arrays,p_blend_shapes,p_alpha_sort); } @@ -452,6 +452,7 @@ VisualServer::PrimitiveType VisualServerRaster::mesh_surface_get_primitive_type( void VisualServerRaster::mesh_remove_surface(RID p_mesh,int p_surface){ rasterizer->mesh_remove_surface(p_mesh,p_surface); + _dependency_queue_update(p_mesh,true,true); } int VisualServerRaster::mesh_get_surface_count(RID p_mesh) const{ @@ -480,6 +481,8 @@ void VisualServerRaster::mesh_clear(RID p_mesh) { while(rasterizer->mesh_get_surface_count(p_mesh)) { rasterizer->mesh_remove_surface(p_mesh,0); } + + _dependency_queue_update(p_mesh,true,true); } @@ -2038,7 +2041,7 @@ Variant VisualServerRaster::environment_fx_get_param(RID p_env,EnvironmentFxPara /* SCENARIO API */ -void VisualServerRaster::_dependency_queue_update(RID p_rid,bool p_update_aabb) { +void VisualServerRaster::_dependency_queue_update(RID p_rid,bool p_update_aabb,bool p_update_materials) { Map< RID, Set<RID> >::Element * E = instance_dependency_map.find( p_rid ); @@ -2051,17 +2054,19 @@ void VisualServerRaster::_dependency_queue_update(RID p_rid,bool p_update_aabb) while(I) { Instance *ins = instance_owner.get( I->get() ); - _instance_queue_update( ins , p_update_aabb ); + _instance_queue_update( ins , p_update_aabb, p_update_materials ); I = I->next(); } } -void VisualServerRaster::_instance_queue_update(Instance *p_instance,bool p_update_aabb) { +void VisualServerRaster::_instance_queue_update(Instance *p_instance,bool p_update_aabb,bool p_update_materials) { if (p_update_aabb) p_instance->update_aabb=true; + if (p_update_materials) + p_instance->update_materials=true; if (p_instance->update) return; @@ -2273,6 +2278,7 @@ void VisualServerRaster::instance_set_base(RID p_instance, RID p_base) { } instance->data.morph_values.clear(); + instance->data.materials.clear(); } @@ -2286,6 +2292,7 @@ void VisualServerRaster::instance_set_base(RID p_instance, RID p_base) { if (rasterizer->is_mesh(p_base)) { instance->base_type=INSTANCE_MESH; instance->data.morph_values.resize( rasterizer->mesh_get_morph_target_count(p_base)); + instance->data.materials.resize( rasterizer->mesh_get_surface_count(p_base)); } else if (rasterizer->is_multimesh(p_base)) { instance->base_type=INSTANCE_MULTIMESH; } else if (rasterizer->is_immediate(p_base)) { @@ -2510,6 +2517,16 @@ float VisualServerRaster::instance_get_morph_target_weight(RID p_instance,int p_ return instance->data.morph_values[p_shape]; } +void VisualServerRaster::instance_set_surface_material(RID p_instance,int p_surface, RID p_material) { + + VS_CHANGED; + Instance *instance = instance_owner.get( p_instance ); + ERR_FAIL_COND( !instance); + ERR_FAIL_INDEX( p_surface, instance->data.materials.size() ); + instance->data.materials[p_surface]=p_material; +} + + void VisualServerRaster::instance_set_transform(RID p_instance, const Transform& p_transform) { VS_CHANGED; Instance *instance = instance_owner.get( p_instance ); @@ -3046,6 +3063,7 @@ void VisualServerRaster::_update_instance(Instance *p_instance) { } + if (p_instance->aabb.has_no_surface()) return; @@ -3301,10 +3319,17 @@ void VisualServerRaster::_update_instances() { if (instance->update_aabb) _update_instance_aabb(instance); + if (instance->update_materials) { + if (instance->base_type==INSTANCE_MESH) { + instance->data.materials.resize(rasterizer->mesh_get_surface_count(instance->base_rid)); + } + } + _update_instance(instance); instance->update=false; instance->update_aabb=false; + instance->update_materials=false; instance->update_next=0; } } diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index 5abad863ee..39ea2f55e6 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -160,6 +160,7 @@ class VisualServerRaster : public VisualServer { Scenario *scenario; bool update; bool update_aabb; + bool update_materials; Instance *update_next; InstanceType base_type; @@ -317,6 +318,8 @@ class VisualServerRaster : public VisualServer { draw_range_end=0; extra_margin=0; visible_in_all_rooms=false; + update_aabb=false; + update_materials=false; baked_light=NULL; baked_light_info=NULL; @@ -583,8 +586,8 @@ class VisualServerRaster : public VisualServer { void _portal_disconnect(Instance *p_portal,bool p_cleanup=false); void _portal_attempt_connect(Instance *p_portal); - void _dependency_queue_update(RID p_rid,bool p_update_aabb=false); - _FORCE_INLINE_ void _instance_queue_update(Instance *p_instance,bool p_update_aabb=false); + void _dependency_queue_update(RID p_rid, bool p_update_aabb=false, bool p_update_materials=false); + _FORCE_INLINE_ void _instance_queue_update(Instance *p_instance,bool p_update_aabb=false,bool p_update_materials=false); void _update_instances(); void _update_instance_aabb(Instance *p_instance); void _update_instance(Instance *p_instance); @@ -1083,6 +1086,9 @@ public: virtual void instance_set_morph_target_weight(RID p_instance,int p_shape, float p_weight); virtual float instance_get_morph_target_weight(RID p_instance,int p_shape) const; + virtual void instance_set_surface_material(RID p_instance,int p_surface, RID p_material); + + virtual void instance_set_transform(RID p_instance, const Transform& p_transform); virtual Transform instance_get_transform(RID p_instance) const; diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index 6a42fcc8a6..80cf43d572 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -525,6 +525,8 @@ public: FUNC3(instance_set_morph_target_weight,RID,int, float); FUNC2RC(float,instance_get_morph_target_weight,RID,int); + FUNC3(instance_set_surface_material,RID,int, RID); + FUNC2(instance_set_transform,RID, const Transform&); FUNC1RC(Transform,instance_get_transform,RID); diff --git a/servers/visual_server.h b/servers/visual_server.h index 750c090bbe..f32e976b57 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -919,6 +919,8 @@ public: virtual void instance_set_morph_target_weight(RID p_instance,int p_shape, float p_weight)=0; virtual float instance_get_morph_target_weight(RID p_instance,int p_shape) const=0; + virtual void instance_set_surface_material(RID p_instance,int p_surface, RID p_material)=0; + virtual void instance_attach_skeleton(RID p_instance,RID p_skeleton)=0; virtual RID instance_get_skeleton(RID p_instance) const=0; diff --git a/tools/editor/create_dialog.cpp b/tools/editor/create_dialog.cpp index 151208ace0..8bce415fb8 100644 --- a/tools/editor/create_dialog.cpp +++ b/tools/editor/create_dialog.cpp @@ -255,6 +255,15 @@ void CreateDialog::set_base_type(const String& p_base) { _update_search(); } +String CreateDialog::get_selected_type() { + + TreeItem *selected = search_options->get_selected(); + if (selected) + return selected->get_text(0); + else + return String(); +} + Object *CreateDialog::instance_selected() { TreeItem *selected = search_options->get_selected(); diff --git a/tools/editor/create_dialog.h b/tools/editor/create_dialog.h index a46ff5ae06..8957479beb 100644 --- a/tools/editor/create_dialog.h +++ b/tools/editor/create_dialog.h @@ -66,6 +66,7 @@ protected: public: Object *instance_selected(); + String get_selected_type(); void set_base_type(const String& p_base); String get_base_type() const; diff --git a/tools/editor/editor_file_system.cpp b/tools/editor/editor_file_system.cpp index 1062417fec..3fd5f7e444 100644 --- a/tools/editor/editor_file_system.cpp +++ b/tools/editor/editor_file_system.cpp @@ -149,6 +149,41 @@ bool EditorFileSystemDirectory::is_missing_sources(int p_idx) const { return false; } +bool EditorFileSystemDirectory::have_sources_changed(int p_idx) const { + + ERR_FAIL_INDEX_V(p_idx,files.size(),false); + return files[p_idx]->meta.sources_changed; + +} + +int EditorFileSystemDirectory::get_source_count(int p_idx) const { + + ERR_FAIL_INDEX_V(p_idx,files.size(),0); + if (!files[p_idx]->meta.enabled) + return 0; + +} +String EditorFileSystemDirectory::get_source_file(int p_idx,int p_source) const { + + ERR_FAIL_INDEX_V(p_idx,files.size(),String()); + ERR_FAIL_INDEX_V(p_source,files[p_idx]->meta.sources.size(),String()); + if (!files[p_idx]->meta.enabled) + return String(); + + return files[p_idx]->meta.sources[p_source].path; + +} +bool EditorFileSystemDirectory::is_source_file_missing(int p_idx,int p_source) const { + + ERR_FAIL_INDEX_V(p_idx,files.size(),false); + ERR_FAIL_INDEX_V(p_source,files[p_idx]->meta.sources.size(),false); + if (!files[p_idx]->meta.enabled) + return false; + + return files[p_idx]->meta.sources[p_source].missing; +} + + StringName EditorFileSystemDirectory::get_file_type(int p_idx) const { ERR_FAIL_INDEX_V(p_idx,files.size(),""); @@ -210,8 +245,11 @@ EditorFileSystemDirectory::ImportMeta EditorFileSystem::_get_meta(const String& EditorFileSystemDirectory::ImportMeta m; if (imd.is_null()) { m.enabled=false; + m.sources_changed=false; } else { m.enabled=true; + m.sources_changed=false; + for(int i=0;i<imd->get_source_count();i++) { EditorFileSystemDirectory::ImportMeta::Source s; s.path=imd->get_source_path(i); @@ -649,7 +687,13 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir,DirAccess ia.dir=p_dir; ia.file=E->get(); scan_actions.push_back(ia); + fi->meta.sources_changed=true; + } else { + fi->meta.sources_changed=false; } + + } else { + fi->meta.sources_changed=true; } p_dir->files.push_back(fi); @@ -764,6 +808,9 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir,const S ia.dir=p_dir; ia.file=f; scan_actions.push_back(ia); + fi->meta.sources_changed=true; + } else { + fi->meta.sources_changed=false; } } else { @@ -800,6 +847,9 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir,const S ia.dir=p_dir; ia.file=p_dir->files[i]->file; scan_actions.push_back(ia); + p_dir->files[i]->meta.sources_changed=true; + } else { + p_dir->files[i]->meta.sources_changed=false; } } @@ -1113,6 +1163,25 @@ String EditorFileSystem::get_file_type(const String& p_file) const { } +EditorFileSystemDirectory* EditorFileSystem::find_file(const String& p_file,int* r_index) const { + + if (!filesystem || scanning) + return NULL; + + EditorFileSystemDirectory *fs=NULL; + int cpos=-1; + if (!_find_file(p_file,&fs,cpos)) { + + return NULL; + } + + + if (r_index) + *r_index=cpos; + + return fs; +} + EditorFileSystemDirectory *EditorFileSystem::get_path(const String& p_path) { diff --git a/tools/editor/editor_file_system.h b/tools/editor/editor_file_system.h index 254dd68c14..b96e947569 100644 --- a/tools/editor/editor_file_system.h +++ b/tools/editor/editor_file_system.h @@ -55,7 +55,7 @@ class EditorFileSystemDirectory : public Object { String path; String md5; uint64_t modified_time; - bool missing; + bool missing; }; @@ -63,6 +63,7 @@ class EditorFileSystemDirectory : public Object { String import_editor; Vector<String> deps; bool enabled; + bool sources_changed; }; @@ -102,8 +103,12 @@ public: StringName get_file_type(int p_idx) const; bool get_file_meta(int p_idx) const; bool is_missing_sources(int p_idx) const; + bool have_sources_changed(int p_idx) const; Vector<String> get_missing_sources(int p_idx) const; Vector<String> get_file_deps(int p_idx) const; + int get_source_count(int p_idx) const; + String get_source_file(int p_idx,int p_source) const; + bool is_source_file_missing(int p_idx,int p_source) const; EditorFileSystemDirectory *get_parent(); @@ -230,6 +235,7 @@ public: String find_resource_from_source(const String& p_path) const; EditorFileSystemDirectory *get_path(const String& p_path); String get_file_type(const String& p_file) const; + EditorFileSystemDirectory* find_file(const String& p_file,int* r_index) const; EditorFileSystem(); ~EditorFileSystem(); }; diff --git a/tools/editor/editor_import_export.cpp b/tools/editor/editor_import_export.cpp index 25dced4745..ac7ea514d7 100644 --- a/tools/editor/editor_import_export.cpp +++ b/tools/editor/editor_import_export.cpp @@ -85,6 +85,9 @@ void EditorImportPlugin::_bind_methods() { ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo("import_dialog",PropertyInfo(Variant::STRING,"from"))); ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo(Variant::INT,"import",PropertyInfo(Variant::STRING,"path"),PropertyInfo(Variant::OBJECT,"from",PROPERTY_HINT_RESOURCE_TYPE,"ResourceImportMetadata"))); ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo(Variant::RAW_ARRAY,"custom_export",PropertyInfo(Variant::STRING,"path"),PropertyInfo(Variant::OBJECT,"platform",PROPERTY_HINT_RESOURCE_TYPE,"EditorExportPlatform"))); + ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo("import_from_drop",PropertyInfo(Variant::STRING_ARRAY,"files"),PropertyInfo(Variant::STRING,"dest_path"))); + ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo("reimport_multiple_files",PropertyInfo(Variant::STRING_ARRAY,"files"))); + ObjectTypeDB::add_virtual_method(get_type_static(),MethodInfo(Variant::BOOL,"can_reimport_multiple_files")); // BIND_VMETHOD( mi ); } @@ -130,13 +133,37 @@ Error EditorImportPlugin::import(const String& p_path, const Ref<ResourceImportM Vector<uint8_t> EditorImportPlugin::custom_export(const String& p_path, const Ref<EditorExportPlatform> &p_platform) { - if (get_script_instance() && get_script_instance()->has_method("_custom_export")) { - get_script_instance()->call("_custom_export",p_path,p_platform); + if (get_script_instance() && get_script_instance()->has_method("custom_export")) { + get_script_instance()->call("custom_export",p_path,p_platform); } return Vector<uint8_t>(); } +bool EditorImportPlugin::can_reimport_multiple_files() const { + + if (get_script_instance() && get_script_instance()->has_method("can_reimport_multiple_files")) { + return get_script_instance()->call("can_reimport_multiple_files"); + } + + return false; +} +void EditorImportPlugin::reimport_multiple_files(const Vector<String>& p_list) { + + if (get_script_instance() && get_script_instance()->has_method("reimport_multiple_files")) { + get_script_instance()->call("reimport_multiple_files",p_list); + } + +} + +void EditorImportPlugin::import_from_drop(const Vector<String>& p_drop, const String &p_dest_path) { + + if (get_script_instance() && get_script_instance()->has_method("import_from_drop")) { + get_script_instance()->call("import_from_drop",p_drop,p_dest_path); + } + +} + EditorImportPlugin::EditorImportPlugin() { diff --git a/tools/editor/editor_import_export.h b/tools/editor/editor_import_export.h index 5e09d674d1..e21fd8c8f8 100644 --- a/tools/editor/editor_import_export.h +++ b/tools/editor/editor_import_export.h @@ -60,6 +60,9 @@ public: virtual String get_visible_name() const; virtual void import_dialog(const String& p_from=""); virtual Error import(const String& p_path, const Ref<ResourceImportMetadata>& p_from); + virtual void import_from_drop(const Vector<String>& p_drop,const String& p_dest_path); + virtual void reimport_multiple_files(const Vector<String>& p_list); + virtual bool can_reimport_multiple_files() const; virtual Vector<uint8_t> custom_export(const String& p_path,const Ref<EditorExportPlatform> &p_platform); EditorImportPlugin(); diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index 69dfc556b4..af27f7d4a7 100644 --- a/tools/editor/editor_node.cpp +++ b/tools/editor/editor_node.cpp @@ -288,6 +288,7 @@ void EditorNode::_notification(int p_what) { get_tree()->get_root()->set_as_audio_listener(false); get_tree()->get_root()->set_as_audio_listener_2d(false); get_tree()->set_auto_accept_quit(false); + get_tree()->connect("files_dropped",this,"_dropped_files"); //VisualServer::get_singleton()->viewport_set_hide_canvas(editor->get_scene_root()->get_viewport(),false); //import_monitor->scan_changes(); @@ -375,6 +376,7 @@ void EditorNode::_notification(int p_what) { _menu_option_confirm(DEPENDENCY_LOAD_CHANGED_IMAGES,true); } + waiting_for_sources_changed=true; EditorFileSystem::get_singleton()->scan_sources(); } @@ -412,6 +414,42 @@ void EditorNode::_fs_changed() { void EditorNode::_sources_changed(bool p_exist) { + if (p_exist && bool(EditorSettings::get_singleton()->get("import/automatic_reimport_on_sources_changed"))) { + p_exist=false; + + List<String> changed_sources; + EditorFileSystem::get_singleton()->get_changed_sources(&changed_sources); + + + EditorProgress ep("reimport",TTR("Re-Importing"),changed_sources.size()); + int step_idx=0; + + for(List<String>::Element *E=changed_sources.front();E;E=E->next()) { + + ep.step(TTR("Importing:")+" "+E->get(),step_idx++); + + Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(E->get()); + ERR_CONTINUE(rimd.is_null()); + String editor = rimd->get_editor(); + if (editor.begins_with("texture_")) { + editor="texture"; //compatibility fix for old versions + } + Ref<EditorImportPlugin> eip = EditorImportExport::get_singleton()->get_import_plugin_by_name(editor); + ERR_CONTINUE(eip.is_null()); + Error err = eip->import(E->get(),rimd); + if (err!=OK) { + EditorNode::add_io_error("Error Re Importing:\n "+E->get()); + } + + } + + EditorFileSystem::get_singleton()->scan_sources(); + waiting_for_sources_changed=false; + + return; + } + + if (p_exist) { sources_button->set_icon(gui_base->get_icon("DependencyChanged","EditorIcons")); @@ -424,6 +462,8 @@ void EditorNode::_sources_changed(bool p_exist) { } + waiting_for_sources_changed=false; + } void EditorNode::_vp_resized() { @@ -435,13 +475,13 @@ void EditorNode::_rebuild_import_menu() { PopupMenu* p = import_menu->get_popup(); p->clear(); - p->add_item(TTR("Node From Scene"), FILE_IMPORT_SUBSCENE); - p->add_separator(); + //p->add_item(TTR("Node From Scene"), FILE_IMPORT_SUBSCENE); + //p->add_separator(); for (int i = 0; i < editor_import_export->get_import_plugin_count(); i++) { p->add_item(editor_import_export->get_import_plugin(i)->get_visible_name(), IMPORT_PLUGIN_BASE + i); } - p->add_separator(); - p->add_item(TTR("Re-Import.."), SETTINGS_IMPORT); + //p->add_separator(); + //p->add_item(TTR("Re-Import.."), SETTINGS_IMPORT); } void EditorNode::_node_renamed() { @@ -2858,6 +2898,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { } break; + default: { if (p_option>=OBJECT_METHOD_BASE) { @@ -4899,6 +4940,7 @@ Variant EditorNode::drag_resource(const Ref<Resource>& p_res,Control* p_from) { TextureFrame *drag_preview = memnew( TextureFrame ); Label* label=memnew( Label ); + waiting_for_sources_changed=true; // Ref<Texture> preview; { @@ -5000,6 +5042,15 @@ Variant EditorNode::drag_files_and_dirs(const Vector<String>& p_files, Control * } + +void EditorNode::_dropped_files(const Vector<String>& p_files,int p_screen) { + + String cur_path = scenes_dock->get_current_path(); + for(int i=0;i<EditorImportExport::get_singleton()->get_import_plugin_count();i++) { + EditorImportExport::get_singleton()->get_import_plugin(i)->import_from_drop(p_files,cur_path); + } +} + void EditorNode::_bind_methods() { @@ -5067,6 +5118,9 @@ void EditorNode::_bind_methods() { ObjectTypeDB::bind_method("_toggle_search_bar",&EditorNode::_toggle_search_bar); ObjectTypeDB::bind_method("_clear_search_box",&EditorNode::_clear_search_box); ObjectTypeDB::bind_method("_clear_undo_history",&EditorNode::_clear_undo_history); + ObjectTypeDB::bind_method("_dropped_files",&EditorNode::_dropped_files); + + ObjectTypeDB::bind_method(_MD("add_editor_import_plugin", "plugin"), &EditorNode::add_editor_import_plugin); ObjectTypeDB::bind_method(_MD("remove_editor_import_plugin", "plugin"), &EditorNode::remove_editor_import_plugin); @@ -6185,10 +6239,7 @@ EditorNode::EditorNode() { file_server = memnew( EditorFileServer ); - editor_import_export->add_import_plugin( Ref<EditorTextureImportPlugin>( memnew(EditorTextureImportPlugin(this,EditorTextureImportPlugin::MODE_TEXTURE_2D) ))); - editor_import_export->add_import_plugin( Ref<EditorTextureImportPlugin>( memnew(EditorTextureImportPlugin(this,EditorTextureImportPlugin::MODE_ATLAS) ))); - editor_import_export->add_import_plugin( Ref<EditorTextureImportPlugin>( memnew(EditorTextureImportPlugin(this,EditorTextureImportPlugin::MODE_LARGE) ))); - editor_import_export->add_import_plugin( Ref<EditorTextureImportPlugin>( memnew(EditorTextureImportPlugin(this,EditorTextureImportPlugin::MODE_TEXTURE_3D) ))); + editor_import_export->add_import_plugin( Ref<EditorTextureImportPlugin>( memnew(EditorTextureImportPlugin(this) ))); Ref<EditorSceneImportPlugin> _scene_import = memnew(EditorSceneImportPlugin(this) ); Ref<EditorSceneImporterCollada> _collada_import = memnew( EditorSceneImporterCollada); _scene_import->add_importer(_collada_import); @@ -6401,6 +6452,7 @@ EditorNode::EditorNode() { _load_docks(); + } diff --git a/tools/editor/editor_node.h b/tools/editor/editor_node.h index 18a88f63bb..db589bb1c3 100644 --- a/tools/editor/editor_node.h +++ b/tools/editor/editor_node.h @@ -366,6 +366,8 @@ private: String open_navigate; bool changing_scene; + bool waiting_for_sources_changed; + uint32_t circle_step_msec; uint64_t circle_step_frame; int circle_step; @@ -464,6 +466,7 @@ private: void _add_to_recent_scenes(const String& p_scene); void _update_recent_scenes(); void _open_recent_scene(int p_idx); + void _dropped_files(const Vector<String>& p_files,int p_screen); //void _open_recent_scene_confirm(); String _recent_scene; @@ -607,6 +610,8 @@ public: void save_resource(const Ref<Resource>& p_resource); void save_resource_as(const Ref<Resource>& p_resource, const String &p_at_path=String()); + void merge_from_scene() { _menu_option_confirm(FILE_IMPORT_SUBSCENE,false); } + static bool has_unsaved_changes() { return singleton->unsaved_cache; } static HBoxContainer *get_menu_hb() { return singleton->menu_hb; } diff --git a/tools/editor/editor_resource_preview.cpp b/tools/editor/editor_resource_preview.cpp index f684b49a2c..d31cf9e0fd 100644 --- a/tools/editor/editor_resource_preview.cpp +++ b/tools/editor/editor_resource_preview.cpp @@ -36,14 +36,24 @@ void EditorResourcePreview::_preview_ready(const String& p_str,const Ref<Texture //print_line("preview is ready"); preview_mutex->lock(); + String path = p_str; + uint32_t hash=0; + + if (p_str.begins_with("ID:")) { + hash=p_str.get_slicec(':',2).to_int(); + path="ID:"+p_str.get_slicec(':',1); + } + Item item; item.order=order++; item.preview=p_texture; - cache[p_str]=item; + item.last_hash=hash; + + cache[path]=item; Object *recv = ObjectDB::get_instance(id); if (recv) { - recv->call_deferred(p_func,p_str,p_texture,p_ud); + recv->call_deferred(p_func,path,p_texture,p_ud); } preview_mutex->unlock(); @@ -51,7 +61,12 @@ void EditorResourcePreview::_preview_ready(const String& p_str,const Ref<Texture Ref<Texture> EditorResourcePreview::_generate_preview(const QueueItem& p_item,const String& cache_base) { - String type = ResourceLoader::get_resource_type(p_item.path); + String type; + + if (p_item.resource.is_valid()) + type=p_item.resource->get_type(); + else + type=ResourceLoader::get_resource_type(p_item.path); //print_line("resource type is: "+type); if (type=="") @@ -62,24 +77,31 @@ Ref<Texture> EditorResourcePreview::_generate_preview(const QueueItem& p_item,co for(int i=0;i<preview_generators.size();i++) { if (!preview_generators[i]->handles(type)) continue; - generated = preview_generators[i]->generate_from_path(p_item.path); + if (p_item.resource.is_valid()) { + generated = preview_generators[i]->generate(p_item.resource); + } else { + generated = preview_generators[i]->generate_from_path(p_item.path); + } break; } - if (generated.is_valid()) { - //print_line("was generated"); - int thumbnail_size = EditorSettings::get_singleton()->get("file_dialog/thumbnail_size"); - //wow it generated a preview... save cache - ResourceSaver::save(cache_base+".png",generated); - FileAccess *f=FileAccess::open(cache_base+".txt",FileAccess::WRITE); - f->store_line(itos(thumbnail_size)); - f->store_line(itos(FileAccess::get_modified_time(p_item.path))); - f->store_line(FileAccess::get_md5(p_item.path)); - memdelete(f); - } else { - //print_line("was not generated"); + if (!p_item.resource.is_valid()) { + // cache the preview in case it's a resource on disk + if (generated.is_valid()) { + //print_line("was generated"); + int thumbnail_size = EditorSettings::get_singleton()->get("file_dialog/thumbnail_size"); + //wow it generated a preview... save cache + ResourceSaver::save(cache_base+".png",generated); + FileAccess *f=FileAccess::open(cache_base+".txt",FileAccess::WRITE); + f->store_line(itos(thumbnail_size)); + f->store_line(itos(FileAccess::get_modified_time(p_item.path))); + f->store_line(FileAccess::get_md5(p_item.path)); + memdelete(f); + } else { + //print_line("was not generated"); + } } return generated; @@ -113,8 +135,17 @@ void EditorResourcePreview::_thread() { if (cache.has(item.path)) { //already has it because someone loaded it, just let it know it's ready + if (item.resource.is_valid()) { + item.path+=":"+itos(cache[item.path].last_hash); //keep last hash (see description of what this is in condition below) + } call_deferred("_preview_ready",item.path,cache[item.path].preview,item.id,item.function,item.userdata); + } else if (item.resource.is_valid()){ + + texture=_generate_preview(item,String()); + //adding hash to the end of path (should be ID:<objid>:<hash>) because of 5 argument limit to call_deferred + call_deferred("_preview_ready",item.path+":"+itos(item.resource->hash_edited_version()),texture,item.id,item.function,item.userdata); + } else { @@ -194,6 +225,35 @@ void EditorResourcePreview::_thread() { +void EditorResourcePreview::queue_edited_resource_preview(const Ref<Resource>& p_res, Object* p_receiver, const StringName& p_receiver_func, const Variant& p_userdata) { + + ERR_FAIL_NULL(p_receiver); + ERR_FAIL_COND(!p_res.is_valid()); + + preview_mutex->lock(); + + String path_id = "ID:"+itos(p_res->get_instance_ID()); + if (cache.has(path_id) && cache[path_id].last_hash==p_res->hash_edited_version()) { + + cache[path_id].order=order++; + p_receiver->call_deferred(p_receiver_func,path_id,cache[path_id].preview,p_userdata); + preview_mutex->unlock(); + return; + + } + + //print_line("send to thread "+p_path); + QueueItem item; + item.function=p_receiver_func; + item.id=p_receiver->get_instance_ID(); + item.resource=p_res; + item.path=path_id; + item.userdata=p_userdata; + + queue.push_back(item); + preview_mutex->unlock(); + preview_sem->post(); +} void EditorResourcePreview::queue_resource_preview(const String& p_path, Object* p_receiver, const StringName& p_receiver_func, const Variant& p_userdata) { @@ -204,7 +264,6 @@ void EditorResourcePreview::queue_resource_preview(const String& p_path, Object* p_receiver->call_deferred(p_receiver_func,p_path,cache[p_path].preview,p_userdata); preview_mutex->unlock(); return; - } //print_line("send to thread "+p_path); diff --git a/tools/editor/editor_resource_preview.h b/tools/editor/editor_resource_preview.h index aadae75597..13c3d51313 100644 --- a/tools/editor/editor_resource_preview.h +++ b/tools/editor/editor_resource_preview.h @@ -47,6 +47,7 @@ class EditorResourcePreview : public Node { static EditorResourcePreview* singleton; struct QueueItem { + Ref<Resource> resource; String path; ObjectID id; StringName function; @@ -63,6 +64,7 @@ class EditorResourcePreview : public Node { struct Item { Ref<Texture> preview; int order; + uint32_t last_hash; }; int order; @@ -84,7 +86,8 @@ public: static EditorResourcePreview* get_singleton(); //callback funtion is callback(String p_path,Ref<Texture> preview,Variant udata) preview null if could not load - void queue_resource_preview(const String& p_path, Object* p_receiver, const StringName& p_receiver_func, const Variant& p_userdata); + void queue_resource_preview(const String& p_res, Object* p_receiver, const StringName& p_receiver_func, const Variant& p_userdata); + void queue_edited_resource_preview(const Ref<Resource>& p_path, Object* p_receiver, const StringName& p_receiver_func, const Variant& p_userdata); void add_preview_generator(const Ref<EditorResourcePreviewGenerator>& p_generator); diff --git a/tools/editor/editor_settings.cpp b/tools/editor/editor_settings.cpp index ad990e3fab..05c4f74b0d 100644 --- a/tools/editor/editor_settings.cpp +++ b/tools/editor/editor_settings.cpp @@ -507,6 +507,8 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { set("resources/save_compressed_resources",true); set("resources/auto_reload_modified_images",true); + set("import/automatic_reimport_on_sources_changed",true); + if (p_extra_config.is_valid()) { if (p_extra_config->has_section("init_projects") && p_extra_config->has_section_key("init_projects", "list")) { diff --git a/tools/editor/icons/icon_dependency_changed.png b/tools/editor/icons/icon_dependency_changed.png Binary files differindex ecf8a011cf..f48906f256 100644 --- a/tools/editor/icons/icon_dependency_changed.png +++ b/tools/editor/icons/icon_dependency_changed.png diff --git a/tools/editor/icons/icon_dependency_ok.png b/tools/editor/icons/icon_dependency_ok.png Binary files differindex f4d4c9ea29..fe4d7053f7 100644 --- a/tools/editor/icons/icon_dependency_ok.png +++ b/tools/editor/icons/icon_dependency_ok.png diff --git a/tools/editor/io_plugins/editor_font_import_plugin.cpp b/tools/editor/io_plugins/editor_font_import_plugin.cpp index 6ac67ab8a6..7cc5b579fe 100644 --- a/tools/editor/io_plugins/editor_font_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_font_import_plugin.cpp @@ -601,6 +601,13 @@ public: } } + + void set_source_and_dest(const String& p_font,const String& p_dest) { + source->get_line_edit()->set_text(p_font); + dest->get_line_edit()->set_text(p_dest); + _prop_changed(); + } + EditorFontImportDialog(EditorFontImportPlugin *p_plugin) { plugin=p_plugin; VBoxContainer *vbc = memnew( VBoxContainer ); @@ -1629,6 +1636,20 @@ Error EditorFontImportPlugin::import(const String& p_path, const Ref<ResourceImp } +void EditorFontImportPlugin::import_from_drop(const Vector<String>& p_drop, const String &p_dest_path) { + + for(int i=0;i<p_drop.size();i++) { + String ext = p_drop[i].extension().to_lower(); + String file = p_drop[i].get_file(); + if (ext=="ttf" || ext=="otf" || ext=="fnt") { + + import_dialog(); + dialog->set_source_and_dest(p_drop[i],p_dest_path.plus_file(file.basename()+".fnt")); + break; + } + } +} + EditorFontImportPlugin::EditorFontImportPlugin(EditorNode* p_editor) { diff --git a/tools/editor/io_plugins/editor_font_import_plugin.h b/tools/editor/io_plugins/editor_font_import_plugin.h index ce26ef91e2..25914e6f83 100644 --- a/tools/editor/io_plugins/editor_font_import_plugin.h +++ b/tools/editor/io_plugins/editor_font_import_plugin.h @@ -48,6 +48,7 @@ public: virtual String get_visible_name() const; virtual void import_dialog(const String& p_from=""); virtual Error import(const String& p_path, const Ref<ResourceImportMetadata>& p_from); + virtual void import_from_drop(const Vector<String>& p_drop,const String& p_dest_path); EditorFontImportPlugin(EditorNode* p_editor); diff --git a/tools/editor/io_plugins/editor_mesh_import_plugin.cpp b/tools/editor/io_plugins/editor_mesh_import_plugin.cpp index 9af7d8daa5..c77256f27b 100644 --- a/tools/editor/io_plugins/editor_mesh_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_mesh_import_plugin.cpp @@ -331,7 +331,7 @@ String EditorMeshImportPlugin::get_name() const { } String EditorMeshImportPlugin::get_visible_name() const{ - return "3D Mesh"; + return "Mesh"; } void EditorMeshImportPlugin::import_dialog(const String& p_from){ @@ -536,6 +536,26 @@ Error EditorMeshImportPlugin::import(const String& p_path, const Ref<ResourceImp } +void EditorMeshImportPlugin::import_from_drop(const Vector<String>& p_drop, const String &p_dest_path) { + + + Vector<String> files; + for(int i=0;i<p_drop.size();i++) { + String ext = p_drop[i].extension().to_lower(); + String file = p_drop[i].get_file(); + if (ext=="obj") { + + files.push_back(p_drop[i]); + } + } + + if (files.size()) { + import_dialog(); + dialog->_choose_files(files); + dialog->_choose_save_dir(p_dest_path); + } +} + EditorMeshImportPlugin::EditorMeshImportPlugin(EditorNode* p_editor) { dialog = memnew( EditorMeshImportDialog(this)); diff --git a/tools/editor/io_plugins/editor_mesh_import_plugin.h b/tools/editor/io_plugins/editor_mesh_import_plugin.h index 014954685d..ed30d69e18 100644 --- a/tools/editor/io_plugins/editor_mesh_import_plugin.h +++ b/tools/editor/io_plugins/editor_mesh_import_plugin.h @@ -21,6 +21,7 @@ public: virtual String get_visible_name() const; virtual void import_dialog(const String& p_from=""); virtual Error import(const String& p_path, const Ref<ResourceImportMetadata>& p_from); + void import_from_drop(const Vector<String>& p_drop, const String &p_dest_path); EditorMeshImportPlugin(EditorNode* p_editor); diff --git a/tools/editor/io_plugins/editor_sample_import_plugin.cpp b/tools/editor/io_plugins/editor_sample_import_plugin.cpp index c608fe906f..631273a878 100644 --- a/tools/editor/io_plugins/editor_sample_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_sample_import_plugin.cpp @@ -823,6 +823,58 @@ void EditorSampleImportPlugin::_compress_ima_adpcm(const Vector<float>& p_data,D EditorSampleImportPlugin* EditorSampleImportPlugin::singleton=NULL; +void EditorSampleImportPlugin::import_from_drop(const Vector<String>& p_drop, const String &p_dest_path) { + + + Vector<String> files; + for(int i=0;i<p_drop.size();i++) { + String ext = p_drop[i].extension().to_lower(); + + if (ext=="wav") { + + files.push_back(p_drop[i]); + } + } + + if (files.size()) { + import_dialog(); + dialog->_choose_files(files); + dialog->_choose_save_dir(p_dest_path); + } +} + +void EditorSampleImportPlugin::reimport_multiple_files(const Vector<String>& p_list) { + + if (p_list.size()==0) + return; + + Vector<String> sources; + for(int i=0;i<p_list.size();i++) { + int idx; + EditorFileSystemDirectory *efsd = EditorFileSystem::get_singleton()->find_file(p_list[i],&idx); + if (efsd) { + for(int j=0;j<efsd->get_source_count(idx);j++) { + String file = expand_source_path(efsd->get_source_file(idx,j)); + if (sources.find(file)==-1) { + sources.push_back(file); + } + + } + } + } + + if (sources.size()) { + + dialog->popup_import(p_list[0]); + dialog->_choose_files(sources); + dialog->_choose_save_dir(p_list[0].get_base_dir()); + } +} + +bool EditorSampleImportPlugin::can_reimport_multiple_files() const { + + return true; +} EditorSampleImportPlugin::EditorSampleImportPlugin(EditorNode* p_editor) { @@ -865,6 +917,7 @@ Vector<uint8_t> EditorSampleExportPlugin::custom_export(String& p_path,const Ref } + EditorSampleExportPlugin::EditorSampleExportPlugin() { } diff --git a/tools/editor/io_plugins/editor_sample_import_plugin.h b/tools/editor/io_plugins/editor_sample_import_plugin.h index b31562af76..a2686ebe4f 100644 --- a/tools/editor/io_plugins/editor_sample_import_plugin.h +++ b/tools/editor/io_plugins/editor_sample_import_plugin.h @@ -49,6 +49,9 @@ public: virtual String get_visible_name() const; virtual void import_dialog(const String& p_from=""); virtual Error import(const String& p_path, const Ref<ResourceImportMetadata>& p_from); + void import_from_drop(const Vector<String>& p_drop, const String &p_dest_path); + virtual void reimport_multiple_files(const Vector<String>& p_list); + virtual bool can_reimport_multiple_files() const; EditorSampleImportPlugin(EditorNode* p_editor); diff --git a/tools/editor/io_plugins/editor_scene_import_plugin.cpp b/tools/editor/io_plugins/editor_scene_import_plugin.cpp index 84ef5f1973..00bd5413d3 100644 --- a/tools/editor/io_plugins/editor_scene_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_scene_import_plugin.cpp @@ -41,6 +41,7 @@ #include "scene/3d/physics_body.h" #include "scene/3d/portal.h" #include "scene/3d/vehicle_body.h" +#include "tools/editor/create_dialog.h" #include "os/os.h" @@ -95,6 +96,7 @@ class EditorImportAnimationOptions : public VBoxContainer { Tree *optimization_tree; Vector<TreeItem*> items; + bool updating; bool validating; @@ -167,6 +169,7 @@ class EditorSceneImportDialog : public ConfirmationDialog { EditorFileDialog *script_select; EditorDirDialog *save_select; OptionButton *texture_action; + CreateDialog *root_type_choose; ConfirmationDialog *confirm_open; @@ -178,8 +181,13 @@ class EditorSceneImportDialog : public ConfirmationDialog { Map<Ref<Mesh>,Ref<Shape> > collision_map; ConfirmationDialog *error_dialog; - OptionButton *this_import; - OptionButton *next_import; + Button *root_type; + CheckBox *root_default; + + + void _root_default_pressed(); + void _root_type_pressed(); + void _set_root_type(); void _choose_file(const String& p_path); void _choose_save_file(const String& p_path); @@ -206,6 +214,11 @@ protected: static void _bind_methods(); public: + void setup_popup(const String& p_from,const String& p_to_path) { + _choose_file(p_from); + _choose_save_file(p_to_path); + } + Error import(const String& p_from, const String& p_to, const String& p_preset); void popup_import(const String& p_from); EditorSceneImportDialog(EditorNode *p_editor,EditorSceneImportPlugin *p_plugin); @@ -764,9 +777,10 @@ void EditorSceneImportDialog::_import(bool p_and_open) { rim->set_option("animation_filters",animation_options->get_filter()); rim->set_option("animation_clips",animation_options->get_clips()); rim->set_option("post_import_script",script_path->get_text()); - rim->set_option("import_this_time",this_import->get_selected()); - rim->set_option("import_next_time",next_import->get_selected()); rim->set_option("reimport",true); + if (!root_default->is_pressed()) { + rim->set_option("root_type",root_type->get_text()); + } List<String> missing; Error err = plugin->import1(rim,&scene,&missing); @@ -909,12 +923,24 @@ void EditorSceneImportDialog::popup_import(const String &p_from) { if (rimd->has_option("animation_optimizer_max_angle")) animation_options->set_optimize_max_angle(rimd->get_option("animation_optimizer_max_angle")); + if (rimd->has_option("root_type")) { + root_default->set_pressed(false); + String type = rimd->get_option("root_type"); + root_type->set_text(type); + root_type->set_disabled(false); + + if (has_icon(type,"EditorIcons")) { + root_type->set_icon(get_icon(type,"EditorIcons")); + } else { + root_type->set_icon(get_icon("Object","EditorIcons")); + } + + } else { + root_default->set_pressed(true); + root_type->set_disabled(true); + } script_path->set_text(rimd->get_option("post_import_script")); - if (rimd->has_option("import_this_time")) - this_import->select(rimd->get_option("import_this_time")); - if (rimd->has_option("import_next_time")) - next_import->select(rimd->get_option("import_next_time")); save_path->set_text(p_from.get_base_dir()); import_path->set_text(EditorImportPlugin::expand_source_path(rimd->get_source_path(0))); @@ -931,6 +957,9 @@ void EditorSceneImportDialog::_notification(int p_what) { List<String> extensions; file_select->clear_filters(); + root_type->set_icon(get_icon("Spatial","EditorIcons")); + root_type->set_text("Spatial"); + root_type->set_disabled(true); for(int i=0;i<plugin->get_importers().size();i++) { plugin->get_importers()[i]->get_extensions(&extensions); @@ -981,7 +1010,30 @@ void EditorSceneImportDialog::_dialog_hid() { wip_rimd=Ref<ResourceImportMetadata>(); } } +void EditorSceneImportDialog::_root_default_pressed() { + + root_type->set_disabled(root_default->is_pressed()); +} + +void EditorSceneImportDialog::_root_type_pressed() { + + + root_type_choose->popup(false); +} + + +void EditorSceneImportDialog::_set_root_type() { + String type = root_type_choose->get_selected_type(); + if (type==String()) + return; + root_type->set_text(type); + if (has_icon(type,"EditorIcons")) { + root_type->set_icon(get_icon(type,"EditorIcons")); + } else { + root_type->set_icon(get_icon("Object","EditorIcons")); + } +} void EditorSceneImportDialog::_bind_methods() { @@ -996,13 +1048,16 @@ void EditorSceneImportDialog::_bind_methods() { ObjectTypeDB::bind_method("_dialog_hid",&EditorSceneImportDialog::_dialog_hid); ObjectTypeDB::bind_method("_import_confirm",&EditorSceneImportDialog::_import_confirm); ObjectTypeDB::bind_method("_open_and_import",&EditorSceneImportDialog::_open_and_import); + ObjectTypeDB::bind_method("_root_default_pressed",&EditorSceneImportDialog::_root_default_pressed); + ObjectTypeDB::bind_method("_root_type_pressed",&EditorSceneImportDialog::_root_type_pressed); + ObjectTypeDB::bind_method("_set_root_type",&EditorSceneImportDialog::_set_root_type); + ADD_SIGNAL( MethodInfo("imported",PropertyInfo(Variant::OBJECT,"scene")) ); } - const EditorSceneImportDialog::FlagInfo EditorSceneImportDialog::scene_flag_names[]={ {EditorSceneImportPlugin::SCENE_FLAG_REMOVE_NOIMP,("Actions"),"Remove Nodes (-noimp)",true}, @@ -1162,6 +1217,23 @@ EditorSceneImportDialog::EditorSceneImportDialog(EditorNode *p_editor, EditorSce error_dialog->get_ok()->set_text(TTR("Accept")); // error_dialog->get_cancel()->hide(); + + HBoxContainer *custom_root_hb = memnew( HBoxContainer ); + vbc->add_margin_child(TTR("Custom Root Node Type:"),custom_root_hb); + root_type = memnew(Button); + root_type->set_h_size_flags(SIZE_EXPAND_FILL); + root_type->set_text_align(Button::ALIGN_LEFT); + root_type->connect("pressed",this,"_root_type_pressed"); + custom_root_hb->add_child(root_type); + + root_default = memnew(CheckBox); + root_default->set_text("Auto"); + root_default->set_pressed(true); + root_default->connect("pressed",this,"_root_default_pressed"); + custom_root_hb->add_child(root_default); + + + /* this_import = memnew( OptionButton ); this_import->add_item(TTR("Overwrite Existing Scene")); this_import->add_item(TTR("Overwrite Existing, Keep Materials")); @@ -1175,7 +1247,7 @@ EditorSceneImportDialog::EditorSceneImportDialog(EditorNode *p_editor, EditorSce next_import->add_item(TTR("Keep Existing, Merge with New")); next_import->add_item(TTR("Keep Existing, Ignore New")); vbc->add_margin_child(TTR("Next Time:"),next_import); - +*/ set_hide_on_ok(false); GLOBAL_DEF("import/shared_textures","res://"); @@ -1183,6 +1255,7 @@ EditorSceneImportDialog::EditorSceneImportDialog(EditorNode *p_editor, EditorSce import_hb->add_constant_override("separation",30); + VBoxContainer *ovb = memnew( VBoxContainer); ovb->set_h_size_flags(SIZE_EXPAND_FILL); import_hb->add_child(ovb); @@ -1232,6 +1305,10 @@ EditorSceneImportDialog::EditorSceneImportDialog(EditorNode *p_editor, EditorSce wip_open=false; //texture_options->set_format(EditorImport::IMAGE_FORMAT_C); + root_type_choose = memnew( CreateDialog ); + add_child(root_type_choose); + root_type_choose->set_base_type("Node"); + root_type_choose->connect("create",this,"_set_root_type"); } @@ -1247,7 +1324,7 @@ String EditorSceneImportPlugin::get_name() const { String EditorSceneImportPlugin::get_visible_name() const{ - return "3D Scene"; + return "Scene"; } void EditorSceneImportPlugin::import_dialog(const String& p_from){ @@ -1906,397 +1983,7 @@ Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh> } -void EditorSceneImportPlugin::_merge_existing_node(Node *p_node,Node *p_imported_scene,Set<Ref<Resource> >& checked_resources,Set<Node*> &checked_nodes) { - - - NodePath path = p_node->get_import_path(); - - if (!path.is_empty() && p_imported_scene->has_node(path)) { - - Node *imported_node = p_imported_scene->get_node(path); - - if (imported_node->get_type()==p_node->get_type()) { - //same thing, check what it is - - if (p_node->get_type()=="MeshInstance") { - - //merge mesh instance, this is a special case! - MeshInstance *mi_imported=imported_node->cast_to<MeshInstance>(); - MeshInstance *mi_node=p_node->cast_to<MeshInstance>(); - - Ref<Mesh> mesh_imported = mi_imported->get_mesh(); - Ref<Mesh> mesh_node = mi_node->get_mesh(); - - if (mesh_node.is_null() && mesh_imported.is_valid()) { - - mi_node->set_mesh(mesh_imported); - - } else if (mesh_node.is_valid() && mesh_imported.is_valid()) { - - if (checked_resources.has(mesh_imported)) { - - mi_node->set_mesh(mesh_imported); - } else { - //mix up meshes - //import new geometry but keep materials - for(int i=0;i<mesh_imported->get_surface_count();i++) { - - String name = mesh_imported->surface_get_name(i); - - for(int j=0;j<mesh_node->get_surface_count();j++) { - - Ref<Material> mat = mesh_node->surface_get_material(j); - if (mat.is_valid() && mesh_node->surface_get_name(j)==name ) { - - mesh_imported->surface_set_material(i,mat); - break; - } - } - } - // was imported, do nothing further - checked_resources.insert(mesh_imported); - mi_node->set_mesh(mesh_imported); - } - - } - } else if (p_node->get_type()=="Path") { - //for paths, overwrite path - Path *path_imported =imported_node->cast_to<Path>(); - Path *path_node =p_node->cast_to<Path>(); - - if (path_imported->get_curve().is_valid()) { - - path_node->set_curve(path_imported->get_curve()); - } - } else if (p_node->get_type()=="Portal") { - //for paths, overwrite path - - Portal *portal_imported =imported_node->cast_to<Portal>(); - Portal *portal_node =p_node->cast_to<Portal>(); - - portal_node->set_shape( portal_imported->get_shape() ); - - } else if (p_node->get_type()=="Room") { - //for paths, overwrite path - - Room *room_imported =imported_node->cast_to<Room>(); - Room *room_node =p_node->cast_to<Room>(); - - room_node->set_room( room_imported->get_room() ); - } else if (p_node->get_type()=="Skeleton") { - //for paths, overwrite path - - Skeleton *skeleton_imported =imported_node->cast_to<Skeleton>(); - Skeleton *skeleton_node =p_node->cast_to<Skeleton>(); - - //use imported bones, obviously - skeleton_node->clear_bones(); - for(int i=0;i<skeleton_imported->get_bone_count();i++) { - - skeleton_node->add_bone(skeleton_imported->get_bone_name(i)); - skeleton_node->set_bone_parent(i,skeleton_imported->get_bone_parent(i)); - skeleton_node->set_bone_rest(i,skeleton_imported->get_bone_rest(i)); - //skeleton_node->set_bone_pose(i,skeleton_imported->get_bone_pose(i)); // not in a scene, will throw errors - } - } - else if (p_node->get_type() == "AnimationPlayer") { - //for paths, overwrite path - AnimationPlayer *aplayer_imported = imported_node->cast_to<AnimationPlayer>(); - AnimationPlayer *aplayer_node = p_node->cast_to<AnimationPlayer>(); - - //use imported bones, obviously - List<StringName> anims; - List<StringName> existing_anims; - aplayer_imported->get_animation_list(&anims); - aplayer_node->get_animation_list(&existing_anims); - - //use imported animations - for (List<StringName>::Element *N = anims.front(); N; N = N->next()) { - - Ref<Animation> candidate = aplayer_imported->get_animation(N->get()); - - if (aplayer_node->has_animation(N->get())) { - - Ref<Animation> found = aplayer_node->get_animation(N->get()); - - candidate->set_loop(found->has_loop()); - candidate->set_step(found->get_step()); - - //For each track candidate - for (int i = 0; i < candidate->get_track_count(); i++) { - - NodePath track_path = candidate->track_get_path(i); - // For each track existing - for (int x = 0; x < found->get_track_count(); x++) { - - NodePath path_to_compare = found->track_get_path(x); - - if (track_path.hash() == path_to_compare.hash() && candidate->track_get_type(x) == found->track_get_type(i)) { - - //Tracks matches - if (candidate->track_get_interpolation_type(i) != found->track_get_interpolation_type(x)) - candidate->track_set_interpolation_type(i, found->track_get_interpolation_type(x)); - if (candidate->track_get_type(i) == Animation::TYPE_VALUE && candidate->value_track_is_continuous(i) != found->value_track_is_continuous(x)) - candidate->value_track_set_continuous(i, found->value_track_is_continuous(x)); - - //Key transitions might have changed, but the animation remained unchanged - if (candidate->track_get_key_count(i) == found->track_get_key_count(x)) { - for (int k = 0; k < candidate->track_get_key_count(i); k++) { - - if (candidate->track_get_key_transition(i, k) != found->track_get_key_transition(x, k)) - candidate->track_set_key_transition(i, k, found->track_get_key_transition(x, k)); - } - } - - } - - } - } - - // Append function callbacks and values - for (int x = 0; x < found->get_track_count(); x++) { - if (found->track_get_type(x) == Animation::TYPE_METHOD || found->track_get_type(x) == Animation::TYPE_VALUE) - candidate->add_track(found->track_get_type(x), candidate->get_track_count()); - - for (int k = 0; k < found->track_get_key_count(x); k++) - candidate->track_insert_key(x, found->track_get_key_time(x, k), found->track_get_key_value(x, k), found->track_get_key_transition(x, k)); - } - } - - aplayer_node->add_animation(N->get(), candidate); - } - - } else if (p_node->get_type()=="CollisionShape") { - //for paths, overwrite path - - CollisionShape *collision_imported =imported_node->cast_to<CollisionShape>(); - CollisionShape *collision_node =p_node->cast_to<CollisionShape>(); - - collision_node->set_shape( collision_imported->get_shape() ); - } - } - - if (p_node->cast_to<Spatial>() && imported_node->cast_to<Spatial>()) { - //apply transform if changed - Spatial *snode = p_node->cast_to<Spatial>(); - Spatial *simp = imported_node->cast_to<Spatial>(); - - if (snode->get_import_transform() == snode->get_transform()) { - //not moved, apply new - snode->set_import_transform(simp->get_transform()); - snode->set_transform(simp->get_transform()); - } else if (snode->get_import_transform() == simp->get_import_transform()) { - //do nothing, nothing changed keep local changes - } else { - //changed both, imported and edited, merge - Transform local_xform = snode->get_import_transform().affine_inverse() * snode->get_transform(); - snode->set_import_transform(simp->get_import_transform()); - snode->set_transform(simp->get_import_transform() * local_xform); - } - } - - checked_nodes.insert(imported_node); - - } -#if 0 - else { - - if (p_node!=p_root && p_existing->has_node(p_root->get_path_to(p_node->get_parent()))) { - - Node *parent = p_existing->get_node(p_root->get_path_to(p_node->get_parent())); - NodePath path = p_root->get_path_to(p_node); - - //add it.. because not existing in existing scene - Object *o = ObjectTypeDB::instance(p_existing->get_type()); - Node *n=NULL; - if (o) - n=o->cast_to<Node>(); - - if (n) { - - List<PropertyInfo> pl; - p_existing->get_property_list(&pl); - for(List<PropertyInfo>::Element *E=pl.front();E;E=E->next()) { - if (!(E->get().usage&PROPERTY_USAGE_STORAGE)) - continue; - n->set( E->get().name, p_existing->get(E->get().name) ); - } - - parent->add_child(n); - - valid=true; - } - } - - } -#endif - - for(int i=0;i<p_node->get_child_count();i++) { - _merge_existing_node(p_node->get_child(i),p_imported_scene,checked_resources,checked_nodes); - } -} - - -void EditorSceneImportPlugin::_add_new_nodes(Node *p_node,Node *p_imported,Node *p_imported_scene,Node *p_existing_scene,Set<Node*> &checked_nodes) { - - - for(int i=0;i<p_imported->get_child_count();i++) { - - - Node *imported_node = p_imported->get_child(i); - - if (imported_node->get_owner()!=p_imported_scene) { - // print_line("skipping because not imported at "+String(imported_node->get_name())); - continue; //end of the road - } - - Vector<StringName> nn; - nn.push_back(imported_node->get_name()); - NodePath imported_path(nn,false); - //print_line("check for: "+String(imported_path)); - - if (!p_node->has_node(imported_path) && !checked_nodes.has(imported_node)) { - //not there, re-add it - //add it.. because not existing in existing scene - Object *o = ObjectTypeDB::instance(imported_node->get_type()); - Node *n=NULL; - if (o) - n=o->cast_to<Node>(); - - //print_line("creating node of same type.."); - - if (n) { - - //print_line("copy props and add"); - List<PropertyInfo> pl; - imported_node->get_property_list(&pl); - for(List<PropertyInfo>::Element *E=pl.front();E;E=E->next()) { - if (!(E->get().usage&PROPERTY_USAGE_STORAGE)) - continue; - n->set( E->get().name, imported_node->get(E->get().name) ); - } - - p_node->add_child(n); - n->set_owner(p_existing_scene); - } - - } else { - //print_line("already exists"); - } - - - if (p_node->has_node(imported_path)) { - - Node *other_node = p_node->get_node(imported_path); - - _add_new_nodes(other_node,imported_node,p_imported_scene,p_existing_scene,checked_nodes); - - } - - } -} - - -void EditorSceneImportPlugin::_merge_scenes(Node *p_node,Node *p_imported) { - - Set<Ref<Resource> > checked_resources; - Set<Node*> checked_nodes; - _merge_existing_node(p_node,p_imported,checked_resources,checked_nodes); - _add_new_nodes(p_node,p_imported,p_imported,p_node,checked_nodes); - //add existing.. ? -} - - -void EditorSceneImportPlugin::_scan_materials(Node*p_base,Node *p_node,Map<String,Ref<Material> > &mesh_materials,Map<String,Ref<Material> >& override_materials) { - - if (!p_base && p_node->get_owner()!=p_base) - return; - MeshInstance *mi=p_node->cast_to<MeshInstance>(); - - if (mi) { - if (mi->get_material_override().is_valid()) { - String path = p_base->get_path_to(p_node); - override_materials[path]=mi->get_material_override(); - } - Ref<Mesh> mesh = mi->get_mesh(); - if (mesh.is_valid()) { - - for(int i=0;i<mesh->get_surface_count();i++) { - - String name = mesh->get_name()+":"+mesh->surface_get_name(i); - if (!mesh_materials.has(name)) { - mesh_materials[name]=mesh->surface_get_material(i); - } - } - } - } - - for(int i=0;i<p_node->get_child_count();i++) { - _scan_materials(p_base,p_node->get_child(i),mesh_materials,override_materials); - } -} - - -void EditorSceneImportPlugin::_apply_materials(Node*p_base,Node *p_node,Map<String,Ref<Material> > &mesh_materials,Map<String,Ref<Material> >& override_materials,Set<Ref<Mesh> >& meshes_processed) { - - if (p_node!=p_base && p_node->get_owner()!=p_base) - return; - - MeshInstance *mi=p_node->cast_to<MeshInstance>(); - - if (mi) { - - print_line("is mesh "+String(p_node->get_name())); - String path = p_base->get_path_to(p_node); - if (override_materials.has(path)) { - print_line("is in material overrides"); - mi->set_material_override(override_materials[path]); - } - - Ref<Mesh> mesh = mi->get_mesh(); - if (mesh.is_valid() && !meshes_processed.has(mesh)) { - print_line("mesh was not processed"); - meshes_processed.insert(mesh); - for(int i=0;i<mesh->get_surface_count();i++) { - - String name = mesh->get_name()+":"+mesh->surface_get_name(i); - print_line("name for surface "+itos(i)+": "+name); - if (mesh_materials.has(name)) { - - Ref<Material> mat = mesh_materials[name]; - mesh->surface_set_material(i,mat); - print_line("overriding!"); - } - } - } - } - - for(int i=0;i<p_node->get_child_count();i++) { - _apply_materials(p_base,p_node->get_child(i),mesh_materials,override_materials,meshes_processed); - } -} - -void EditorSceneImportPlugin::_merge_materials(Node *p_node,Node *p_imported) { - - Map<String,Ref<Material> > mesh_materials; - Map<String,Ref<Material> > override_materials; - - _scan_materials(p_node,p_node,mesh_materials,override_materials); - - for (Map<String,Ref<Material> >::Element *E=mesh_materials.front();E;E=E->next()) { - print_line("Mats: "+String(E->key())); - } - - for (Map<String,Ref<Material> >::Element *E=override_materials.front();E;E=E->next()) { - print_line("Overrides: "+String(E->key())); - } - - Set<Ref<Mesh> > mp; - _apply_materials(p_imported,p_imported,mesh_materials,override_materials,mp); - - -} #if 0 @@ -2397,6 +2084,21 @@ Error EditorSceneImportPlugin::import1(const Ref<ResourceImportMetadata>& p_from return err; } + if (from->has_option("root_type")) { + String type = from->get_option("root_type"); + Object *base = ObjectTypeDB::instance(type); + Node *base_node = NULL; + if (base) + base_node=base->cast_to<Node>(); + + if (base_node) { + + scene->replace_by(base_node); + memdelete(scene); + scene=base_node; + } + } + _tag_import_paths(scene,scene); *r_node=scene; @@ -2839,66 +2541,12 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c } } - Error err = EditorTextureImportPlugin::get_singleton(EditorTextureImportPlugin::MODE_TEXTURE_3D)->import(target_path,imd); + Error err = EditorTextureImportPlugin::get_singleton()->import(target_path,imd); } } - /// BEFORE SAVING - MERGE - - - if (import_action!=SCENE_UPDATE_REPLACE_WITH_NEW) { - - - progress.step(TTR("Merging.."),103); - - FileAccess *fa = FileAccess::create(FileAccess::ACCESS_RESOURCES); - - if (fa->file_exists(p_dest_path)) { - - - //try to merge - - Ref<PackedScene> s = ResourceLoader::load(p_dest_path); - if (s.is_valid()) { - - Node *existing = s->instance(true); - - if (existing) { - - - switch(import_action) { - - case SCENE_UPDATE_REPLACE_WITH_NEW: break; - case SCENE_UPDATE_REPLACE_WITH_NEW_KEEP_MATERIALS: { - - _merge_materials(existing,scene); - memdelete(existing); - - } break; - case SCENE_UPDATE_KEEP_OLD_MERGE_CHANGES: { - - _merge_scenes(existing,scene); - memdelete(scene); - scene=existing; - - } break; - case SCENE_UPDATE_KEEP_OLD: { - - memdelete(scene); - scene=existing; - } break; - } - - } - } - - } - - memdelete(fa); - } - progress.step(TTR("Saving.."),104); @@ -2957,6 +2605,30 @@ void EditorSceneImportPlugin::add_importer(const Ref<EditorSceneImporter>& p_imp importers.push_back(p_importer); } +void EditorSceneImportPlugin::import_from_drop(const Vector<String>& p_drop,const String& p_dest_path) { + + List<String> extensions; + for(int i=0;i<importers.size();i++) { + importers[i]->get_extensions(&extensions); + } + //bool warn_compatible=false; + for(int i=0;i<p_drop.size();i++) { + + String extension = p_drop[i].extension().to_lower(); + + for(List<String>::Element *E=extensions.front();E;E=E->next()) { + + if (E->get()==extension) { + + dialog->popup_import(String()); + dialog->setup_popup(p_drop[i],p_dest_path); + return; + } + } + } + +} + EditorSceneImportPlugin::EditorSceneImportPlugin(EditorNode* p_editor) { diff --git a/tools/editor/io_plugins/editor_scene_import_plugin.h b/tools/editor/io_plugins/editor_scene_import_plugin.h index a1a090de7e..8a2d30f1f6 100644 --- a/tools/editor/io_plugins/editor_scene_import_plugin.h +++ b/tools/editor/io_plugins/editor_scene_import_plugin.h @@ -45,6 +45,7 @@ #include "tools/editor/io_plugins/editor_texture_import_plugin.h" #include "scene/resources/animation.h" + class EditorNode; class EditorSceneImportDialog; @@ -111,16 +112,8 @@ class EditorSceneImportPlugin : public EditorImportPlugin { void _create_clips(Node *scene, const Array& p_clips, bool p_bake_all); void _filter_anim_tracks(Ref<Animation> anim,Set<String> &keep); void _filter_tracks(Node *scene, const String& p_text); - void _merge_existing_node(Node *p_node,Node *p_imported_scene,Set<Ref<Resource> >& checked_resources,Set<Node*> &checked_nodes); - - void _add_new_nodes(Node *p_node,Node *p_imported,Node *p_imported_scene,Node *p_existing_scene,Set<Node*> &checked_nodes); void _optimize_animations(Node *scene, float p_max_lin_error,float p_max_ang_error,float p_max_angle); - void _merge_scenes(Node *p_node, Node *p_imported); - void _scan_materials(Node*p_base,Node *p_node,Map<String,Ref<Material> > &mesh_materials,Map<String,Ref<Material> >& override_materials); - void _apply_materials(Node*p_base,Node *p_node,Map<String,Ref<Material> > &mesh_materials,Map<String,Ref<Material> >& override_materials,Set<Ref<Mesh> >& meshes_processed); - void _merge_materials(Node *p_node,Node *p_imported); - void _tag_import_paths(Node *p_scene,Node *p_node); public: @@ -150,13 +143,6 @@ public: SCENE_FLAG_CONVERT_NORMALMAPS_TO_XY=1<<30, }; - enum SceneUpdate { - SCENE_UPDATE_REPLACE_WITH_NEW, - SCENE_UPDATE_REPLACE_WITH_NEW_KEEP_MATERIALS, - SCENE_UPDATE_KEEP_OLD_MERGE_CHANGES, - SCENE_UPDATE_KEEP_OLD, - }; - virtual String get_name() const; virtual String get_visible_name() const; @@ -169,6 +155,8 @@ public: void add_importer(const Ref<EditorSceneImporter>& p_importer); const Vector<Ref<EditorSceneImporter> >& get_importers() { return importers; } + virtual void import_from_drop(const Vector<String>& p_drop,const String& p_dest_path); + EditorSceneImportPlugin(EditorNode* p_editor=NULL); diff --git a/tools/editor/io_plugins/editor_texture_import_plugin.cpp b/tools/editor/io_plugins/editor_texture_import_plugin.cpp index 0e2d35b9f2..c7598466d5 100644 --- a/tools/editor/io_plugins/editor_texture_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_texture_import_plugin.cpp @@ -35,6 +35,9 @@ #include "io/md5.h" #include "io/marshalls.h" #include "globals.h" +#include "scene/gui/check_button.h" +#include "scene/gui/button_group.h" +#include "scene/gui/margin_container.h" static const char *flag_names[]={ ("Streaming Format"), @@ -164,12 +167,13 @@ void EditorImportTextureOptions::_notification(int p_what) { void EditorImportTextureOptions::show_2d_notice() { - notice_for_2d->show(); + //notice_for_2d->show(); } EditorImportTextureOptions::EditorImportTextureOptions() { + add_constant_override("separation",3); updating=false; format = memnew( OptionButton ); @@ -223,12 +227,6 @@ EditorImportTextureOptions::EditorImportTextureOptions() { add_margin_child(TTR("Texture Options"),flags,true); - notice_for_2d = memnew( Label ); - notice_for_2d->set_text(TTR("NOTICE: You are not forced to import textures for 2D projects. Just copy your .jpg or .png files to your project, and change export options later. Atlases can be generated on export too.")); - notice_for_2d->set_custom_minimum_size(Size2(0,50)); - notice_for_2d->set_autowrap(true); - add_child(notice_for_2d); - notice_for_2d->hide(); } @@ -242,8 +240,13 @@ class EditorTextureImportDialog : public ConfirmationDialog { OBJ_TYPE(EditorTextureImportDialog,ConfirmationDialog); + + HBoxContainer *mode_hb; + CheckBox *mode_check[EditorTextureImportPlugin::MODE_MAX]; + EditorImportTextureOptions *texture_options; + EditorTextureImportPlugin::Mode mode; //EditorNode *editor; LineEdit *import_path; @@ -255,11 +258,16 @@ class EditorTextureImportDialog : public ConfirmationDialog { ConfirmationDialog *error_dialog; CheckButton *crop_source; SpinBox *size; - bool atlas; - bool large; + + MarginContainer *size_mc; + Label* size_label; + + Label* source_label; + Label *notice_for_2d; EditorTextureImportPlugin *plugin; + void _mode_changed(int p_mode); void _choose_files(const Vector<String>& p_path); void _choose_file(const String& p_path); void _choose_save_dir(const String& p_path); @@ -274,9 +282,23 @@ protected: static void _bind_methods(); public: + + void setup_multiple_import_3d(const Vector<String>& p_path,const String& p_dest) { + + _mode_changed(EditorTextureImportPlugin::MODE_TEXTURE_3D); + _choose_files(p_path); + _choose_save_dir(p_dest); + } + + void add_sources_and_dest(const Vector<String>& p_path,const String& p_dest) { + + _choose_files(p_path); + _choose_save_dir(p_dest); + } + Error import(const String& p_from, const String& p_to, const String& p_preset); void popup_import(const String &p_from=String()); - EditorTextureImportDialog(EditorTextureImportPlugin *p_plugin=NULL,bool p_2d=false,bool p_atlas=false,bool p_large=false); + EditorTextureImportDialog(EditorTextureImportPlugin *p_plugin=NULL); }; @@ -349,13 +371,13 @@ void EditorTextureImportDialog::_import() { } - if (!atlas && !large && !DirAccess::exists(save_path->get_text())) { + if (mode!=EditorTextureImportPlugin::MODE_ATLAS && mode!=EditorTextureImportPlugin::MODE_LARGE && !DirAccess::exists(save_path->get_text())) { error_dialog->set_text(TTR("Target path must exist.")); error_dialog->popup_centered_minsize(); return; } - if (atlas) { //atlas + if (mode==EditorTextureImportPlugin::MODE_ATLAS) { //atlas if (files.size()==0) { @@ -378,6 +400,7 @@ void EditorTextureImportDialog::_import() { imd->set_option("atlas_size",int(size->get_val())); imd->set_option("large",false); imd->set_option("crop",crop_source->is_pressed()); + imd->set_option("mode",mode); Error err = plugin->import(dst_file,imd); if (err) { @@ -387,7 +410,7 @@ void EditorTextureImportDialog::_import() { return; } - } else if (large) { //atlas + } else if (mode==EditorTextureImportPlugin::MODE_LARGE) { //large if (files.size()!=1) { @@ -410,6 +433,7 @@ void EditorTextureImportDialog::_import() { imd->set_option("large",true); imd->set_option("large_cell_size",int(size->get_val())); imd->set_option("crop",crop_source->is_pressed()); + imd->set_option("mode",mode); Error err = plugin->import(dst_file,imd); if (err) { @@ -434,6 +458,7 @@ void EditorTextureImportDialog::_import() { imd->set_option("quality",texture_options->get_quality()); imd->set_option("atlas",false); imd->set_option("large",false); + imd->set_option("mode",mode); Error err = plugin->import(dst_file,imd); if (err) { @@ -456,7 +481,7 @@ void EditorTextureImportDialog::_browse() { void EditorTextureImportDialog::_browse_target() { - if (atlas || large) { + if (mode==EditorTextureImportPlugin::MODE_ATLAS || mode==EditorTextureImportPlugin::MODE_LARGE) { save_file_select->popup_centered_ratio(); } else { save_select->popup_centered_ratio(); @@ -467,12 +492,28 @@ void EditorTextureImportDialog::_browse_target() { void EditorTextureImportDialog::popup_import(const String& p_from) { - popup_centered(Size2(400,400)); + popup_centered(Size2(600,500)); if (p_from!="") { Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_from); ERR_FAIL_COND(!rimd.is_valid()); - if (plugin->get_mode()==EditorTextureImportPlugin::MODE_ATLAS || plugin->get_mode()==EditorTextureImportPlugin::MODE_LARGE) + if (rimd->has_option("mode")) { + //new imported stuff uses this option + _mode_changed(rimd->get_option("mode")); + } else { + //this one is for compatibility, will have to guess it + if (rimd->has_option("atlas") && rimd->get_option("atlas")) { + _mode_changed(EditorTextureImportPlugin::MODE_ATLAS); + } else if (rimd->has_option("large") && rimd->get_option("large")) { + _mode_changed(EditorTextureImportPlugin::MODE_LARGE); + } else { + //guess by usage of mipmaps..? + _mode_changed(EditorTextureImportPlugin::MODE_TEXTURE_2D); + } + + } + + if (mode==EditorTextureImportPlugin::MODE_ATLAS || mode==EditorTextureImportPlugin::MODE_LARGE) save_path->set_text(p_from); else save_path->set_text(p_from.get_base_dir()); @@ -518,6 +559,81 @@ Error EditorTextureImportDialog::import(const String& p_from, const String& p_to return OK; } +void EditorTextureImportDialog::_mode_changed(int p_mode) { + + mode = EditorTextureImportPlugin::Mode(p_mode); + + for(int i=0;i<EditorTextureImportPlugin::MODE_MAX;i++) { + mode_check[i]->set_pressed(i==mode); + } + + if (p_mode==EditorTextureImportPlugin::MODE_ATLAS) { + + size_label->set_text(TTR("Max Texture Size:")); + size->set_val(2048); + crop_source->show(); + size_label->show(); + size->show(); + + texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA|EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS|EditorTextureImportPlugin::IMAGE_FLAG_FILTER); + texture_options->set_quality(0.7); + texture_options->set_format(EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSY); + set_title(TTR("Import Textures for Atlas (2D)")); + + } else { + crop_source->hide(); + } + + + if (p_mode==EditorTextureImportPlugin::MODE_LARGE) { + + size_label->set_text(TTR("Cell Size:")); + size->set_val(256); + size_label->show(); + size->show(); + + file_select->set_mode(EditorFileDialog::MODE_OPEN_FILE); + save_file_select->add_filter("*.ltex;"+TTR("Large Texture")); + + texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA|EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS|EditorTextureImportPlugin::IMAGE_FLAG_FILTER); + texture_options->set_quality(0.7); + texture_options->set_format(EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSLESS); + set_title(TTR("Import Large Textures (2D)")); + source_label->set_text(TTR("Source Texture")); + + } else { + file_select->set_mode(EditorFileDialog::MODE_OPEN_FILES); + save_file_select->add_filter("*.tex;"+TTR("Base Atlas Texture")); + source_label->set_text(TTR("Source Texture(s)")); + } + + if (p_mode==EditorTextureImportPlugin::MODE_TEXTURE_2D) { + + size_label->hide(); + size->hide(); + + texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS|EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA|EditorTextureImportPlugin::IMAGE_FLAG_FILTER); + texture_options->set_quality(0.7); + texture_options->set_format(EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSY); + notice_for_2d->show(); + set_title(TTR("Import Textures for 2D")); + + } else { + notice_for_2d->hide(); + } + + if (p_mode==EditorTextureImportPlugin::MODE_TEXTURE_3D) { + + size_label->hide(); + size->hide(); + //texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_); + //texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS); + texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA|EditorTextureImportPlugin::IMAGE_FLAG_FILTER|EditorTextureImportPlugin::IMAGE_FLAG_REPEAT); + texture_options->set_format(EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM); + set_title(TTR("Import Textures for 3D")); + } +} + void EditorTextureImportDialog::_bind_methods() { @@ -527,28 +643,64 @@ void EditorTextureImportDialog::_bind_methods() { ObjectTypeDB::bind_method("_import",&EditorTextureImportDialog::_import); ObjectTypeDB::bind_method("_browse",&EditorTextureImportDialog::_browse); ObjectTypeDB::bind_method("_browse_target",&EditorTextureImportDialog::_browse_target); + ObjectTypeDB::bind_method("_mode_changed",&EditorTextureImportDialog::_mode_changed); // ADD_SIGNAL( MethodInfo("imported",PropertyInfo(Variant::OBJECT,"scene")) ); } -EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin* p_plugin, bool p_2d, bool p_atlas,bool p_large) { +EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin* p_plugin) { + + + - atlas=p_atlas; - large=p_large; plugin=p_plugin; set_title(TTR("Import Textures")); + mode_hb = memnew( HBoxContainer ); + add_child(mode_hb); + set_child_rect(mode_hb); + + VBoxContainer *vbcg = memnew( VBoxContainer); + + + mode_hb->add_child(vbcg); + mode_hb->add_constant_override("separation",15); + ButtonGroup *bg = memnew( ButtonGroup ); + vbcg->add_margin_child("Import Mode",bg); + + for(int i=0;i<EditorTextureImportPlugin::MODE_MAX;i++) { + String mode_name[EditorTextureImportPlugin::MODE_MAX]={ + TTR("2D Texture"), + TTR("3D Texture"), + TTR("Atlas Texture"), + TTR("Large Texture") + }; + + + mode_check[i]=memnew(CheckBox); + bg->add_child(mode_check[i]); + mode_check[i]->set_text(mode_name[i]); + mode_check[i]->connect("pressed",this,"_mode_changed",varray(i)); + } VBoxContainer *vbc = memnew(VBoxContainer); - add_child(vbc); - set_child_rect(vbc); + mode_hb->add_child(vbc); + vbc->set_h_size_flags(SIZE_EXPAND_FILL); + vbc->add_constant_override("separation",4); + notice_for_2d = memnew( Label ); + notice_for_2d->set_text(TTR("NOTICE: Importing 2D textures is not mandatory. Just copy png/jpg files to the project.")); + //notice_for_2d->set_custom_minimum_size(Size2(0,50)); + notice_for_2d->set_autowrap(true); + notice_for_2d->hide(); + vbcg->add_child(notice_for_2d); + notice_for_2d->set_v_size_flags(SIZE_EXPAND_FILL); + notice_for_2d->set_valign(Label::VALIGN_BOTTOM); VBoxContainer *source_vb=memnew(VBoxContainer); - if (large) - vbc->add_margin_child(TTR("Source Texture:"),source_vb); - else - vbc->add_margin_child(TTR("Source Texture(s):"),source_vb); + MarginContainer *source_mc = vbc->add_margin_child(TTR("Source Texture(s):"),source_vb); + + source_label = vbc->get_child(source_mc->get_index()-1)->cast_to<Label>(); HBoxContainer *hbc = memnew( HBoxContainer ); source_vb->add_child(hbc); @@ -560,8 +712,6 @@ EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin* crop_source->set_pressed(true); source_vb->add_child(crop_source); crop_source->set_text(TTR("Crop empty space.")); - if (!p_atlas) - crop_source->hide(); Button * import_choose = memnew( Button ); @@ -577,13 +727,10 @@ EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin* size->set_min(128); size->set_max(16384); - if (p_atlas) { - size->set_val(2048); - vbc->add_margin_child(TTR("Max Texture Size:"),size); - } else { - size->set_val(256); - vbc->add_margin_child(TTR("Cell Size:"),size); - } + + size->set_val(256); + size_mc=vbc->add_margin_child(TTR("Cell Size:"),size); + size_label=vbc->get_child(size_mc->get_index()-1)->cast_to<Label>(); save_path = memnew( LineEdit ); @@ -599,10 +746,7 @@ EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin* file_select = memnew(EditorFileDialog); file_select->set_access(EditorFileDialog::ACCESS_FILESYSTEM); add_child(file_select); - if (!large) - file_select->set_mode(EditorFileDialog::MODE_OPEN_FILES); - else - file_select->set_mode(EditorFileDialog::MODE_OPEN_FILE); + file_select->connect("files_selected", this,"_choose_files"); file_select->connect("file_selected", this,"_choose_file"); @@ -611,10 +755,7 @@ EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin* add_child(save_file_select); save_file_select->set_mode(EditorFileDialog::MODE_SAVE_FILE); save_file_select->clear_filters(); - if (large) - save_file_select->add_filter("*.ltex;"+TTR("Large Texture")); - else - save_file_select->add_filter("*.tex;"+TTR("Base Atlas Texture")); + save_file_select->connect("file_selected", this,"_choose_save_dir"); save_select = memnew( EditorDirDialog ); @@ -641,36 +782,7 @@ EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin* vbc->add_child(texture_options); texture_options->set_v_size_flags(SIZE_EXPAND_FILL); - if (atlas) { - - texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA|EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS|EditorTextureImportPlugin::IMAGE_FLAG_FILTER); - texture_options->set_quality(0.7); - texture_options->set_format(EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSY); - //texture_options->show_2d_notice(); - set_title(TTR("Import Textures for Atlas (2D)")); - } else if (large) { - - texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA|EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS|EditorTextureImportPlugin::IMAGE_FLAG_FILTER); - texture_options->set_quality(0.7); - texture_options->set_format(EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSLESS); - texture_options->show_2d_notice(); - set_title(TTR("Import Large Textures (2D)")); - - } else if (p_2d) { - - texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS|EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA|EditorTextureImportPlugin::IMAGE_FLAG_FILTER); - texture_options->set_quality(0.7); - texture_options->set_format(EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_DISK_LOSSY); - texture_options->show_2d_notice(); - set_title(TTR("Import Textures for 2D")); - } else { - - //texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_); - //texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS); - texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA|EditorTextureImportPlugin::IMAGE_FLAG_FILTER|EditorTextureImportPlugin::IMAGE_FLAG_REPEAT); - texture_options->set_format(EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM); - set_title(TTR("Import Textures for 3D")); - } + _mode_changed(EditorTextureImportPlugin::MODE_TEXTURE_3D); // GLOBAL_DEF("import/shared_textures","res://"); @@ -686,6 +798,8 @@ EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin* String EditorTextureImportPlugin::get_name() const { + return "texture"; +#if 0 //old names, kept for compatibility reference switch(mode) { case MODE_TEXTURE_2D: { @@ -707,34 +821,14 @@ String EditorTextureImportPlugin::get_name() const { } - return ""; + return ""; +#endif } String EditorTextureImportPlugin::get_visible_name() const { - switch(mode) { - case MODE_TEXTURE_2D: { - - return "2D Texture"; - } break; - case MODE_TEXTURE_3D: { - - return "3D Texture"; - - } break; - case MODE_ATLAS: { - - return "2D Atlas Texture"; - } break; - case MODE_LARGE: { - - return "2D Large Texture"; - } break; - - } - - return ""; + return "Texture"; } void EditorTextureImportPlugin::import_dialog(const String& p_from) { @@ -1626,15 +1720,93 @@ Vector<uint8_t> EditorTextureImportPlugin::custom_export(const String& p_path, c return ret; } +void EditorTextureImportPlugin::import_from_drop(const Vector<String>& p_drop,const String& p_dest_path) { + + Vector<String> valid; + + List<String> valid_extensions; + ImageLoader::get_recognized_extensions(&valid_extensions); + for(int i=0;i<p_drop.size();i++) { + + String extension=p_drop[i].extension().to_lower(); + + for (List<String>::Element *E=valid_extensions.front();E;E=E->next()) { + + if (E->get()==extension) { + valid.push_back(p_drop[i]); + break; + } + } + } + + if (valid.size()) { + dialog->popup_import(); + dialog->setup_multiple_import_3d(valid,p_dest_path); + } +} + +void EditorTextureImportPlugin::reimport_multiple_files(const Vector<String>& p_list) { + + Vector<String> valid; + + + bool warning=false; + for(int i=0;i<p_list.size();i++) { + + Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_list[i]); + String type = rimd->get_editor(); + if (type=="texture" || type.begins_with("texture_")) { + + if ((rimd->has_option("atlas") && rimd->get_option("atlas")) || (rimd->has_option("large") && rimd->get_option("large"))) { + warning=true; + continue; + } + + valid.push_back(p_list[i]); + } + } + + if (valid.size()) { + + dialog->popup_import(valid[0]); + + Vector<String> sources; + for(int i=0;i<valid.size();i++) { + int idx; + EditorFileSystemDirectory *efsd = EditorFileSystem::get_singleton()->find_file(valid[i],&idx); + if (efsd) { + for(int j=0;j<efsd->get_source_count(idx);j++) { + String file = expand_source_path(efsd->get_source_file(idx,j)); + if (sources.find(file)==-1) { + sources.push_back(file); + } + + } + } + } + + if (sources.size()) { + + dialog->add_sources_and_dest(sources,valid[0].get_base_dir()); + } + } +} + +bool EditorTextureImportPlugin::can_reimport_multiple_files() const { + + return true; + +} + + -EditorTextureImportPlugin *EditorTextureImportPlugin::singleton[EditorTextureImportPlugin::MODE_MAX]={NULL,NULL,NULL,NULL}; +EditorTextureImportPlugin *EditorTextureImportPlugin::singleton=NULL; -EditorTextureImportPlugin::EditorTextureImportPlugin(EditorNode *p_editor, Mode p_mode) { +EditorTextureImportPlugin::EditorTextureImportPlugin(EditorNode *p_editor) { - singleton[p_mode]=this; - editor=p_editor; - mode=p_mode; - dialog = memnew( EditorTextureImportDialog(this,p_mode==MODE_TEXTURE_2D || p_mode==MODE_ATLAS || p_mode==MODE_LARGE,p_mode==MODE_ATLAS,p_mode==MODE_LARGE) ); + singleton=this; + editor=p_editor; + dialog = memnew( EditorTextureImportDialog(this) ); editor->get_gui_base()->add_child(dialog); } diff --git a/tools/editor/io_plugins/editor_texture_import_plugin.h b/tools/editor/io_plugins/editor_texture_import_plugin.h index cb63ba98c8..5c8abd10a4 100644 --- a/tools/editor/io_plugins/editor_texture_import_plugin.h +++ b/tools/editor/io_plugins/editor_texture_import_plugin.h @@ -64,10 +64,10 @@ public: private: - Mode mode; + EditorNode *editor; EditorTextureImportDialog *dialog; - static EditorTextureImportPlugin *singleton[MODE_MAX]; + static EditorTextureImportPlugin *singleton; //used by other importers such as mesh Error _process_texture_data(Ref<ImageTexture> &texture, int format, float quality, int flags,EditorExportPlatform::ImageCompression p_compr,int tex_flags,float shrink); @@ -75,7 +75,7 @@ private: public: - static EditorTextureImportPlugin *get_singleton(Mode p_mode) { return singleton[p_mode]; } + static EditorTextureImportPlugin *get_singleton() { return singleton; } enum ImageFormat { @@ -100,7 +100,6 @@ public: IMAGE_FLAG_USE_ANISOTROPY=1024, //convert image to linear }; - Mode get_mode() const { return mode; } virtual String get_name() const; virtual String get_visible_name() const; virtual void import_dialog(const String& p_from=""); @@ -108,8 +107,11 @@ public: virtual Error import2(const String& p_path, const Ref<ResourceImportMetadata>& p_from,EditorExportPlatform::ImageCompression p_compr, bool p_external=false); virtual Vector<uint8_t> custom_export(const String& p_path,const Ref<EditorExportPlatform> &p_platform); + virtual void import_from_drop(const Vector<String>& p_drop,const String& p_dest_path); + virtual void reimport_multiple_files(const Vector<String>& p_list); + virtual bool can_reimport_multiple_files() const; - EditorTextureImportPlugin(EditorNode* p_editor=NULL,Mode p_mode=MODE_TEXTURE_2D); + EditorTextureImportPlugin(EditorNode* p_editor=NULL); }; @@ -134,7 +136,7 @@ class EditorImportTextureOptions : public VBoxContainer { HSlider *quality; Tree *flags; Vector<TreeItem*> items; - Label *notice_for_2d; + bool updating; diff --git a/tools/editor/io_plugins/editor_translation_import_plugin.cpp b/tools/editor/io_plugins/editor_translation_import_plugin.cpp index b57e4cb84c..282153fa73 100644 --- a/tools/editor/io_plugins/editor_translation_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_translation_import_plugin.cpp @@ -394,6 +394,26 @@ void EditorTranslationImportPlugin::import_dialog(const String& p_from) { dialog->popup_import(p_from); } + + +void EditorTranslationImportPlugin::import_from_drop(const Vector<String>& p_drop, const String &p_dest_path) { + + + for(int i=0;i<p_drop.size();i++) { + String ext = p_drop[i].extension().to_lower(); + + if (ext=="csv") { + + import_dialog(); + dialog->_choose_file(p_drop[i]); + dialog->_choose_save_dir(p_dest_path); + break; + } + } + + +} + Error EditorTranslationImportPlugin::import(const String& p_path, const Ref<ResourceImportMetadata>& p_from) { Ref<ResourceImportMetadata> from = p_from; diff --git a/tools/editor/io_plugins/editor_translation_import_plugin.h b/tools/editor/io_plugins/editor_translation_import_plugin.h index cadcdc03b3..532f2cedcc 100644 --- a/tools/editor/io_plugins/editor_translation_import_plugin.h +++ b/tools/editor/io_plugins/editor_translation_import_plugin.h @@ -46,6 +46,7 @@ public: virtual String get_visible_name() const; virtual void import_dialog(const String& p_from=""); virtual Error import(const String& p_path, const Ref<ResourceImportMetadata>& p_from); + void import_from_drop(const Vector<String>& p_drop, const String &p_dest_path); EditorTranslationImportPlugin(EditorNode* p_editor); diff --git a/tools/editor/plugins/mesh_editor_plugin.cpp b/tools/editor/plugins/mesh_editor_plugin.cpp index c4f44f6082..ecf17fec19 100644 --- a/tools/editor/plugins/mesh_editor_plugin.cpp +++ b/tools/editor/plugins/mesh_editor_plugin.cpp @@ -71,6 +71,22 @@ void MeshEditor::edit(Ref<Mesh> p_mesh) { rot_x=0; rot_y=0; _update_rotation(); + + AABB aabb= mesh->get_aabb(); + Vector3 ofs = aabb.pos + aabb.size*0.5; + aabb.pos-=ofs; + float m = MAX(aabb.size.x,aabb.size.y)*0.5; + if (m!=0) { + m=1.0/m; + m*=0.5; + //print_line("scale: "+rtos(m)); + Transform xform; + xform.basis.scale(Vector3(m,m,m)); + xform.origin=-xform.basis.xform(ofs); //-ofs*m; + xform.origin.z-=aabb.size.z*2; + mesh_instance->set_transform(xform); + } + } } diff --git a/tools/editor/property_editor.cpp b/tools/editor/property_editor.cpp index afc6396ab3..ddbaad5ea1 100644 --- a/tools/editor/property_editor.cpp +++ b/tools/editor/property_editor.cpp @@ -1673,6 +1673,7 @@ void CustomPropertyEditor::config_value_editors(int p_amount, int p_columns,int } + void CustomPropertyEditor::_bind_methods() { ObjectTypeDB::bind_method("_focus_enter", &CustomPropertyEditor::_focus_enter); @@ -1691,6 +1692,7 @@ void CustomPropertyEditor::_bind_methods() { ObjectTypeDB::bind_method( "_menu_option",&CustomPropertyEditor::_menu_option); + ADD_SIGNAL( MethodInfo("variant_changed") ); ADD_SIGNAL( MethodInfo("resource_edit_request") ); } @@ -2180,6 +2182,11 @@ void PropertyEditor::set_item_text(TreeItem *p_item, int p_type, const String& p } } + if (!res->is_type("Texture")) { + //texture already previews via itself + EditorResourcePreview::get_singleton()->queue_edited_resource_preview(res,this,"_resource_preview_done",p_item->get_instance_ID()); + } + } @@ -3357,6 +3364,10 @@ void PropertyEditor::update_tree() { } else if (res.is_valid()) { item->set_tooltip(1,res->get_name()+" ("+res->get_type()+")"); } + if (!res->is_type("Texture")) { + //texture already previews via itself + EditorResourcePreview::get_singleton()->queue_edited_resource_preview(res,this,"_resource_preview_done",item->get_instance_ID()); + } } @@ -3870,6 +3881,29 @@ void PropertyEditor::_filter_changed(const String& p_text) { update_tree(); } + + +void PropertyEditor::_resource_preview_done(const String& p_path,const Ref<Texture>& p_preview,Variant p_ud) { + + if (p_preview.is_null()) + return; //don't bother with empty preview + + ObjectID id = p_ud; + Object *obj = ObjectDB::get_instance(id); + + if (!obj) + return; + + TreeItem *ti = obj->cast_to<TreeItem>(); + + ERR_FAIL_COND(!ti); + + int tw = EditorSettings::get_singleton()->get("property_editor/texture_preview_width"); + + ti->set_icon(1,p_preview); //should be scaled I think? + ti->set_icon_max_width(1,tw); + ti->set_text(1,""); +} void PropertyEditor::_bind_methods() { ObjectTypeDB::bind_method( "_item_edited",&PropertyEditor::_item_edited); @@ -3884,6 +3918,7 @@ void PropertyEditor::_bind_methods() { ObjectTypeDB::bind_method( "_set_range_def",&PropertyEditor::_set_range_def); ObjectTypeDB::bind_method( "_filter_changed",&PropertyEditor::_filter_changed); ObjectTypeDB::bind_method( "update_tree",&PropertyEditor::update_tree); + ObjectTypeDB::bind_method( "_resource_preview_done",&PropertyEditor::_resource_preview_done); ObjectTypeDB::bind_method(_MD("get_drag_data_fw"), &PropertyEditor::get_drag_data_fw); ObjectTypeDB::bind_method(_MD("can_drop_data_fw"), &PropertyEditor::can_drop_data_fw); diff --git a/tools/editor/property_editor.h b/tools/editor/property_editor.h index ac58011d43..a909b5ccd3 100644 --- a/tools/editor/property_editor.h +++ b/tools/editor/property_editor.h @@ -131,6 +131,7 @@ class CustomPropertyEditor : public Popup { void config_value_editors(int p_amount, int p_columns,int p_label_w,const List<String>& p_strings); void config_action_buttons(const List<String>& p_strings); + protected: void _notification(int p_what); @@ -231,6 +232,7 @@ class PropertyEditor : public Control { bool can_drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from) const; void drop_data_fw(const Point2& p_point,const Variant& p_data,Control* p_from); + void _resource_preview_done(const String& p_path,const Ref<Texture>& p_preview,Variant p_ud); UndoRedo *undo_redo; protected: diff --git a/tools/editor/scene_tree_dock.cpp b/tools/editor/scene_tree_dock.cpp index 517162b81e..3e36a30361 100644 --- a/tools/editor/scene_tree_dock.cpp +++ b/tools/editor/scene_tree_dock.cpp @@ -542,6 +542,10 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { } } break; + case TOOL_MERGE_FROM_SCENE: { + + EditorNode::get_singleton()->merge_from_scene(); + } break; case TOOL_NEW_SCENE_FROM: { Node *scene = editor_data->get_edited_scene_root(); @@ -1696,6 +1700,7 @@ void SceneTreeDock::_tree_rmb(const Vector2& p_menu_pos) { if (selection.size()==1) { menu->add_separator(); + menu->add_item(TTR("Merge From Scene"),TOOL_MERGE_FROM_SCENE); menu->add_item(TTR("Save Branch as Scene"),TOOL_NEW_SCENE_FROM); } menu->add_separator(); diff --git a/tools/editor/scene_tree_dock.h b/tools/editor/scene_tree_dock.h index 0894dc8ffa..a5866944f3 100644 --- a/tools/editor/scene_tree_dock.h +++ b/tools/editor/scene_tree_dock.h @@ -64,6 +64,7 @@ class SceneTreeDock : public VBoxContainer { TOOL_DUPLICATE, TOOL_REPARENT, TOOL_NEW_SCENE_FROM, + TOOL_MERGE_FROM_SCENE, TOOL_MULTI_EDIT, TOOL_ERASE, TOOL_BUTTON_MAX diff --git a/tools/editor/scenes_dock.cpp b/tools/editor/scenes_dock.cpp index fc0bcfe7b9..a814dc2d9a 100644 --- a/tools/editor/scenes_dock.cpp +++ b/tools/editor/scenes_dock.cpp @@ -326,6 +326,10 @@ String ScenesDock::get_selected_path() const { return "res://"+path; } +String ScenesDock::get_current_path() const { + + return path; +} void ScenesDock::_thumbnail_done(const String& p_path,const Ref<Texture>& p_preview, const Variant& p_udata) { @@ -388,6 +392,25 @@ void ScenesDock::_search(EditorFileSystemDirectory *p_path,List<FileInfo>* match fi.name=file; fi.type=p_path->get_file_type(i); fi.path=p_path->get_file_path(i); + if (p_path->get_file_meta(i)) { + if (p_path->is_missing_sources(i)) { + fi.import_status=3; + } else if (p_path->have_sources_changed(i)) { + fi.import_status=2; + } else { + fi.import_status=1; + } + } else { + fi.import_status=0; + } + for(int j=0;j<p_path->get_source_count(i);j++) { + String s = EditorImportPlugin::expand_source_path(p_path->get_source_file(i,j)); + if (p_path->is_source_file_missing(i,j)) { + s+=" (Missing)"; + } + fi.sources.push_back(s); + } + matches->push_back(fi); if (matches->size()>p_max_items) return; @@ -517,6 +540,27 @@ void ScenesDock::_update_files(bool p_keep_selection) { fi.name=efd->get_file(i); fi.path=path.plus_file(fi.name); fi.type=efd->get_file_type(i); + if (efd->get_file_meta(i)) { + if (efd->is_missing_sources(i)) { + fi.import_status=3; + } else if (efd->have_sources_changed(i)) { + fi.import_status=2; + } else { + fi.import_status=1; + } + + for(int j=0;j<efd->get_source_count(i);j++) { + String s = EditorImportPlugin::expand_source_path(efd->get_source_file(i,j)); + if (efd->is_source_file_missing(i,j)) { + s+=" (Missing)"; + } + fi.sources.push_back(s); + } + } else { + fi.import_status=0; + } + + filelist.push_back(fi); } @@ -533,12 +577,33 @@ void ScenesDock::_update_files(bool p_keep_selection) { Ref<Texture> type_icon; - if (has_icon(type,ei)) { - type_icon=get_icon(type,ei); - } else { - type_icon=get_icon(oi,ei); + String tooltip=fname; + + if (E->get().import_status==0) { + + if (has_icon(type,ei)) { + type_icon=get_icon(type,ei); + } else { + type_icon=get_icon(oi,ei); + } + } else if (E->get().import_status==1) { + type_icon=get_icon("DependencyOk","EditorIcons"); + } else if (E->get().import_status==2) { + type_icon=get_icon("DependencyChanged","EditorIcons"); + tooltip+"\nStatus: Needs Re-Import"; + } else if (E->get().import_status==3) { + type_icon=get_icon("ImportFail","EditorIcons"); + tooltip+"\nStatus: Missing Dependencies"; + } + + if (E->get().sources.size()) { + for(int i=0;i<E->get().sources.size();i++) { + tooltip+="\nSource: "+E->get().sources[i]; + } } + + if (use_thumbnails) { files->add_item(fname,file_thumbnail,true); files->set_item_metadata(files->get_item_count()-1,fp); @@ -557,6 +622,9 @@ void ScenesDock::_update_files(bool p_keep_selection) { if (cselection.has(fname)) files->select(files->get_item_count()-1,false); + files->set_item_tooltip(files->get_item_count()-1,tooltip); + + } @@ -997,6 +1065,40 @@ void ScenesDock::_file_option(int p_option) { case FILE_INFO: { } break; + case FILE_REIMPORT: { + + + Vector<String> reimport; + for(int i=0;i<files->get_item_count();i++) { + + if (!files->is_selected(i)) + continue; + + String path = files->get_item_metadata(i); + reimport.push_back(path); + } + + ERR_FAIL_COND(reimport.size()==0); + + Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(reimport[0]); + ERR_FAIL_COND(!rimd.is_valid()); + String editor=rimd->get_editor(); + + if (editor.begins_with("texture_")) { //compatibility fix for old texture format + editor="texture"; + } + + Ref<EditorImportPlugin> rimp = EditorImportExport::get_singleton()->get_import_plugin_by_name(editor); + ERR_FAIL_COND(!rimp.is_valid()); + + if (reimport.size()==1) { + rimp->import_dialog(reimport[0]); + } else { + rimp->reimport_multiple_files(reimport); + + } + + } break; } } @@ -1362,6 +1464,8 @@ void ScenesDock::_files_list_rmb_select(int p_item,const Vector2& p_pos) { Vector<String> filenames; bool all_scenes=true; + bool all_can_reimport=true; + Set<String> types; for(int i=0;i<files->get_item_count();i++) { @@ -1381,6 +1485,38 @@ void ScenesDock::_files_list_rmb_select(int p_item,const Vector2& p_pos) { } + EditorFileSystemDirectory *efsd=NULL; + int pos; + + efsd = EditorFileSystem::get_singleton()->find_file(path,&pos); + + if (efsd) { + + + if (!efsd->get_file_meta(pos)) { + all_can_reimport=false; + + + } else { + Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(path); + if (rimd.is_valid()) { + + String editor=rimd->get_editor(); + if (editor.begins_with("texture_")) { //compatibility fix for old texture format + editor="texture"; + } + types.insert(editor); + + } else { + all_can_reimport=false; + + } + } + } else { + all_can_reimport=false; + + } + filenames.push_back(path); if (EditorFileSystem::get_singleton()->get_file_type(path)!="PackedScene") all_scenes=false; @@ -1412,12 +1548,34 @@ void ScenesDock::_files_list_rmb_select(int p_item,const Vector2& p_pos) { file_options->add_item(TTR("Move To.."),FILE_MOVE); } + file_options->add_item(TTR("Delete"),FILE_REMOVE); + //file_options->add_item(TTR("Info"),FILE_INFO); file_options->add_separator(); file_options->add_item(TTR("Show In File Manager"),FILE_SHOW_IN_EXPLORER); + if (all_can_reimport && types.size()==1) { //all can reimport and are of the same type + + + bool valid=true; + Ref<EditorImportPlugin> rimp = EditorImportExport::get_singleton()->get_import_plugin_by_name(types.front()->get()); + if (rimp.is_valid()) { + + if (filenames.size()>1 && !rimp->can_reimport_multiple_files()) { + valid=false; + } + } else { + valid=false; + } + + if (valid) { + file_options->add_separator(); + file_options->add_item(TTR("Re-Import.."),FILE_REIMPORT); + } + } + file_options->set_pos(files->get_global_pos() + p_pos); file_options->popup(); diff --git a/tools/editor/scenes_dock.h b/tools/editor/scenes_dock.h index 1d6d03374a..9a0d6c87cf 100644 --- a/tools/editor/scenes_dock.h +++ b/tools/editor/scenes_dock.h @@ -153,6 +153,8 @@ class ScenesDock : public VBoxContainer { String name; String path; StringName type; + int import_status; //0 not imported, 1 - ok, 2- must reimport, 3- broken + Vector<String> sources; bool operator<(const FileInfo& fi) const { return name < fi.name; @@ -171,6 +173,8 @@ protected: public: String get_selected_path() const; + + String get_current_path() const; void focus_on_filter(); void fix_dependencies(const String& p_for_file); |