summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/docdump/class_list.xml2
-rw-r--r--tools/editor/animation_editor.cpp53
-rw-r--r--tools/editor/animation_editor.h6
-rw-r--r--tools/editor/editor_file_system.cpp29
-rw-r--r--tools/editor/editor_file_system.h3
-rw-r--r--tools/editor/io_plugins/editor_import_collada.cpp13
-rw-r--r--tools/editor/io_plugins/editor_scene_import_plugin.cpp138
-rw-r--r--tools/editor/io_plugins/editor_scene_import_plugin.h1
-rw-r--r--tools/editor/plugins/script_editor_plugin.cpp173
-rw-r--r--tools/editor/plugins/script_editor_plugin.h6
-rw-r--r--tools/export/blender25/io_scene_dae/export_dae.py20
11 files changed, 423 insertions, 21 deletions
diff --git a/tools/docdump/class_list.xml b/tools/docdump/class_list.xml
index 897477ff48..ab33cef7d7 100644
--- a/tools/docdump/class_list.xml
+++ b/tools/docdump/class_list.xml
@@ -319,7 +319,7 @@
<argument index="1" name="animation" type="Object">
</argument>
<description>
- Add an animation resource to the player, which will be later referenced by the &quot;name&quot; arguemnt.
+ Add an animation resource to the player, which will be later referenced by the &quot;name&quot; argument.
</description>
</method>
<method name="remove_animation" >
diff --git a/tools/editor/animation_editor.cpp b/tools/editor/animation_editor.cpp
index 68bd051ee9..0d4f5a7b74 100644
--- a/tools/editor/animation_editor.cpp
+++ b/tools/editor/animation_editor.cpp
@@ -687,9 +687,7 @@ void AnimationKeyEditor::_menu_track(int p_type) {
case TRACK_MENU_OPTIMIZE: {
- animation->optimize();
-
- track_editor->update();
+ optimize_dialog->popup_centered(Size2(250,180));
} break;
@@ -698,6 +696,18 @@ void AnimationKeyEditor::_menu_track(int p_type) {
}
+
+void AnimationKeyEditor::_animation_optimize() {
+
+
+ print_line("OPTIMIZE!");
+ animation->optimize(optimize_linear_error->get_val(),optimize_angular_error->get_val(),optimize_max_angle->get_val());
+ track_editor->update();
+ undo_redo->clear_history();
+
+}
+
+
float AnimationKeyEditor::_get_zoom_scale() const {
float zv = zoom->get_val();
@@ -2335,11 +2345,12 @@ void AnimationKeyEditor::_notification(int p_what) {
tpp->add_item("Out-In",TRACK_MENU_SET_ALL_TRANS_OUTIN);
tpp->set_name("Transitions");
tpp->connect("item_pressed",this,"_menu_track");
+ optimize_dialog->connect("confirmed",this,"_animation_optimize");
menu_track->get_popup()->add_child(tpp);
menu_track->get_popup()->add_submenu_item("Set Transitions..","Transitions");
- //menu_track->get_popup()->add_separator();
- //menu_track->get_popup()->add_item("Optimize Animation",TRACK_MENU_OPTIMIZE);
+ menu_track->get_popup()->add_separator();
+ menu_track->get_popup()->add_item("Optimize Animation",TRACK_MENU_OPTIMIZE);
@@ -3099,6 +3110,7 @@ void AnimationKeyEditor::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_animation_len_update"),&AnimationKeyEditor::_animation_len_update);
ObjectTypeDB::bind_method(_MD("set_animation"),&AnimationKeyEditor::set_animation);
+ ObjectTypeDB::bind_method(_MD("_animation_optimize"),&AnimationKeyEditor::_animation_optimize);
ADD_SIGNAL( MethodInfo("resource_selected", PropertyInfo( Variant::OBJECT, "res"),PropertyInfo( Variant::STRING, "prop") ) );
@@ -3224,6 +3236,37 @@ AnimationKeyEditor::AnimationKeyEditor(UndoRedo *p_undo_redo, EditorHistory *p_h
remove_button->set_disabled(true);
remove_button->set_tooltip("Remove selected track.");
+
+ optimize_dialog = memnew( ConfirmationDialog );
+ add_child(optimize_dialog);
+ optimize_dialog->set_title("Anim. Optimizer");
+ VBoxContainer *optimize_vb = memnew( VBoxContainer );
+ optimize_dialog->add_child(optimize_vb);
+ optimize_dialog->set_child_rect(optimize_vb);
+ optimize_linear_error = memnew( SpinBox );
+ optimize_linear_error->set_max(1.0);
+ optimize_linear_error->set_min(0.001);
+ optimize_linear_error->set_step(0.001);
+ optimize_linear_error->set_val(0.05);
+ optimize_vb->add_margin_child("Max. Linear Error:",optimize_linear_error);
+ optimize_angular_error = memnew( SpinBox );
+ optimize_angular_error->set_max(1.0);
+ optimize_angular_error->set_min(0.001);
+ optimize_angular_error->set_step(0.001);
+ optimize_angular_error->set_val(0.01);
+
+ optimize_vb->add_margin_child("Max. Angular Error:",optimize_angular_error);
+ optimize_max_angle = memnew( SpinBox );
+ optimize_vb->add_margin_child("Max Optimizable Angle:",optimize_max_angle);
+ optimize_max_angle->set_max(360.0);
+ optimize_max_angle->set_min(0.0);
+ optimize_max_angle->set_step(0.1);
+ optimize_max_angle->set_val(22);
+
+ optimize_dialog->get_ok()->set_text("Optimize");
+
+
+
/*keying = memnew( Button );
keying->set_toggle_mode(true);
//keying->set_text("Keys");
diff --git a/tools/editor/animation_editor.h b/tools/editor/animation_editor.h
index 01f6e294cc..9d3e692fad 100644
--- a/tools/editor/animation_editor.h
+++ b/tools/editor/animation_editor.h
@@ -169,6 +169,11 @@ class AnimationKeyEditor : public VBoxContainer {
ToolButton *move_down_button;
ToolButton *remove_button;
+ ConfirmationDialog *optimize_dialog;
+ SpinBox *optimize_linear_error;
+ SpinBox *optimize_angular_error;
+ SpinBox *optimize_max_angle;
+
SpinBox *step;
MenuButton *menu_track;
@@ -257,6 +262,7 @@ class AnimationKeyEditor : public VBoxContainer {
StringName alc;
void _animation_changed();
+ void _animation_optimize();
void _scroll_changed(double);
diff --git a/tools/editor/editor_file_system.cpp b/tools/editor/editor_file_system.cpp
index e0b743a929..5d72928e9c 100644
--- a/tools/editor/editor_file_system.cpp
+++ b/tools/editor/editor_file_system.cpp
@@ -992,6 +992,35 @@ void EditorFileSystem::_resource_saved(const String& p_path){
EditorFileSystem::get_singleton()->update_file(p_path);
}
+String EditorFileSystem::_find_first_from_source(EditorFileSystemDirectory* p_dir,const String &p_src) const {
+
+ for(int i=0;i<p_dir->files.size();i++) {
+ for(int j=0;j<p_dir->files[i].meta.sources.size();j++) {
+
+ if (p_dir->files[i].meta.sources[j].path==p_src)
+ return p_dir->get_file_path(i);
+ }
+ }
+
+ for(int i=0;i<p_dir->subdirs.size();i++) {
+
+ String ret = _find_first_from_source(p_dir->subdirs[i],p_src);
+ if (ret.length()>0)
+ return ret;
+ }
+
+ return String();
+}
+
+
+String EditorFileSystem::find_resource_from_source(const String& p_path) const {
+
+
+ if (filesystem)
+ return _find_first_from_source(filesystem,p_path);
+ return String();
+}
+
void EditorFileSystem::update_file(const String& p_file) {
EditorFileSystemDirectory *fs=NULL;
diff --git a/tools/editor/editor_file_system.h b/tools/editor/editor_file_system.h
index c26fc02548..2d14f9012f 100644
--- a/tools/editor/editor_file_system.h
+++ b/tools/editor/editor_file_system.h
@@ -75,6 +75,7 @@ class EditorFileSystemDirectory : public Object {
static void _bind_methods();
+
friend class EditorFileSystem;
public:
@@ -180,6 +181,7 @@ class EditorFileSystem : public Node {
List<String> sources_changed;
static void _resource_saved(const String& p_path);
+ String _find_first_from_source(EditorFileSystemDirectory* p_dir,const String &p_src) const;
protected:
@@ -197,6 +199,7 @@ public:
void scan_sources();
void get_changed_sources(List<String> *r_changed);
void update_file(const String& p_file);
+ 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;
EditorFileSystem();
diff --git a/tools/editor/io_plugins/editor_import_collada.cpp b/tools/editor/io_plugins/editor_import_collada.cpp
index 3fb45d1870..8fe7010760 100644
--- a/tools/editor/io_plugins/editor_import_collada.cpp
+++ b/tools/editor/io_plugins/editor_import_collada.cpp
@@ -1844,12 +1844,15 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
anim_length=collada.state.animation_clips[p_clip].end;
while(f<anim_length) {
- if (f>=anim_length)
- f=anim_length;
base_snapshots.push_back(f);
f+=snapshot_interval;
+
+ if (f>=anim_length) {
+ base_snapshots.push_back(anim_length);
+ }
}
+
//print_line("anim len: "+rtos(anim_length));
animation->set_length(anim_length);
@@ -1894,6 +1897,8 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
for(int i=0;i<at.keys.size();i++)
snapshots.push_back(at.keys[i].time);
+ print_line("using anim snapshots");
+
}
@@ -2185,8 +2190,6 @@ Node* EditorSceneImporterCollada::import_scene(const String& p_path, uint32_t p_
else
name=state.animations[i]->get_name();
- if (p_flags&IMPORT_ANIMATION_OPTIMIZE)
- state.animations[i]->optimize();
if (p_flags&IMPORT_ANIMATION_DETECT_LOOP) {
if (name.begins_with("loop") || name.ends_with("loop") || name.begins_with("cycle") || name.ends_with("cycle")) {
@@ -2232,8 +2235,6 @@ Ref<Animation> EditorSceneImporterCollada::import_animation(const String& p_path
}
}
- if (p_flags&IMPORT_ANIMATION_OPTIMIZE)
- anim->optimize();
return anim;
}
diff --git a/tools/editor/io_plugins/editor_scene_import_plugin.cpp b/tools/editor/io_plugins/editor_scene_import_plugin.cpp
index f305564622..06780e4d8a 100644
--- a/tools/editor/io_plugins/editor_scene_import_plugin.cpp
+++ b/tools/editor/io_plugins/editor_scene_import_plugin.cpp
@@ -80,17 +80,25 @@ class EditorImportAnimationOptions : public VBoxContainer {
TreeItem *fps;
+ TreeItem* optimize_linear_error;
+ TreeItem* optimize_angular_error;
+ TreeItem* optimize_max_angle;
+
TreeItem *clips_base;
+
TextEdit *filters;
Vector<TreeItem*> clips;
Tree *flags;
Tree *clips_tree;
+ Tree *optimization_tree;
Vector<TreeItem*> items;
bool updating;
bool validating;
+
+
void _changed();
void _item_edited();
void _button_action(Object *p_obj,int p_col,int p_id);
@@ -107,6 +115,15 @@ public:
void set_fps(int p_fps);
int get_fps() const;
+ void set_optimize_linear_error(float p_error);
+ float get_optimize_linear_error() const;
+
+ void set_optimize_angular_error(float p_error);
+ float get_optimize_angular_error() const;
+
+ void set_optimize_max_angle(float p_error);
+ float get_optimize_max_angle() const;
+
void setup_clips(const Array& p_clips);
Array get_clips() const;
@@ -453,9 +470,41 @@ EditorImportAnimationOptions::EditorImportAnimationOptions() {
fps = flags->create_item(fps_base);
fps->set_cell_mode(0,TreeItem::CELL_MODE_RANGE);
fps->set_editable(0,true);
- fps->set_range(0,15);
fps->set_range_config(0,1,120,1);
+ fps->set_range(0,15);
+ optimization_tree = memnew( Tree );
+ optimization_tree->set_columns(2);
+ tab->add_child(optimization_tree);
+ optimization_tree->set_name("Optimizer");
+ optimization_tree->set_column_expand(0,true);
+ optimization_tree->set_column_expand(1,false);
+ optimization_tree->set_column_min_width(1,80);
+ optimization_tree->set_hide_root(true);
+
+
+ TreeItem *optimize_root = optimization_tree->create_item();
+
+ optimize_linear_error = optimization_tree->create_item(optimize_root);
+ optimize_linear_error->set_text(0,"Max Linear Error");
+ optimize_linear_error->set_cell_mode(1,TreeItem::CELL_MODE_RANGE);
+ optimize_linear_error->set_editable(1,true);
+ optimize_linear_error->set_range_config(1,0,1,0.001);
+ optimize_linear_error->set_range(1,0.05);
+
+ optimize_angular_error = optimization_tree->create_item(optimize_root);
+ optimize_angular_error->set_text(0,"Max Angular Error");
+ optimize_angular_error->set_cell_mode(1,TreeItem::CELL_MODE_RANGE);
+ optimize_angular_error->set_editable(1,true);
+ optimize_angular_error->set_range_config(1,0,1,0.001);
+ optimize_angular_error->set_range(1,0.01);
+
+ optimize_max_angle = optimization_tree->create_item(optimize_root);
+ optimize_max_angle->set_text(0,"Max Angle");
+ optimize_max_angle->set_cell_mode(1,TreeItem::CELL_MODE_RANGE);
+ optimize_max_angle->set_editable(1,true);
+ optimize_max_angle->set_range_config(1,0,360,0.001);
+ optimize_max_angle->set_range(1,int(180*0.125));
clips_tree = memnew( Tree );
clips_tree->set_hide_root(true);
@@ -498,6 +547,38 @@ int EditorImportAnimationOptions::get_fps() const {
return fps->get_range(0);
}
+
+void EditorImportAnimationOptions::set_optimize_linear_error(float p_optimize_linear_error) {
+
+ optimize_linear_error->set_range(1,p_optimize_linear_error);
+}
+
+float EditorImportAnimationOptions::get_optimize_linear_error() const {
+
+ return optimize_linear_error->get_range(1);
+}
+
+void EditorImportAnimationOptions::set_optimize_angular_error(float p_optimize_angular_error) {
+
+ optimize_angular_error->set_range(1,p_optimize_angular_error);
+}
+
+float EditorImportAnimationOptions::get_optimize_angular_error() const {
+
+ return optimize_angular_error->get_range(1);
+}
+
+void EditorImportAnimationOptions::set_optimize_max_angle(float p_optimize_max_angle) {
+
+ optimize_max_angle->set_range(1,p_optimize_max_angle);
+}
+
+float EditorImportAnimationOptions::get_optimize_max_angle() const {
+
+ return optimize_max_angle->get_range(1);
+}
+
+
void EditorImportAnimationOptions::set_filter(const String& p_filter) {
filters->set_text(p_filter);
@@ -544,6 +625,17 @@ void EditorSceneImportDialog::_choose_file(const String& p_path) {
}
#endif
+ if (p_path!=String()) {
+
+ String from_path = EditorFileSystem::get_singleton()->find_resource_from_source(EditorImportPlugin::validate_source_path(p_path));
+ print_line("from path.."+from_path);
+ if (from_path!=String()) {
+ popup_import(from_path);
+
+ }
+ }
+
+
import_path->set_text(p_path);
}
@@ -650,6 +742,9 @@ void EditorSceneImportDialog::_import(bool p_and_open) {
rim->set_option("texture_quality",texture_options->get_quality());
rim->set_option("animation_flags",animation_options->get_flags());
rim->set_option("animation_bake_fps",animation_options->get_fps());
+ rim->set_option("animation_optimizer_linear_error",animation_options->get_optimize_linear_error());
+ rim->set_option("animation_optimizer_angular_error",animation_options->get_optimize_angular_error());
+ rim->set_option("animation_optimizer_max_angle",animation_options->get_optimize_max_angle());
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()!=String()?EditorImportPlugin::validate_source_path(script_path->get_text()):String());
@@ -791,6 +886,13 @@ void EditorSceneImportDialog::popup_import(const String &p_from) {
animation_options->set_filter(rimd->get_option("animation_filters"));
if (rimd->has_option("animation_bake_fps"))
animation_options->set_fps(rimd->get_option("animation_bake_fps"));
+ if (rimd->has_option("animation_optimizer_linear_error"))
+ animation_options->set_optimize_linear_error(rimd->get_option("animation_optimizer_linear_error"));
+ if (rimd->has_option("animation_optimizer_angular_error"))
+ animation_options->set_optimize_angular_error(rimd->get_option("animation_optimizer_angular_error"));
+ if (rimd->has_option("animation_optimizer_max_angle"))
+ animation_options->set_optimize_max_angle(rimd->get_option("animation_optimizer_max_angle"));
+
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"));
@@ -2223,6 +2325,8 @@ Error EditorSceneImportPlugin::import1(const Ref<ResourceImportMetadata>& p_from
int fps = 24;
if (from->has_option("animation_bake_fps"))
fps=from->get_option("animation_bake_fps");
+
+
Array clips;
if (from->has_option("animation_clips"))
clips=from->get_option("animation_clips");
@@ -2503,6 +2607,26 @@ void EditorSceneImportPlugin::_filter_tracks(Node *scene, const String& p_text)
}
+void EditorSceneImportPlugin::_optimize_animations(Node *scene, float p_max_lin_error,float p_max_ang_error,float p_max_angle) {
+
+ if (!scene->has_node(String("AnimationPlayer")))
+ return;
+ Node* n = scene->get_node(String("AnimationPlayer"));
+ ERR_FAIL_COND(!n);
+ AnimationPlayer *anim = n->cast_to<AnimationPlayer>();
+ ERR_FAIL_COND(!anim);
+
+
+ List<StringName> anim_names;
+ anim->get_animation_list(&anim_names);
+ for(List<StringName>::Element *E=anim_names.front();E;E=E->next()) {
+
+ Ref<Animation> a = anim->get_animation(E->get());
+ a->optimize(p_max_lin_error,p_max_ang_error,Math::deg2rad(p_max_angle));
+ }
+}
+
+
Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, const Ref<ResourceImportMetadata>& p_from) {
Error err=OK;
@@ -2512,6 +2636,16 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c
Array animation_clips = p_from->get_option("animation_clips");
String animation_filter = p_from->get_option("animation_filters");
int scene_flags = from->get_option("flags");
+ float anim_optimizer_linerr=0.05;
+ float anim_optimizer_angerr=0.01;
+ float anim_optimizer_maxang=22;
+
+ if (from->has_option("animation_optimizer_linear_error"))
+ anim_optimizer_linerr=from->get_option("animation_optimizer_linear_error");
+ if (from->has_option("animation_optimizer_angular_error"))
+ anim_optimizer_angerr=from->get_option("animation_optimizer_angular_error");
+ if (from->has_option("animation_optimizer_max_angle"))
+ anim_optimizer_maxang=from->get_option("animation_optimizer_max_angle");
EditorProgress progress("import","Import Scene",104);
progress.step("Importing Scene..",2);
@@ -2536,6 +2670,8 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c
Map< Ref<ImageTexture>,TextureRole > imagemap;
scene=_fix_node(scene,scene,collision_map,scene_flags,imagemap);
+ if (animation_flags&EditorSceneAnimationImportPlugin::ANIMATION_OPTIMIZE)
+ _optimize_animations(scene,anim_optimizer_linerr,anim_optimizer_angerr,anim_optimizer_maxang);
if (animation_clips.size())
_create_clips(scene,animation_clips,animation_flags&EditorSceneAnimationImportPlugin::ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS);
diff --git a/tools/editor/io_plugins/editor_scene_import_plugin.h b/tools/editor/io_plugins/editor_scene_import_plugin.h
index c56be57aed..fa4730f7ee 100644
--- a/tools/editor/io_plugins/editor_scene_import_plugin.h
+++ b/tools/editor/io_plugins/editor_scene_import_plugin.h
@@ -114,6 +114,7 @@ class EditorSceneImportPlugin : public EditorImportPlugin {
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,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);
diff --git a/tools/editor/plugins/script_editor_plugin.cpp b/tools/editor/plugins/script_editor_plugin.cpp
index 2cb907f1c3..c0d773309c 100644
--- a/tools/editor/plugins/script_editor_plugin.cpp
+++ b/tools/editor/plugins/script_editor_plugin.cpp
@@ -237,7 +237,7 @@ void ScriptTextEditor::_load_theme_settings() {
//colorize engine types
Color type_color= EDITOR_DEF("text_editor/engine_type_color",Color(0.0,0.2,0.4));
- List<String> types;
+ List<String> types;
ObjectTypeDB::get_type_list(&types);
for(List<String>::Element *E=types.front();E;E=E->next()) {
@@ -661,13 +661,10 @@ void ScriptEditor::_menu_option(int p_option) {
} break;
case EDIT_UNDO: {
-
-
current->get_text_edit()->undo();
} break;
case EDIT_REDO: {
current->get_text_edit()->redo();
-
} break;
case EDIT_CUT: {
@@ -686,6 +683,163 @@ void ScriptEditor::_menu_option(int p_option) {
current->get_text_edit()->select_all();
} break;
+ case EDIT_MOVE_LINE_UP: {
+
+ TextEdit *tx = current->get_text_edit();
+ Ref<Script> scr = current->get_edited_script();
+ if (scr.is_null())
+ return;
+
+ int line_id = tx->cursor_get_line();
+ int next_id = line_id - 1;
+
+ if (line_id == 0 || next_id < 0)
+ return;
+
+ String tmp = tx->get_line(line_id);
+ String tmp2 = tx->get_line(next_id);
+ tx->set_line(next_id, tmp);
+ tx->set_line(line_id, tmp2);
+ tx->update();
+ tx->cursor_set_line(next_id);
+
+ } break;
+ case EDIT_MOVE_LINE_DOWN: {
+
+ TextEdit *tx = current->get_text_edit();
+ Ref<Script> scr = current->get_edited_script();
+ if (scr.is_null())
+ return;
+
+ int line_id = tx->cursor_get_line();
+ int next_id = line_id + 1;
+
+ if (line_id == tx->get_line_count() || next_id > tx->get_line_count())
+ return;
+
+ String tmp = tx->get_line(line_id);
+ String tmp2 = tx->get_line(next_id);
+ tx->set_line(next_id, tmp);
+ tx->set_line(line_id, tmp2);
+ tx->update();
+ tx->cursor_set_line(next_id);
+
+ } break;
+ case EDIT_INDENT_LEFT: {
+
+ TextEdit *tx = current->get_text_edit();
+ Ref<Script> scr = current->get_edited_script();
+ if (scr.is_null())
+ return;
+
+ int begin, end;
+ begin = tx->get_selection_from_line();
+ if (tx->is_selection_active())
+ {
+ end = tx->get_selection_to_line();
+ for (int i = begin; i <= end; i++)
+ {
+ String line_text = tx->get_line(i);
+ line_text = line_text.substr(1, line_text.length());
+ tx->set_line(i, line_text);
+ }
+ }
+ else
+ {
+ begin = tx->cursor_get_line();
+ String line_text = tx->get_line(begin);
+ line_text = line_text.substr(1, line_text.length());
+ tx->set_line(begin, line_text);
+ }
+ tx->update();
+ tx->deselect();
+
+ } break;
+ case EDIT_INDENT_RIGHT: {
+
+ TextEdit *tx = current->get_text_edit();
+ Ref<Script> scr = current->get_edited_script();
+ if (scr.is_null())
+ return;
+
+ int begin, end;
+ begin = tx->get_selection_from_line();
+ if (tx->is_selection_active())
+ {
+ end = tx->get_selection_to_line();
+ for (int i = begin; i <= end; i++)
+ {
+ String line_text = tx->get_line(i);
+ line_text = '\t' + line_text;
+ tx->set_line(i, line_text);
+ }
+ }
+ else
+ {
+ begin = tx->cursor_get_line();
+ String line_text = tx->get_line(begin);
+ line_text = '\t' + line_text;
+ tx->set_line(begin, line_text);
+ }
+ tx->update();
+ tx->deselect();
+
+ } break;
+ case EDIT_CLONE_DOWN: {
+
+ TextEdit *tx = current->get_text_edit();
+ Ref<Script> scr = current->get_edited_script();
+ if (scr.is_null())
+ return;
+ int line = tx->cursor_get_line();
+ int next_line = line + 1;
+
+ if (line == tx->get_line_count() || next_line > tx->get_line_count())
+ return;
+
+ String line_clone = tx->get_line(line);
+ tx->insert_at(line_clone, next_line);
+ tx->update();
+
+ } break;
+ case EDIT_TOGGLE_COMMENT: {
+
+ TextEdit *tx = current->get_text_edit();
+ Ref<Script> scr = current->get_edited_script();
+ if (scr.is_null())
+ return;
+
+ int begin, end;
+ begin = tx->get_selection_from_line();
+ if (tx->is_selection_active())
+ {
+ end = tx->get_selection_to_line();
+ for (int i = begin; i <= end; i++)
+ {
+ String line_text = tx->get_line(i);
+
+ if (line_text.begins_with("#"))
+ line_text = line_text.strip_edges().substr(1, line_text.length());
+ else
+ line_text = "#" + line_text;
+ tx->set_line(i, line_text);
+ }
+ }
+ else
+ {
+ begin = tx->cursor_get_line();
+ String line_text = tx->get_line(begin);
+
+ if (line_text.begins_with("#"))
+ line_text = line_text.strip_edges().substr(1, line_text.length());
+ else
+ line_text = "#" + line_text;
+ tx->set_line(begin, line_text);
+ }
+ tx->update();
+ tx->deselect();
+
+ } break;
case EDIT_COMPLETE: {
current->get_text_edit()->query_code_comple();
@@ -1335,14 +1489,21 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
edit_menu = memnew( MenuButton );
menu_hb->add_child(edit_menu);
edit_menu->set_text("Edit");
- edit_menu->get_popup()->add_item("Undo");
- edit_menu->get_popup()->add_item("Redo");
+ edit_menu->get_popup()->add_item("Undo",EDIT_UNDO,KEY_MASK_CMD|KEY_Z);
+ edit_menu->get_popup()->add_item("Redo",EDIT_REDO,KEY_MASK_CMD|KEY_Y);
edit_menu->get_popup()->add_separator();
edit_menu->get_popup()->add_item("Cut",EDIT_CUT,KEY_MASK_CMD|KEY_X);
edit_menu->get_popup()->add_item("Copy",EDIT_COPY,KEY_MASK_CMD|KEY_C);
edit_menu->get_popup()->add_item("Paste",EDIT_PASTE,KEY_MASK_CMD|KEY_V);
edit_menu->get_popup()->add_separator();
edit_menu->get_popup()->add_item("Select All",EDIT_SELECT_ALL,KEY_MASK_CMD|KEY_A);
+ edit_menu->get_popup()->add_separator();
+ edit_menu->get_popup()->add_item("Move Line Up",EDIT_MOVE_LINE_UP,KEY_MASK_ALT|KEY_UP);
+ edit_menu->get_popup()->add_item("Move Line Down",EDIT_MOVE_LINE_DOWN,KEY_MASK_ALT|KEY_DOWN);
+ edit_menu->get_popup()->add_item("Indent Left",EDIT_INDENT_LEFT,KEY_MASK_ALT|KEY_LEFT);
+ edit_menu->get_popup()->add_item("Indent Right",EDIT_INDENT_RIGHT,KEY_MASK_ALT|KEY_RIGHT);
+ edit_menu->get_popup()->add_item("Toggle Comment",EDIT_TOGGLE_COMMENT,KEY_MASK_CMD|KEY_SLASH);
+ edit_menu->get_popup()->add_item("Clone Down",EDIT_CLONE_DOWN,KEY_MASK_CMD|KEY_B);
edit_menu->get_popup()->add_separator();
edit_menu->get_popup()->add_item("Complete Symbol",EDIT_COMPLETE,KEY_MASK_CMD|KEY_SPACE);
edit_menu->get_popup()->add_item("Auto Indent",EDIT_AUTO_INDENT,KEY_MASK_CMD|KEY_I);
diff --git a/tools/editor/plugins/script_editor_plugin.h b/tools/editor/plugins/script_editor_plugin.h
index 69b8739d67..62508253e3 100644
--- a/tools/editor/plugins/script_editor_plugin.h
+++ b/tools/editor/plugins/script_editor_plugin.h
@@ -123,6 +123,12 @@ class ScriptEditor : public VBoxContainer {
EDIT_SELECT_ALL,
EDIT_COMPLETE,
EDIT_AUTO_INDENT,
+ EDIT_TOGGLE_COMMENT,
+ EDIT_MOVE_LINE_UP,
+ EDIT_MOVE_LINE_DOWN,
+ EDIT_INDENT_RIGHT,
+ EDIT_INDENT_LEFT,
+ EDIT_CLONE_DOWN,
SEARCH_FIND,
SEARCH_FIND_NEXT,
SEARCH_REPLACE,
diff --git a/tools/export/blender25/io_scene_dae/export_dae.py b/tools/export/blender25/io_scene_dae/export_dae.py
index d3337033c8..f8e64452db 100644
--- a/tools/export/blender25/io_scene_dae/export_dae.py
+++ b/tools/export/blender25/io_scene_dae/export_dae.py
@@ -863,6 +863,20 @@ class DaeExporter:
if (node.parent.type=="ARMATURE"):
armature=node.parent
+ if (node.data.shape_keys!=None):
+ sk = node.data.shape_keys
+ if (sk.animation_data):
+ print("HAS ANIM")
+ print("DRIVERS: "+str(len(sk.animation_data.drivers)))
+ for d in sk.animation_data.drivers:
+ if (d.driver):
+ for v in d.driver.variables:
+ for t in v.targets:
+ if (t.id!=None and t.id.name in self.scene.objects):
+ print("LINKING "+str(node)+" WITH "+str(t.id.name))
+ self.armature_for_morph[node]=self.scene.objects[t.id.name]
+
+
meshdata = self.export_mesh(node,armature)
close_controller=False
@@ -1339,6 +1353,7 @@ class DaeExporter:
if (node.type=="MESH" and node.data!=None and (node in self.armature_for_morph) and (self.armature_for_morph[node] in allowed)):
pass #all good you pass with flying colors for morphs inside of action
else:
+ #print("fail "+str((node in self.armature_for_morph)))
continue
if (node.type=="MESH" and node.data!=None and node.data.shape_keys!=None and (node.data in self.mesh_cache) and len(node.data.shape_keys.key_blocks)):
target = self.mesh_cache[node.data]["morph_id"]
@@ -1453,11 +1468,11 @@ class DaeExporter:
allowed_skeletons.append(y)
y.animation_data.action=x;
-
+ print("allowed skeletons "+str(allowed_skeletons))
print(str(x))
- tcn = self.export_animation(int(x.frame_range[0]),int(x.frame_range[1]),allowed_skeletons)
+ tcn = self.export_animation(int(x.frame_range[0]),int(x.frame_range[1]+0.5),allowed_skeletons)
framelen=(1.0/self.scene.render.fps)
start = x.frame_range[0]*framelen
end = x.frame_range[1]*framelen
@@ -1563,6 +1578,7 @@ class DaeExporter:
+
def save(operator, context,
filepath="",
use_selection=False,