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
This commit is contained in:
parent
eb7227a20b
commit
8be2fabbe5
|
@ -243,6 +243,7 @@ Ref<ResourceImportMetadata> ResourceLoader::load_import_metadata(const String &p
|
|||
break;
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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!="")
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
if (E) {
|
||||
r_ret = E->get().value;
|
||||
return true;
|
||||
}
|
||||
|
||||
r_ret = E->get().value;
|
||||
|
||||
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"));
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -186,6 +186,12 @@ public:
|
|||
|
||||
StringName node_configuration_warning_changed;
|
||||
|
||||
enum {
|
||||
MAX_MATERIALS=32
|
||||
};
|
||||
StringName mesh_materials[MAX_MATERIALS];
|
||||
StringName _mesh_changed;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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() {
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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")) {
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 651 B After Width: | Height: | Size: 649 B |
Binary file not shown.
Before Width: | Height: | Size: 685 B After Width: | Height: | Size: 707 B |
|
@ -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) {
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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() {
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,398 +1983,8 @@ 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
|
||||
|
||||
Error EditorImport::import_scene(const String& p_path,const String& p_dest_path,const String& p_resource_path,uint32_t p_flags,ImageFormat p_image_format,ImageCompression p_image_compression,uint32_t p_image_flags,float p_quality,uint32_t animation_flags,Node **r_scene,Ref<EditorPostImport> p_post_import) {
|
||||
|
@ -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) {
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
||||
EditorTextureImportPlugin *EditorTextureImportPlugin::singleton[EditorTextureImportPlugin::MODE_MAX]={NULL,NULL,NULL,NULL};
|
||||
Vector<String> valid;
|
||||
|
||||
EditorTextureImportPlugin::EditorTextureImportPlugin(EditorNode *p_editor, Mode p_mode) {
|
||||
List<String> valid_extensions;
|
||||
ImageLoader::get_recognized_extensions(&valid_extensions);
|
||||
for(int i=0;i<p_drop.size();i++) {
|
||||
|
||||
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) );
|
||||
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=NULL;
|
||||
|
||||
EditorTextureImportPlugin::EditorTextureImportPlugin(EditorNode *p_editor) {
|
||||
|
||||
singleton=this;
|
||||
editor=p_editor;
|
||||
dialog = memnew( EditorTextureImportDialog(this) );
|
||||
editor->get_gui_base()->add_child(dialog);
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue