summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2014-11-02 11:31:01 -0300
committerJuan Linietsky <reduzio@gmail.com>2014-11-02 11:31:01 -0300
commitd85b67be53bac252c0a28b799d56d1b359c4ee99 (patch)
tree5227e145e3271bfee542bdd3e4237c3378565306 /tools
parent738eb2c1a88d441eacc4149ce8f1c12a90267191 (diff)
Bug Fixes
-=-=-=-=- -Fixed problem with scaling shapes (#827), related to not taking scale in consideration for calculating the moment of inertia -Added support for multiline strings (or comments) using """ -Save subscene bug, properties not being saved in root node (#806) -Fix Crash in CollisionPolygon2DEditor (#814) -Restored Ability to compile without 3D (#795) -Fix InterpolatedCamera (#803) -Fix UV Import for OBJ Meshes (#771) -Fixed issue with modifier gizmos (#794) -Fixed CapsuleShape gizmo handle (#50) -Fixed Import Button (not properly working in 3D) (#733) -Many misc fixes (though no new features)
Diffstat (limited to 'tools')
-rw-r--r--tools/editor/editor_node.cpp47
-rw-r--r--tools/editor/editor_node.h1
-rw-r--r--tools/editor/io_plugins/editor_import_collada.cpp12
-rw-r--r--tools/editor/io_plugins/editor_import_collada.h2
-rw-r--r--tools/editor/io_plugins/editor_mesh_import_plugin.cpp2
-rw-r--r--tools/editor/io_plugins/editor_scene_import_plugin.cpp609
-rw-r--r--tools/editor/io_plugins/editor_scene_import_plugin.h20
-rw-r--r--tools/editor/plugins/baked_light_baker_cmpxchg.cpp37
-rw-r--r--tools/editor/plugins/collision_polygon_2d_editor_plugin.cpp7
-rw-r--r--tools/editor/plugins/mesh_editor_plugin.cpp55
-rw-r--r--tools/editor/plugins/mesh_editor_plugin.h6
-rw-r--r--tools/editor/spatial_editor_gizmos.cpp2
12 files changed, 753 insertions, 47 deletions
diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp
index 701704fbfa..b23f6c2765 100644
--- a/tools/editor/editor_node.cpp
+++ b/tools/editor/editor_node.cpp
@@ -1310,6 +1310,8 @@ void EditorNode::_edit_current() {
p->add_item("Copy Params",OBJECT_COPY_PARAMS);
p->add_item("Set Params",OBJECT_PASTE_PARAMS);
p->add_separator();
+ p->add_item("Make Resources Unique",OBJECT_UNIQUE_RESOURCES);
+ p->add_separator();
p->add_icon_item(gui_base->get_icon("Help","EditorIcons"),"Class Reference",OBJECT_REQUEST_HELP);
List<MethodInfo> methods;
current_obj->get_method_list(&methods);
@@ -2023,6 +2025,47 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
editor_data.paste_object_params(current);
editor_data.get_undo_redo().clear_history();
} break;
+ case OBJECT_UNIQUE_RESOURCES: {
+
+ editor_data.apply_changes_in_editors();;
+ if (current) {
+ List<PropertyInfo> props;
+ current->get_property_list(&props);
+ Map<RES,RES> duplicates;
+ for (List<PropertyInfo>::Element *E=props.front();E;E=E->next()) {
+
+ if (!(E->get().usage&PROPERTY_USAGE_STORAGE))
+ continue;
+
+ Variant v = current->get(E->get().name);
+ if (v.is_ref()) {
+ REF ref = v;
+ if (ref.is_valid()) {
+
+ RES res = ref;
+ if (res.is_valid()) {
+
+ if (!duplicates.has(res)) {
+ duplicates[res]=res->duplicate();
+ }
+ res=duplicates[res];
+
+ current->set(E->get().name,res);
+ }
+
+ }
+ }
+
+ }
+ }
+
+ editor_data.get_undo_redo().clear_history();
+ if (editor_plugin_screen) { //reload editor plugin
+ editor_plugin_over->edit(NULL);
+ editor_plugin_over->edit(current);
+ }
+
+ } break;
case OBJECT_CALL_METHOD: {
editor_data.apply_changes_in_editors();;
@@ -3950,8 +3993,8 @@ EditorNode::EditorNode() {
Ref<EditorSceneImportPlugin> _scene_import = memnew(EditorSceneImportPlugin(this) );
Ref<EditorSceneImporterCollada> _collada_import = memnew( EditorSceneImporterCollada);
_scene_import->add_importer(_collada_import);
- Ref<EditorSceneImporterFBXConv> _fbxconv_import = memnew( EditorSceneImporterFBXConv);
- _scene_import->add_importer(_fbxconv_import);
+// Ref<EditorSceneImporterFBXConv> _fbxconv_import = memnew( EditorSceneImporterFBXConv);
+// _scene_import->add_importer(_fbxconv_import);
editor_import_export->add_import_plugin( _scene_import);
editor_import_export->add_import_plugin( Ref<EditorSceneAnimationImportPlugin>( memnew(EditorSceneAnimationImportPlugin(this))));
editor_import_export->add_import_plugin( Ref<EditorMeshImportPlugin>( memnew(EditorMeshImportPlugin(this))));
diff --git a/tools/editor/editor_node.h b/tools/editor/editor_node.h
index 2cec301cf6..7b66a7809e 100644
--- a/tools/editor/editor_node.h
+++ b/tools/editor/editor_node.h
@@ -133,6 +133,7 @@ class EditorNode : public Node {
RESOURCE_COPY,
OBJECT_COPY_PARAMS,
OBJECT_PASTE_PARAMS,
+ OBJECT_UNIQUE_RESOURCES,
OBJECT_CALL_METHOD,
OBJECT_REQUEST_HELP,
RUN_PLAY,
diff --git a/tools/editor/io_plugins/editor_import_collada.cpp b/tools/editor/io_plugins/editor_import_collada.cpp
index e86356ebe9..3fb45d1870 100644
--- a/tools/editor/io_plugins/editor_import_collada.cpp
+++ b/tools/editor/io_plugins/editor_import_collada.cpp
@@ -61,6 +61,7 @@ struct ColladaImport {
Color ambient;
bool found_directional;
bool force_make_tangents;
+ float bake_fps;
@@ -95,6 +96,7 @@ struct ColladaImport {
found_ambient=false;
found_directional=false;
force_make_tangents=false;
+ bake_fps=15;
}
};
@@ -1835,7 +1837,7 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
Vector<float> base_snapshots;
float f=0;
- float snapshot_interval = 1.0/20.0; //should be customizable somewhere...
+ float snapshot_interval = 1.0/bake_fps; //should be customizable somewhere...
float anim_length=collada.state.animation_length;
if (p_clip>=0 && collada.state.animation_clips[p_clip].end)
@@ -2142,14 +2144,14 @@ void EditorSceneImporterCollada::get_extensions(List<String> *r_extensions) cons
r_extensions->push_back("dae");
}
-Node* EditorSceneImporterCollada::import_scene(const String& p_path, uint32_t p_flags, List<String> *r_missing_deps, Error* r_err) {
-
+Node* EditorSceneImporterCollada::import_scene(const String& p_path, uint32_t p_flags,int p_bake_fps, List<String> *r_missing_deps, Error* r_err) {
ColladaImport state;
uint32_t flags=Collada::IMPORT_FLAG_SCENE;
if (p_flags&IMPORT_ANIMATION)
flags|=Collada::IMPORT_FLAG_ANIMATION;
+ state.bake_fps=p_bake_fps;
Error err = state.load(p_path,flags,p_flags&EditorSceneImporter::IMPORT_GENERATE_TANGENT_ARRAYS);
@@ -2174,7 +2176,7 @@ Node* EditorSceneImporterCollada::import_scene(const String& p_path, uint32_t p_
if (p_flags&IMPORT_ANIMATION) {
- state.create_animations(p_flags&IMPORT_ANIMATION_FORCE_TRACKS_IN_ALL_BONES);
+ state.create_animations(p_flags&IMPORT_ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS);
AnimationPlayer *ap = memnew( AnimationPlayer );
for(int i=0;i<state.animations.size();i++) {
String name;
@@ -2213,7 +2215,7 @@ Ref<Animation> EditorSceneImporterCollada::import_animation(const String& p_path
ERR_FAIL_COND_V(err!=OK,RES());
- state.create_animations(p_flags&EditorSceneImporter::IMPORT_ANIMATION_FORCE_TRACKS_IN_ALL_BONES);
+ state.create_animations(p_flags&EditorSceneImporter::IMPORT_ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS);
if (state.scene)
memdelete(state.scene);
diff --git a/tools/editor/io_plugins/editor_import_collada.h b/tools/editor/io_plugins/editor_import_collada.h
index 9580f42ed0..ae4cedeff6 100644
--- a/tools/editor/io_plugins/editor_import_collada.h
+++ b/tools/editor/io_plugins/editor_import_collada.h
@@ -40,7 +40,7 @@ public:
virtual uint32_t get_import_flags() const;
virtual void get_extensions(List<String> *r_extensions) const;
- virtual Node* import_scene(const String& p_path,uint32_t p_flags,List<String> *r_missing_deps=NULL,Error* r_err=NULL);
+ virtual Node* import_scene(const String& p_path,uint32_t p_flags,int p_bake_fps,List<String> *r_missing_deps=NULL,Error* r_err=NULL);
virtual Ref<Animation> import_animation(const String& p_path,uint32_t p_flags);
EditorSceneImporterCollada();
diff --git a/tools/editor/io_plugins/editor_mesh_import_plugin.cpp b/tools/editor/io_plugins/editor_mesh_import_plugin.cpp
index d76a778433..6ebdb6cc41 100644
--- a/tools/editor/io_plugins/editor_mesh_import_plugin.cpp
+++ b/tools/editor/io_plugins/editor_mesh_import_plugin.cpp
@@ -425,7 +425,7 @@ Error EditorMeshImportPlugin::import(const String& p_path, const Ref<ResourceImp
ERR_FAIL_COND_V(v.size()<3,ERR_INVALID_DATA);
Vector2 uv;
uv.x=v[1].to_float();
- uv.y=v[2].to_float();
+ uv.y=1.0-v[2].to_float();
uvs.push_back(uv);
} else if (l.begins_with("vn ")) {
diff --git a/tools/editor/io_plugins/editor_scene_import_plugin.cpp b/tools/editor/io_plugins/editor_scene_import_plugin.cpp
index 27400344d3..d7f0bd470c 100644
--- a/tools/editor/io_plugins/editor_scene_import_plugin.cpp
+++ b/tools/editor/io_plugins/editor_scene_import_plugin.cpp
@@ -78,12 +78,23 @@ class EditorImportAnimationOptions : public VBoxContainer {
OBJ_TYPE( EditorImportAnimationOptions, VBoxContainer );
+
+ TreeItem *fps;
+ TreeItem *clips_base;
+ TextEdit *filters;
+ Vector<TreeItem*> clips;
+
Tree *flags;
+ Tree *clips_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);
+
protected:
static void _bind_methods();
void _notification(int p_what);
@@ -93,6 +104,14 @@ public:
void set_flags(uint32_t p_flags);
uint32_t get_flags() const;
+ void set_fps(int p_fps);
+ int get_fps() const;
+
+ void setup_clips(const Array& p_clips);
+ Array get_clips() const;
+
+ void set_filter(const String& p_filter);
+ String get_filter() const;
EditorImportAnimationOptions();
@@ -141,6 +160,9 @@ class EditorSceneImportDialog : public ConfirmationDialog {
Map<Ref<Mesh>,Ref<Shape> > collision_map;
ConfirmationDialog *error_dialog;
+ OptionButton *this_import;
+ OptionButton *next_import;
+
void _choose_file(const String& p_path);
void _choose_save_file(const String& p_path);
void _choose_script(const String& p_path);
@@ -178,7 +200,7 @@ static const char *anim_flag_names[]={
"Detect Loop (-loop,-cycle)",
"Keep Value Tracks",
"Optimize",
- "Force Tracks in All Bones",
+ "Force All Tracks in All Clips",
NULL
};
@@ -223,9 +245,101 @@ void EditorImportAnimationOptions::_changed() {
}
+void EditorImportAnimationOptions::_button_action(Object *p_obj,int p_col,int p_id) {
+
+ memdelete(p_obj);
+
+}
+
+
+void EditorImportAnimationOptions::_item_edited() {
+
+ if (validating)
+ return;
+
+ if (clips.size()==0)
+ return;
+ validating=true;
+ print_line("edited");
+ TreeItem *item = clips_tree->get_edited();
+ if (item==clips[clips.size()-1]) {
+ //add new
+ print_line("islast");
+ if (item->get_text(0).find("<")!=-1 || item->get_text(0).find(">")!=-1) {
+ validating=false;
+ return; //fuckit
+ }
+
+ item->set_editable(1,true);
+ item->set_editable(2,true);
+ item->add_button(0,EditorNode::get_singleton()->get_gui_base()->get_icon("Del","EditorIcons"));
+ item->set_cell_mode(1,TreeItem::CELL_MODE_RANGE);
+ item->set_range_config(1,0,3600,0.01);
+ item->set_range(1,0);
+ item->set_editable(1,true);
+ item->set_cell_mode(2,TreeItem::CELL_MODE_RANGE);
+ item->set_range_config(2,0,3600,0.01);
+ item->set_range(2,0);
+ item->set_cell_mode(3,TreeItem::CELL_MODE_CHECK);
+ item->set_editable(3,true);
+
+ TreeItem *newclip = clips_tree->create_item(clips_base);
+ newclip->set_text(0,"<new clip>");
+ newclip->set_editable(0,true);
+ newclip->set_editable(1,false);
+ newclip->set_editable(2,false);
+ clips.push_back(newclip);
+
+
+
+ }
+
+
+ //make name unique JUST IN CASE
+ String name = item->get_text(0);
+ name=name.replace("/","_").replace(":","_").strip_edges();
+ if (name=="")
+ name="New Clip";
+
+ if (clips.size()>2) {
+ int index=1;
+ while(true) {
+ bool valid = true;
+ String try_name=name;
+ if (index>1)
+ try_name+=" "+itos(index);
+
+ for(int i=0;i<clips.size()-1;i++) {
+
+ if (clips[i]==item)
+ continue;
+ if (clips[i]->get_text(0)==try_name) {
+ index++;
+ valid=false;
+ break;
+ }
+ }
+
+ if (valid) {
+ name=try_name;
+ break;
+ }
+
+ }
+ }
+
+ if (item->get_text(0)!=name)
+ item->set_text(0,name);
+
+ validating=false;
+
+}
+
void EditorImportAnimationOptions::_bind_methods() {
ObjectTypeDB::bind_method("_changed",&EditorImportAnimationOptions::_changed);
+ ObjectTypeDB::bind_method("_item_edited",&EditorImportAnimationOptions::_item_edited);
+ ObjectTypeDB::bind_method("_button_action",&EditorImportAnimationOptions::_button_action);
// ObjectTypeDB::bind_method("_changedp",&EditorImportAnimationOptions::_changedp);
ADD_SIGNAL(MethodInfo("changed"));
@@ -237,17 +351,84 @@ void EditorImportAnimationOptions::_notification(int p_what) {
if (p_what==NOTIFICATION_ENTER_SCENE) {
flags->connect("item_edited",this,"_changed");
+ clips_tree->connect("item_edited",this,"_item_edited");
+ clips_tree->connect("button_pressed",this,"_button_action",varray(),CONNECT_DEFERRED);
// format->connect("item_selected",this,"_changedp");
}
}
+
+Array EditorImportAnimationOptions::get_clips() const {
+
+ Array arr;
+ for(int i=0;i<clips.size()-1;i++) {
+
+ arr.push_back(clips[i]->get_text(0));
+ arr.push_back(clips[i]->get_range(1));
+ arr.push_back(clips[i]->get_range(2));
+ arr.push_back(clips[i]->is_checked(3));
+ }
+
+ return arr;
+}
+
+
+void EditorImportAnimationOptions::setup_clips(const Array& p_clips) {
+
+ ERR_FAIL_COND(p_clips.size()%4!=0);
+ for(int i=0;i<clips.size();i++) {
+
+ memdelete(clips[i]);
+ }
+
+
+ clips.clear();
+
+ for(int i=0;i<p_clips.size();i+=4) {
+
+ TreeItem *clip = clips_tree->create_item(clips_base);
+ clip->set_text(0,p_clips[i]);
+ clip->add_button(0,EditorNode::get_singleton()->get_gui_base()->get_icon("Del","EditorIcons"));
+ clip->set_editable(0,true);
+ clip->set_cell_mode(1,TreeItem::CELL_MODE_RANGE);
+ clip->set_range_config(1,0,3600,0.01);
+ clip->set_range(1,p_clips[i+1]);
+ clip->set_editable(1,true);
+ clip->set_cell_mode(2,TreeItem::CELL_MODE_RANGE);
+ clip->set_range_config(2,0,3600,0.01);
+ clip->set_range(2,p_clips[i+2]);
+ clip->set_editable(2,true);
+ clip->set_cell_mode(3,TreeItem::CELL_MODE_CHECK);
+ clip->set_editable(3,true);
+ clip->set_checked(3,p_clips[i+3]);
+ clips.push_back(clip);
+
+ }
+
+ TreeItem *newclip = clips_tree->create_item(clips_base);
+ newclip->set_text(0,"<new clip>");
+ newclip->set_editable(0,true);
+ newclip->set_editable(1,false);
+ newclip->set_editable(2,false);
+ newclip->set_editable(3,false);
+ clips.push_back(newclip);
+
+}
+
+
EditorImportAnimationOptions::EditorImportAnimationOptions() {
updating=false;
+ validating=false;
+
+ TabContainer *tab= memnew(TabContainer);
+ add_margin_child("Animation Options",tab,true);
flags = memnew( Tree );
flags->set_hide_root(true);
+ tab->add_child(flags);
+ flags->set_name("Flags");
TreeItem *root = flags->create_item();
const char ** fname=anim_flag_names;
@@ -263,14 +444,69 @@ EditorImportAnimationOptions::EditorImportAnimationOptions() {
items.push_back(ti);
fname++;
fdescr++;
- }
+ }
+
+
+ TreeItem *fps_base = flags->create_item(root);
+ fps_base->set_text(0,"Bake FPS:");
+ fps_base->set_editable(0,false);
+ 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);
+
+
+ clips_tree = memnew( Tree );
+ clips_tree->set_hide_root(true);
+ tab->add_child(clips_tree);
+ clips_tree->set_name("Clips");
+
+ clips_tree->set_columns(4);
+ clips_tree->set_column_expand(0,1);
+ clips_tree->set_column_expand(1,0);
+ clips_tree->set_column_expand(2,0);
+ clips_tree->set_column_expand(3,0);
+ clips_tree->set_column_min_width(1,60);
+ clips_tree->set_column_min_width(2,60);
+ clips_tree->set_column_min_width(3,40);
+ clips_tree->set_column_titles_visible(true);
+ clips_tree->set_column_title(0,"Name");
+ clips_tree->set_column_title(1,"Start(s)");
+ clips_tree->set_column_title(2,"End(s)");
+ clips_tree->set_column_title(3,"Loop");
+ clips_base =clips_tree->create_item(0);
+
+
+ setup_clips(Array());
+
+
+ filters = memnew( TextEdit );
+ tab->add_child(filters);
+ filters->set_name("Filters");
+}
- add_margin_child("Animation Options",flags,true);
+void EditorImportAnimationOptions::set_fps(int p_fps) {
+
+ fps->set_range(0,p_fps);
}
+int EditorImportAnimationOptions::get_fps() const {
+ return fps->get_range(0);
+}
+
+void EditorImportAnimationOptions::set_filter(const String& p_filter) {
+
+ filters->set_text(p_filter);
+}
+
+String EditorImportAnimationOptions::get_filter() const {
+
+ return filters->get_text();
+}
@@ -413,7 +649,12 @@ void EditorSceneImportDialog::_import(bool p_and_open) {
rim->set_option("texture_format",texture_options->get_format());
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_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());
+ 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);
List<String> missing;
@@ -526,7 +767,7 @@ void EditorSceneImportDialog::_browse_script() {
void EditorSceneImportDialog::popup_import(const String &p_from) {
- popup_centered(Size2(700,500));
+ popup_centered(Size2(750,550));
if (p_from!="") {
Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_from);
if (rimd.is_null())
@@ -544,7 +785,17 @@ void EditorSceneImportDialog::popup_import(const String &p_from) {
texture_options->set_format(EditorTextureImportPlugin::ImageFormat(int(rimd->get_option("texture_format"))));
texture_options->set_quality(rimd->get_option("texture_quality"));
animation_options->set_flags(rimd->get_option("animation_flags"));
+ if (rimd->has_option("animation_clips"))
+ animation_options->setup_clips(rimd->get_option("animation_clips"));
+ if (rimd->has_option("animation_filters"))
+ 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"));
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)));
@@ -619,7 +870,7 @@ void EditorSceneImportDialog::_bind_methods() {
ObjectTypeDB::bind_method("_choose_file",&EditorSceneImportDialog::_choose_file);
ObjectTypeDB::bind_method("_choose_save_file",&EditorSceneImportDialog::_choose_save_file);
ObjectTypeDB::bind_method("_choose_script",&EditorSceneImportDialog::_choose_script);
- ObjectTypeDB::bind_method("_import",&EditorSceneImportDialog::_import);
+ ObjectTypeDB::bind_method("_import",&EditorSceneImportDialog::_import,DEFVAL(false));
ObjectTypeDB::bind_method("_browse",&EditorSceneImportDialog::_browse);
ObjectTypeDB::bind_method("_browse_target",&EditorSceneImportDialog::_browse_target);
ObjectTypeDB::bind_method("_browse_script",&EditorSceneImportDialog::_browse_script);
@@ -792,6 +1043,20 @@ EditorSceneImportDialog::EditorSceneImportDialog(EditorNode *p_editor, EditorSce
error_dialog->get_ok()->set_text("Accept");
// error_dialog->get_cancel()->hide();
+ this_import = memnew( OptionButton );
+ this_import->add_item("Overwrite Existing Scene");
+ this_import->add_item("Owerwrite Existing, Keep Materials");
+ this_import->add_item("Keep Existing, Merge with New");
+ this_import->add_item("Keep Existing, Ignore New");
+ vbc->add_margin_child("This Time:",this_import);
+
+ next_import = memnew( OptionButton );
+ next_import->add_item("Overwrite Existing Scene");
+ next_import->add_item("Owerwrite Existing, Keep Materials");
+ next_import->add_item("Keep Existing, Merge with New");
+ next_import->add_item("Keep Existing, Ignore New");
+ vbc->add_margin_child("Next Time:",next_import);
+
set_hide_on_ok(false);
GLOBAL_DEF("import/shared_textures","res://");
@@ -814,7 +1079,7 @@ EditorSceneImportDialog::EditorSceneImportDialog(EditorNode *p_editor, EditorSce
animation_options = memnew( EditorImportAnimationOptions );
ovb->add_child(animation_options);
animation_options->set_v_size_flags(SIZE_EXPAND_FILL);
- animation_options->set_flags(EditorSceneAnimationImportPlugin::ANIMATION_DETECT_LOOP|EditorSceneAnimationImportPlugin::ANIMATION_KEEP_VALUE_TRACKS|EditorSceneAnimationImportPlugin::ANIMATION_OPTIMIZE|EditorSceneAnimationImportPlugin::ANIMATION_FORCE_TRACKS_IN_ALL_BONES);
+ animation_options->set_flags(EditorSceneAnimationImportPlugin::ANIMATION_DETECT_LOOP|EditorSceneAnimationImportPlugin::ANIMATION_KEEP_VALUE_TRACKS|EditorSceneAnimationImportPlugin::ANIMATION_OPTIMIZE|EditorSceneAnimationImportPlugin::ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS);
confirm_import = memnew( ConfirmationDialog );
@@ -1815,6 +2080,79 @@ void EditorSceneImportPlugin::_merge_scenes(Node *p_node,Node *p_imported) {
}
+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_base && p_node->get_owner()!=p_base)
+ return;
+
+ MeshInstance *mi=p_node->cast_to<MeshInstance>();
+
+ if (mi) {
+
+ String path = p_base->get_path_to(p_node);
+ if (override_materials.has(path))
+ mi->set_material_override(override_materials[path]);
+
+ Ref<Mesh> mesh = mi->get_mesh();
+ if (mesh.is_valid() && !meshes_processed.has(mesh)) {
+ meshes_processed.insert(mesh);
+ 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)) {
+
+ Ref<Material> mat = mesh_materials[name];
+ mesh->surface_set_material(i,mat);
+ }
+ }
+ }
+ }
+
+ 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);
+ Set<Ref<Mesh> > mp;
+ _apply_materials(p_imported,p_imported,mesh_materials,override_materials,mp);
+
+}
#if 0
@@ -1882,14 +2220,20 @@ Error EditorSceneImportPlugin::import1(const Ref<ResourceImportMetadata>& p_from
int animation_flags=p_from->get_option("animation_flags");
int scene_flags = from->get_option("flags");
+ 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");
uint32_t import_flags=0;
if (animation_flags&EditorSceneAnimationImportPlugin::ANIMATION_DETECT_LOOP)
import_flags|=EditorSceneImporter::IMPORT_ANIMATION_DETECT_LOOP;
if (animation_flags&EditorSceneAnimationImportPlugin::ANIMATION_OPTIMIZE)
import_flags|=EditorSceneImporter::IMPORT_ANIMATION_OPTIMIZE;
- if (animation_flags&EditorSceneAnimationImportPlugin::ANIMATION_FORCE_TRACKS_IN_ALL_BONES)
- import_flags|=EditorSceneImporter::IMPORT_ANIMATION_FORCE_TRACKS_IN_ALL_BONES;
+ if (animation_flags&EditorSceneAnimationImportPlugin::ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS)
+ import_flags|=EditorSceneImporter::IMPORT_ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS;
if (scene_flags&SCENE_FLAG_IMPORT_ANIMATIONS)
import_flags|=EditorSceneImporter::IMPORT_ANIMATION;
//if (scene_flags&SCENE_FLAG_FAIL_ON_MISSING_IMAGES)
@@ -1902,7 +2246,7 @@ Error EditorSceneImportPlugin::import1(const Ref<ResourceImportMetadata>& p_from
Error err=OK;
- Node *scene = importer->import_scene(src_path,import_flags,r_missing,&err);
+ Node *scene = importer->import_scene(src_path,import_flags,fps,r_missing,&err);
if (!scene || err!=OK) {
return err;
}
@@ -1913,19 +2257,231 @@ Error EditorSceneImportPlugin::import1(const Ref<ResourceImportMetadata>& p_from
return OK;
}
+
+void EditorSceneImportPlugin::_create_clips(Node *scene, const Array& p_clips,bool p_bake_all) {
+
+ 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);
+
+ if (!anim->has_animation("default"))
+ return;
+
+
+ Ref<Animation> default_anim = anim->get_animation("default");
+
+ for(int i=0;i<p_clips.size();i+=4) {
+
+ String name = p_clips[i];
+ float from=p_clips[i+1];
+ float to=p_clips[i+2];
+ bool loop=p_clips[i+3];
+ if (from>=to)
+ continue;
+
+ Ref<Animation> new_anim = memnew( Animation );
+
+ for(int j=0;j<default_anim->get_track_count();j++) {
+
+
+ List<float> keys;
+ int kc = default_anim->track_get_key_count(j);
+ int dtrack=-1;
+ for(int k=0;k<kc;k++) {
+
+ float kt = default_anim->track_get_key_time(j,k);
+ if (kt>=from && kt<to) {
+
+ //found a key within range, so create track
+ if (dtrack==-1) {
+ new_anim->add_track(default_anim->track_get_type(j));
+ dtrack = new_anim->get_track_count()-1;
+ new_anim->track_set_path(dtrack,default_anim->track_get_path(j));
+
+ if (kt>(from+0.01) && k>0) {
+
+ if (default_anim->track_get_type(j)==Animation::TYPE_TRANSFORM) {
+ Quat q;
+ Vector3 p;
+ Vector3 s;
+ default_anim->transform_track_interpolate(j,from,&p,&q,&s);
+ new_anim->transform_track_insert_key(dtrack,0,p,q,s);
+ }
+ }
+
+ }
+
+ if (default_anim->track_get_type(j)==Animation::TYPE_TRANSFORM) {
+ Quat q;
+ Vector3 p;
+ Vector3 s;
+ default_anim->transform_track_get_key(j,k,&p,&q,&s);
+ new_anim->transform_track_insert_key(dtrack,kt-from,p,q,s);
+ }
+
+ }
+
+ if (dtrack!=-1 && kt>=to) {
+
+ if (default_anim->track_get_type(j)==Animation::TYPE_TRANSFORM) {
+ Quat q;
+ Vector3 p;
+ Vector3 s;
+ default_anim->transform_track_interpolate(j,to,&p,&q,&s);
+ new_anim->transform_track_insert_key(dtrack,to-from,p,q,s);
+ }
+ }
+
+ }
+
+ if (dtrack==-1 && p_bake_all) {
+ new_anim->add_track(default_anim->track_get_type(j));
+ dtrack = new_anim->get_track_count()-1;
+ new_anim->track_set_path(dtrack,default_anim->track_get_path(j));
+ if (default_anim->track_get_type(j)==Animation::TYPE_TRANSFORM) {
+
+
+ Quat q;
+ Vector3 p;
+ Vector3 s;
+ default_anim->transform_track_interpolate(j,from,&p,&q,&s);
+ new_anim->transform_track_insert_key(dtrack,0,p,q,s);
+ default_anim->transform_track_interpolate(j,to,&p,&q,&s);
+ new_anim->transform_track_insert_key(dtrack,to-from,p,q,s);
+ }
+
+ }
+ }
+
+
+ new_anim->set_loop(loop);
+ new_anim->set_length(to-from);
+ anim->add_animation(name,new_anim);
+ }
+
+ anim->remove_animation("default"); //remove default (no longer needed)
+}
+
+void EditorSceneImportPlugin::_filter_tracks(Node *scene, const String& p_text) {
+
+ 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);
+
+ Vector<String> strings = p_text.split("\n");
+ for(int i=0;i<strings.size();i++) {
+
+ strings[i]=strings[i].strip_edges();
+ }
+
+ List<StringName> anim_names;
+ anim->get_animation_list(&anim_names);
+ Set<String> keep;
+ for(List<StringName>::Element *E=anim_names.front();E;E=E->next()) {
+
+ String name = E->get();
+ bool valid_for_this=false;
+
+ for(int i=0;i<strings.size();i++) {
+
+
+ if (strings[i].begins_with("@")) {
+
+ valid_for_this=false;
+ keep.clear();
+
+ Vector<String> filters=strings[i].substr(1,strings[i].length()).split(",");
+ for(int j=0;j<filters.size();j++) {
+
+ String fname = filters[i].strip_edges();
+ if (fname=="")
+ continue;
+ int fc = fname[0];
+ bool plus;
+ if (fc=='+')
+ plus=true;
+ else if (fc=='-')
+ plus=false;
+ else
+ continue;
+
+ String filter=fname.substr(1,fname.length()).strip_edges();
+
+ if (!name.matchn(filter))
+ continue;
+ valid_for_this=plus;
+ }
+ } else if (valid_for_this) {
+
+ Ref<Animation> a = anim->get_animation(name);
+ if (!a.is_valid())
+ continue;
+
+ for(int j=0;j<a->get_track_count();j++) {
+
+ String path = a->track_get_path(j);
+
+ String tname = strings[i];
+ if (tname=="")
+ continue;
+ int fc = tname[0];
+ bool plus;
+ if (fc=='+')
+ plus=true;
+ else if (fc=='-')
+ plus=false;
+ else
+ continue;
+
+ String filter=tname.substr(1,tname.length()).strip_edges();
+
+ if (!path.matchn(filter))
+ continue;
+
+ if (plus)
+ keep.insert(path);
+ else if (!keep.has(path)) {
+ a->remove_track(j);
+ j--;
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+
+}
+
Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, const Ref<ResourceImportMetadata>& p_from) {
Error err=OK;
Ref<ResourceImportMetadata> from=p_from;
String src_path=EditorImportPlugin::expand_source_path(from->get_source_path(0));
int animation_flags=p_from->get_option("animation_flags");
+ 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");
EditorProgress progress("import","Import Scene",104);
progress.step("Importing Scene..",2);
- bool merge = !bool(from->get_option("reimport"));
+ bool reimport = bool(from->get_option("reimport"));
+ int this_time_action = from->get_option("import_this_time");
+ int next_time_action = from->get_option("import_next_time");
+
+ int import_action = reimport?this_time_action:next_time_action;
from->set_source_md5(0,FileAccess::get_md5(src_path));
from->set_editor(get_name());
@@ -1940,6 +2496,11 @@ 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_clips.size())
+ _create_clips(scene,animation_clips,animation_flags&EditorSceneAnimationImportPlugin::ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS);
+
+ _filter_tracks(scene,animation_filter);
+
/// BEFORE ANYTHING, RUN SCRIPT
@@ -2063,7 +2624,7 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c
/// BEFORE SAVING - MERGE
- if (merge) {
+ if (import_action!=SCENE_UPDATE_REPLACE_WITH_NEW) {
progress.step("Merging..",103);
@@ -2082,10 +2643,30 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c
if (existing) {
- _merge_scenes(existing,scene);
- memdelete(scene);
- scene=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;
+ }
+
}
}
diff --git a/tools/editor/io_plugins/editor_scene_import_plugin.h b/tools/editor/io_plugins/editor_scene_import_plugin.h
index 72b4089d89..8aafde93df 100644
--- a/tools/editor/io_plugins/editor_scene_import_plugin.h
+++ b/tools/editor/io_plugins/editor_scene_import_plugin.h
@@ -58,7 +58,7 @@ public:
IMPORT_ANIMATION=2,
IMPORT_ANIMATION_DETECT_LOOP=4,
IMPORT_ANIMATION_OPTIMIZE=8,
- IMPORT_ANIMATION_FORCE_TRACKS_IN_ALL_BONES=16,
+ IMPORT_ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS=16,
IMPORT_GENERATE_TANGENT_ARRAYS=256,
IMPORT_FAIL_ON_MISSING_DEPENDENCIES=512
@@ -66,7 +66,7 @@ public:
virtual uint32_t get_import_flags() const=0;
virtual void get_extensions(List<String> *r_extensions) const=0;
- virtual Node* import_scene(const String& p_path,uint32_t p_flags,List<String> *r_missing_deps,Error* r_err=NULL)=0;
+ virtual Node* import_scene(const String& p_path,uint32_t p_flags,int p_bake_fps,List<String> *r_missing_deps,Error* r_err=NULL)=0;
virtual Ref<Animation> import_animation(const String& p_path,uint32_t p_flags)=0;
@@ -108,10 +108,16 @@ class EditorSceneImportPlugin : public EditorImportPlugin {
void _find_resources(const Variant& p_var,Map<Ref<ImageTexture>,TextureRole >& image_map,int p_flags);
Node* _fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>,Ref<Shape> > &collision_map,uint32_t p_flags,Map<Ref<ImageTexture>,TextureRole >& image_map);
+ void _create_clips(Node *scene, const Array& p_clips, bool p_bake_all);
+ 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,Set<Node*> &checked_nodes);
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);
@@ -142,6 +148,13 @@ 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;
@@ -171,7 +184,7 @@ public:
ANIMATION_DETECT_LOOP=1,
ANIMATION_KEEP_VALUE_TRACKS=2,
ANIMATION_OPTIMIZE=4,
- ANIMATION_FORCE_TRACKS_IN_ALL_BONES=8
+ ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS=8
};
virtual String get_name() const;
@@ -185,5 +198,4 @@ public:
};
-
#endif // EDITOR_SCENE_IMPORT_PLUGIN_H
diff --git a/tools/editor/plugins/baked_light_baker_cmpxchg.cpp b/tools/editor/plugins/baked_light_baker_cmpxchg.cpp
index d08c9f6484..42d3fc5276 100644
--- a/tools/editor/plugins/baked_light_baker_cmpxchg.cpp
+++ b/tools/editor/plugins/baked_light_baker_cmpxchg.cpp
@@ -2,12 +2,11 @@
#include "typedefs.h"
-#ifdef WINDOWS_ENABLED
-
-#include "windows.h"
+#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
void baked_light_baker_add_64f(double *dst,double value) {
+
union {
int64_t i;
double f;
@@ -19,28 +18,22 @@ void baked_light_baker_add_64f(double *dst,double value) {
int64_t from = swapy.i;
swapy.f+=value;
int64_t to=swapy.i;
- int64_t result = InterlockedCompareExchange64((int64_t*)dst,to,from);
- if (result==from)
+ if (__sync_bool_compare_and_swap((int64_t*)dst,from,to))
break;
}
-
}
void baked_light_baker_add_64i(int64_t *dst,int64_t value) {
- while(true) {
- int64_t from = *dst;
- int64_t to = from+value;
- int64_t result = InterlockedCompareExchange64(dst,to,from);
- if (result==from)
- break;
- }
+ while(!__sync_bool_compare_and_swap(dst,*dst,(*dst)+value)) {}
+
}
-#elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
+#elif defined(WINDOWS_ENABLED)
-void baked_light_baker_add_64f(double *dst,double value) {
+#include "windows.h"
+void baked_light_baker_add_64f(double *dst,double value) {
union {
int64_t i;
@@ -53,17 +46,25 @@ void baked_light_baker_add_64f(double *dst,double value) {
int64_t from = swapy.i;
swapy.f+=value;
int64_t to=swapy.i;
- if (__sync_bool_compare_and_swap((int64_t*)dst,from,to))
+ int64_t result = InterlockedCompareExchange64((int64_t*)dst,to,from);
+ if (result==from)
break;
}
+
}
void baked_light_baker_add_64i(int64_t *dst,int64_t value) {
- while(!__sync_bool_compare_and_swap(dst,*dst,(*dst)+value)) {}
-
+ while(true) {
+ int64_t from = *dst;
+ int64_t to = from+value;
+ int64_t result = InterlockedCompareExchange64(dst,to,from);
+ if (result==from)
+ break;
+ }
}
+
#else
//in goder (the god of programmers) we trust
diff --git a/tools/editor/plugins/collision_polygon_2d_editor_plugin.cpp b/tools/editor/plugins/collision_polygon_2d_editor_plugin.cpp
index 080ed7d11c..96c7e4540c 100644
--- a/tools/editor/plugins/collision_polygon_2d_editor_plugin.cpp
+++ b/tools/editor/plugins/collision_polygon_2d_editor_plugin.cpp
@@ -13,7 +13,7 @@ void CollisionPolygon2DEditor::_notification(int p_what) {
button_create->set_icon( get_icon("Edit","EditorIcons"));
button_edit->set_icon( get_icon("MovePoint","EditorIcons"));
button_edit->set_pressed(true);
-
+ get_scene()->connect("node_removed",this,"_node_removed");
} break;
case NOTIFICATION_FIXED_PROCESS: {
@@ -28,6 +28,7 @@ void CollisionPolygon2DEditor::_node_removed(Node *p_node) {
if(p_node==node) {
node=NULL;
hide();
+ canvas_item_editor->get_viewport_control()->update();
}
}
@@ -83,6 +84,9 @@ void CollisionPolygon2DEditor::_wip_close() {
bool CollisionPolygon2DEditor::forward_input_event(const InputEvent& p_event) {
+ if (!node)
+ return false;
+
switch(p_event.type) {
case InputEvent::MOUSE_BUTTON: {
@@ -379,6 +383,7 @@ void CollisionPolygon2DEditor::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_menu_option"),&CollisionPolygon2DEditor::_menu_option);
ObjectTypeDB::bind_method(_MD("_canvas_draw"),&CollisionPolygon2DEditor::_canvas_draw);
+ ObjectTypeDB::bind_method(_MD("_node_removed"),&CollisionPolygon2DEditor::_node_removed);
}
diff --git a/tools/editor/plugins/mesh_editor_plugin.cpp b/tools/editor/plugins/mesh_editor_plugin.cpp
index b8a5bd3bbe..10e4c0b681 100644
--- a/tools/editor/plugins/mesh_editor_plugin.cpp
+++ b/tools/editor/plugins/mesh_editor_plugin.cpp
@@ -158,13 +158,54 @@ void MeshInstanceEditor::_menu_option(int p_option) {
ur->add_undo_method(node,"remove_child",nmi);
ur->commit_action();
} break;
+ case MENU_OPTION_CREATE_OUTLINE_MESH: {
+
+ outline_dialog->popup_centered(Size2(200,80));
+ } break;
}
}
+void MeshInstanceEditor::_create_outline_mesh() {
+
+ Ref<Mesh> mesh = node->get_mesh();
+ if (mesh.is_null()) {
+ err_dialog->set_text("MeshInstance lacks a Mesh!");
+ err_dialog->popup_centered(Size2(100,50));
+ return;
+ }
+
+ Ref<Mesh> mesho = mesh->create_outline(outline_size->get_val());
+
+ if (mesho.is_null()) {
+ err_dialog->set_text("Could not create outline!");
+ err_dialog->popup_centered(Size2(100,50));
+ return;
+ }
+
+ MeshInstance *mi = memnew( MeshInstance );
+ mi->set_mesh(mesho);
+ Node *owner=node->get_owner();
+ if (get_scene()->get_edited_scene_root()==node) {
+ owner=node;
+ }
+
+ UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
+
+ ur->create_action("Create Outline");
+
+ ur->add_do_method(node,"add_child",mi);
+ ur->add_do_method(mi,"set_owner",owner);
+
+ ur->add_do_reference(mi);
+ ur->add_undo_method(node,"remove_child",mi);
+ ur->commit_action();
+}
+
void MeshInstanceEditor::_bind_methods() {
ObjectTypeDB::bind_method("_menu_option",&MeshInstanceEditor::_menu_option);
+ ObjectTypeDB::bind_method("_create_outline_mesh",&MeshInstanceEditor::_create_outline_mesh);
}
MeshInstanceEditor::MeshInstanceEditor() {
@@ -182,9 +223,23 @@ MeshInstanceEditor::MeshInstanceEditor() {
options->get_popup()->add_item("Create Convex Collision Sibling",MENU_OPTION_CREATE_CONVEX_COLLISION_SHAPE);
options->get_popup()->add_separator();
options->get_popup()->add_item("Create Navigation Mesh",MENU_OPTION_CREATE_NAVMESH);
+ options->get_popup()->add_separator();
+ options->get_popup()->add_item("Create Outline Mesh..",MENU_OPTION_CREATE_OUTLINE_MESH);
options->get_popup()->connect("item_pressed", this,"_menu_option");
+ outline_dialog = memnew( ConfirmationDialog );
+ outline_dialog->set_title("Outline Size: ");
+ outline_size = memnew( SpinBox );
+ outline_size->set_min(0.001);
+ outline_size->set_max(1024);
+ outline_size->set_step(0.001);
+ outline_size->set_val(0.05);
+ outline_dialog->add_child(outline_size);
+ outline_dialog->set_child_rect(outline_size);
+ add_child(outline_dialog);
+ outline_dialog->connect("confirmed",this,"_create_outline_mesh");
+
}
diff --git a/tools/editor/plugins/mesh_editor_plugin.h b/tools/editor/plugins/mesh_editor_plugin.h
index 557eb90148..e502b5dc2b 100644
--- a/tools/editor/plugins/mesh_editor_plugin.h
+++ b/tools/editor/plugins/mesh_editor_plugin.h
@@ -20,8 +20,12 @@ class MeshInstanceEditor : public Node {
MENU_OPTION_CREATE_TRIMESH_COLLISION_SHAPE,
MENU_OPTION_CREATE_CONVEX_COLLISION_SHAPE,
MENU_OPTION_CREATE_NAVMESH,
+ MENU_OPTION_CREATE_OUTLINE_MESH,
};
+ ConfirmationDialog *outline_dialog;
+ SpinBox *outline_size;
+
AcceptDialog *err_dialog;
@@ -33,6 +37,8 @@ class MeshInstanceEditor : public Node {
void _menu_option(int p_option);
+ void _create_outline_mesh();
+
friend class MeshInstanceEditorPlugin;
MenuButton * options;
diff --git a/tools/editor/spatial_editor_gizmos.cpp b/tools/editor/spatial_editor_gizmos.cpp
index 04d5888861..d48a4ce813 100644
--- a/tools/editor/spatial_editor_gizmos.cpp
+++ b/tools/editor/spatial_editor_gizmos.cpp
@@ -1779,7 +1779,7 @@ void CollisionShapeSpatialGizmo::set_handle(int p_idx,Camera *p_camera, const Po
Ref<CapsuleShape> cs = s;
Vector3 ra,rb;
Geometry::get_closest_points_between_segments(Vector3(),axis*4096,sg[0],sg[1],ra,rb);
- float d = ra[p_idx];
+ float d = axis.dot(ra);
if (p_idx==1)
d-=cs->get_radius();
if (d<0.001)