summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--scene/resources/animation.cpp24
-rw-r--r--scene/resources/animation.h6
-rw-r--r--tools/editor/io_plugins/editor_import_collada.cpp6
-rw-r--r--tools/editor/io_plugins/editor_scene_import_plugin.cpp160
-rw-r--r--tools/editor/io_plugins/editor_scene_import_plugin.h8
5 files changed, 201 insertions, 3 deletions
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp
index 8f61c7b957..9b657d1b8f 100644
--- a/scene/resources/animation.cpp
+++ b/scene/resources/animation.cpp
@@ -74,6 +74,8 @@ bool Animation::_set(const StringName& p_name, const Variant& p_value) {
track_set_path(track,p_value);
else if (what=="interp")
track_set_interpolation_type(track,InterpolationType(p_value.operator int()));
+ else if (what=="imported")
+ track_set_imported(track,p_value);
else if (what == "keys" || what=="key_values") {
if (track_get_type(track)==TYPE_TRANSFORM) {
@@ -171,6 +173,7 @@ bool Animation::_set(const StringName& p_name, const Variant& p_value) {
}
+
DVector<float> times=d["times"];
Array values=d["values"];
@@ -290,6 +293,8 @@ bool Animation::_get(const StringName& p_name,Variant &r_ret) const {
r_ret=track_get_path(track);
else if (what=="interp")
r_ret = track_get_interpolation_type(track);
+ else if (what=="imported")
+ r_ret = track_is_imported(track);
else if (what=="keys") {
if (track_get_type(track)==TYPE_TRANSFORM) {
@@ -437,6 +442,7 @@ void Animation::_get_property_list( List<PropertyInfo> *p_list) const {
p_list->push_back( PropertyInfo( Variant::STRING, "tracks/"+itos(i)+"/type", PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR) );
p_list->push_back( PropertyInfo( Variant::NODE_PATH, "tracks/"+itos(i)+"/path", PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR) );
p_list->push_back( PropertyInfo( Variant::INT, "tracks/"+itos(i)+"/interp", PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR) );
+ p_list->push_back( PropertyInfo( Variant::BOOL, "tracks/"+itos(i)+"/imported", PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR) );
p_list->push_back( PropertyInfo( Variant::ARRAY, "tracks/"+itos(i)+"/keys", PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR) );
}
}
@@ -1648,6 +1654,20 @@ void Animation::track_move_up(int p_track) {
emit_changed();
}
+void Animation::track_set_imported(int p_track,bool p_imported) {
+
+ ERR_FAIL_INDEX(p_track,tracks.size());
+ tracks[p_track]->imported=p_imported;
+}
+
+bool Animation::track_is_imported(int p_track) const{
+
+ ERR_FAIL_INDEX_V(p_track,tracks.size(),false);
+ return tracks[p_track]->imported;
+
+}
+
+
void Animation::track_move_down(int p_track) {
if (p_track>0 && p_track<tracks.size()) {
@@ -1682,6 +1702,10 @@ void Animation::_bind_methods() {
ObjectTypeDB::bind_method(_MD("track_move_up","idx"),&Animation::track_move_up);
ObjectTypeDB::bind_method(_MD("track_move_down","idx"),&Animation::track_move_down);
+ ObjectTypeDB::bind_method(_MD("track_set_imported","idx","imported"),&Animation::track_set_imported);
+ ObjectTypeDB::bind_method(_MD("track_is_imported","idx"),&Animation::track_is_imported);
+
+
ObjectTypeDB::bind_method(_MD("transform_track_insert_key","idx","time","loc","rot","scale"),&Animation::transform_track_insert_key);
ObjectTypeDB::bind_method(_MD("track_insert_key","idx","time","key","transition"),&Animation::track_insert_key,DEFVAL(1));
ObjectTypeDB::bind_method(_MD("track_remove_key","idx","key_idx"),&Animation::track_remove_key);
diff --git a/scene/resources/animation.h b/scene/resources/animation.h
index 8b677fe0da..ee643c9678 100644
--- a/scene/resources/animation.h
+++ b/scene/resources/animation.h
@@ -72,7 +72,8 @@ private:
TrackType type;
InterpolationType interpolation;
NodePath path; // path to something
- Track() { interpolation=INTERPOLATION_LINEAR; }
+ bool imported;
+ Track() { interpolation=INTERPOLATION_LINEAR; imported=false;}
virtual ~Track() {}
};
@@ -241,6 +242,9 @@ public:
void track_move_up(int p_track);
void track_move_down(int p_track);
+ void track_set_imported(int p_track,bool p_imported);
+ bool track_is_imported(int p_track) const;
+
int transform_track_insert_key(int p_track, float p_time, const Vector3 p_loc, const Quat& p_rot=Quat(), const Vector3& p_scale=Vector3());
void track_insert_key(int p_track, float p_time, const Variant& p_key, float p_transition=1);
void track_set_key_transition(int p_track, int p_key_idx,float p_transition);
diff --git a/tools/editor/io_plugins/editor_import_collada.cpp b/tools/editor/io_plugins/editor_import_collada.cpp
index 80cd54756e..363cba3678 100644
--- a/tools/editor/io_plugins/editor_import_collada.cpp
+++ b/tools/editor/io_plugins/editor_import_collada.cpp
@@ -2077,6 +2077,7 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
animation->add_track(Animation::TYPE_TRANSFORM);
int track = animation->get_track_count() -1;
animation->track_set_path( track , path );
+ animation->track_set_imported( track , true ); //helps merging later
Vector<float> snapshots = base_snapshots;
@@ -2229,6 +2230,7 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
animation->add_track(Animation::TYPE_TRANSFORM);
int track = animation->get_track_count() -1;
animation->track_set_path( track , path );
+ animation->track_set_imported( track , true ); //helps merging later
Transform xform = cn->compute_transform(collada);
@@ -2284,8 +2286,11 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
animation->add_track(Animation::TYPE_VALUE);
int track = animation->get_track_count() -1;
+
path = path +":"+at.param;
animation->track_set_path( track , path );
+ animation->track_set_imported( track , true ); //helps merging later
+
for(int i=0;i<at.keys.size();i++) {
@@ -2376,6 +2381,7 @@ Node* EditorSceneImporterCollada::import_scene(const String& p_path, uint32_t p_
state.create_animations(p_flags&IMPORT_ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS);
AnimationPlayer *ap = memnew( AnimationPlayer );
+ ap->set_name("animations");
for(int i=0;i<state.animations.size();i++) {
String name;
if (state.animations[i]->get_name()=="")
diff --git a/tools/editor/io_plugins/editor_scene_import_plugin.cpp b/tools/editor/io_plugins/editor_scene_import_plugin.cpp
index ed766c6598..c7d92a9658 100644
--- a/tools/editor/io_plugins/editor_scene_import_plugin.cpp
+++ b/tools/editor/io_plugins/editor_scene_import_plugin.cpp
@@ -1069,11 +1069,13 @@ const EditorSceneImportDialog::FlagInfo EditorSceneImportDialog::scene_flag_name
{EditorSceneImportPlugin::SCENE_FLAG_IMPORT_ANIMATIONS,("Actions"),"Import Animations",true},
{EditorSceneImportPlugin::SCENE_FLAG_COMPRESS_GEOMETRY,("Actions"),"Compress Geometry",false},
{EditorSceneImportPlugin::SCENE_FLAG_GENERATE_TANGENT_ARRAYS,("Actions"),"Force Generation of Tangent Arrays",false},
- {EditorSceneImportPlugin::SCENE_FLAG_DETECT_ALPHA,("Materials"),"Set Alpha in Materials (-alpha)",true},
- {EditorSceneImportPlugin::SCENE_FLAG_DETECT_VCOLOR,("Materials"),"Set Vert. Color in Materials (-vcol)",true},
{EditorSceneImportPlugin::SCENE_FLAG_LINEARIZE_DIFFUSE_TEXTURES,("Actions"),"SRGB->Linear Of Diffuse Textures",false},
{EditorSceneImportPlugin::SCENE_FLAG_CONVERT_NORMALMAPS_TO_XY,("Actions"),"Convert Normal Maps to XY",true},
{EditorSceneImportPlugin::SCENE_FLAG_SET_LIGHTMAP_TO_UV2_IF_EXISTS,("Actions"),"Set Material Lightmap to UV2 if Tex2Array Exists",true},
+ {EditorSceneImportPlugin::SCENE_FLAG_MERGE_KEEP_MATERIALS,("Merge"),"Keep Materials after first import (delete them for re-import).",true},
+ {EditorSceneImportPlugin::SCENE_FLAG_MERGE_KEEP_EXTRA_ANIM_TRACKS,("Merge"),"Keep user-added Animation tracks.",true},
+ {EditorSceneImportPlugin::SCENE_FLAG_DETECT_ALPHA,("Materials"),"Set Alpha in Materials (-alpha)",true},
+ {EditorSceneImportPlugin::SCENE_FLAG_DETECT_VCOLOR,("Materials"),"Set Vert. Color in Materials (-vcol)",true},
{EditorSceneImportPlugin::SCENE_FLAG_CREATE_COLLISIONS,("Create"),"Create Collisions and/or Rigid Bodies (-col,-colonly,-rigid)",true},
{EditorSceneImportPlugin::SCENE_FLAG_CREATE_PORTALS,("Create"),"Create Portals (-portal)",true},
{EditorSceneImportPlugin::SCENE_FLAG_CREATE_ROOMS,("Create"),"Create Rooms (-room)",true},
@@ -2455,6 +2457,138 @@ void EditorSceneImportPlugin::_optimize_animations(Node *scene, float p_max_lin_
}
+void EditorSceneImportPlugin::_find_resources_to_merge(Node *scene, Node *node, bool p_merge_material, Map<String, Ref<Material> > &materials, bool p_merge_anims, Map<String,Ref<Animation> >& merged_anims,Set<Ref<Mesh> > &tested_meshes) {
+
+ if (node->get_owner()!=scene)
+ return;
+
+ String path = scene->get_path_to(node);
+
+ if (p_merge_anims && node->cast_to<AnimationPlayer>()) {
+
+ AnimationPlayer *ap = node->cast_to<AnimationPlayer>();
+ List<StringName> anims;
+ ap->get_animation_list(&anims);
+ for (List<StringName>::Element *E=anims.front();E;E=E->next()) {
+ Ref<Animation> anim = ap->get_animation(E->get());
+ Ref<Animation> clone;
+
+ bool has_user_tracks=false;
+
+ for(int i=0;i<anim->get_track_count();i++) {
+
+ if (!anim->track_is_imported(i)) {
+ has_user_tracks=true;
+ break;
+ }
+ }
+
+ if (has_user_tracks) {
+
+ clone = anim->duplicate();
+ for(int i=0;i<clone->get_track_count();i++) {
+ if (clone->track_is_imported(i)) {
+ clone->remove_track(i);
+ i--;
+ }
+ }
+
+ merged_anims[path+"::"+String(E->get())]=clone;
+ }
+ }
+ }
+
+
+
+ if (p_merge_material && node->cast_to<MeshInstance>()) {
+ MeshInstance *mi=node->cast_to<MeshInstance>();
+ Ref<Mesh> mesh = mi->get_mesh();
+ if (mesh.is_valid() && mesh->get_name()!=String() && !tested_meshes.has(mesh)) {
+
+ for(int i=0;i<mesh->get_surface_count();i++) {
+ Ref<Material> material = mesh->surface_get_material(i);
+ materials[mesh->get_name()+":surf:"+mesh->surface_get_name(i)]=material;
+ }
+
+ tested_meshes.insert(mesh);
+ }
+ }
+
+
+
+ for(int i=0;i<node->get_child_count();i++) {
+ _find_resources_to_merge(scene,node->get_child(i),p_merge_material,materials,p_merge_anims,merged_anims,tested_meshes);
+ }
+
+}
+
+
+void EditorSceneImportPlugin::_merge_found_resources(Node *scene, Node *node, bool p_merge_material, const Map<String, Ref<Material> > &materials, bool p_merge_anims, const Map<String,Ref<Animation> >& merged_anims, Set<Ref<Mesh> > &tested_meshes) {
+
+ if (node->get_owner()!=scene)
+ return;
+
+ String path = scene->get_path_to(node);
+
+ if (node->cast_to<AnimationPlayer>()) {
+
+ AnimationPlayer *ap = node->cast_to<AnimationPlayer>();
+ List<StringName> anims;
+ ap->get_animation_list(&anims);
+ for (List<StringName>::Element *E=anims.front();E;E=E->next()) {
+ Ref<Animation> anim = ap->get_animation(E->get());
+
+ String anim_path = path+"::"+String(E->get());
+
+ if (merged_anims.has(anim_path)) {
+
+ Ref<Animation> user_tracks = merged_anims[anim_path];
+ for(int i=0;i<user_tracks->get_track_count();i++) {
+
+ int idx = anim->get_track_count();
+ anim->add_track(user_tracks->track_get_type(i));
+ anim->track_set_path(idx,user_tracks->track_get_path(i));
+ anim->track_set_interpolation_type(idx,user_tracks->track_get_interpolation_type(i));
+ for(int j=0;j<user_tracks->track_get_key_count(i);j++) {
+
+ float ofs = user_tracks->track_get_key_time(i,j);
+ float trans = user_tracks->track_get_key_transition(i,j);
+ Variant value = user_tracks->track_get_key_value(i,j);
+
+ anim->track_insert_key(idx,ofs,value,trans);
+ }
+ }
+ }
+ }
+ }
+
+
+
+ if (node->cast_to<MeshInstance>()) {
+ MeshInstance *mi=node->cast_to<MeshInstance>();
+ Ref<Mesh> mesh = mi->get_mesh();
+ if (mesh.is_valid() && mesh->get_name()!=String() && !tested_meshes.has(mesh)) {
+
+ for(int i=0;i<mesh->get_surface_count();i++) {
+ String sname = mesh->get_name()+":surf:"+mesh->surface_get_name(i);
+
+ if (materials.has(sname)) {
+ mesh->surface_set_material(i,materials[sname]);
+ }
+ }
+
+ tested_meshes.insert(mesh);
+ }
+ }
+
+
+
+ for(int i=0;i<node->get_child_count();i++) {
+ _merge_found_resources(scene,node->get_child(i),p_merge_material,materials,p_merge_anims,merged_anims,tested_meshes);
+ }
+
+}
+
Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, const Ref<ResourceImportMetadata>& p_from) {
Error err=OK;
@@ -2506,6 +2640,28 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c
_filter_tracks(scene,animation_filter);
+ if (scene_flags&(SCENE_FLAG_MERGE_KEEP_MATERIALS|SCENE_FLAG_MERGE_KEEP_EXTRA_ANIM_TRACKS) && FileAccess::exists(p_dest_path)) {
+ //must merge!
+
+ Ref<PackedScene> pscene = ResourceLoader::load(p_dest_path,"PackedScene",true);
+ if (pscene.is_valid()) {
+
+ Node *instance = pscene->instance();
+ if (instance) {
+ Map<String,Ref<Animation> > merged_anims;
+ Map<String,Ref<Material> > merged_materials;
+ Set<Ref<Mesh> > tested_meshes;
+
+ _find_resources_to_merge(instance,instance,scene_flags&SCENE_FLAG_MERGE_KEEP_MATERIALS,merged_materials,scene_flags&SCENE_FLAG_MERGE_KEEP_EXTRA_ANIM_TRACKS,merged_anims,tested_meshes);
+ tested_meshes.clear();
+ _merge_found_resources(instance,instance,scene_flags&SCENE_FLAG_MERGE_KEEP_MATERIALS,merged_materials,scene_flags&SCENE_FLAG_MERGE_KEEP_EXTRA_ANIM_TRACKS,merged_anims,tested_meshes);
+
+ memdelete(instance);
+ }
+
+ }
+
+ }
/// BEFORE ANYTHING, RUN SCRIPT
diff --git a/tools/editor/io_plugins/editor_scene_import_plugin.h b/tools/editor/io_plugins/editor_scene_import_plugin.h
index 8a2d30f1f6..c31d3a33d3 100644
--- a/tools/editor/io_plugins/editor_scene_import_plugin.h
+++ b/tools/editor/io_plugins/editor_scene_import_plugin.h
@@ -116,6 +116,10 @@ class EditorSceneImportPlugin : public EditorImportPlugin {
void _tag_import_paths(Node *p_scene,Node *p_node);
+ void _find_resources_to_merge(Node *scene, Node *node, bool p_merge_material, Map<String,Ref<Material> >&materials, bool p_merge_anims, Map<String,Ref<Animation> >& merged_anims, Set<Ref<Mesh> > &tested_meshes);
+ void _merge_found_resources(Node *scene, Node *node, bool p_merge_material, const Map<String, Ref<Material> > &materials, bool p_merge_anims, const Map<String,Ref<Animation> >& merged_anims, Set<Ref<Mesh> > &tested_meshes);
+
+
public:
enum SceneFlags {
@@ -134,6 +138,9 @@ public:
SCENE_FLAG_CREATE_NAVMESH=1<<17,
SCENE_FLAG_DETECT_LIGHTMAP_LAYER=1<<18,
+ SCENE_FLAG_MERGE_KEEP_MATERIALS=1<<20,
+ SCENE_FLAG_MERGE_KEEP_EXTRA_ANIM_TRACKS=1<<21,
+
SCENE_FLAG_REMOVE_NOIMP=1<<24,
SCENE_FLAG_IMPORT_ANIMATIONS=1<<25,
SCENE_FLAG_COMPRESS_GEOMETRY=1<<26,
@@ -144,6 +151,7 @@ public:
};
+
virtual String get_name() const;
virtual String get_visible_name() const;
virtual void import_dialog(const String& p_from="");