diff options
author | Juan Linietsky <reduzio@gmail.com> | 2014-11-02 11:31:01 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2014-11-02 11:31:01 -0300 |
commit | d85b67be53bac252c0a28b799d56d1b359c4ee99 (patch) | |
tree | 5227e145e3271bfee542bdd3e4237c3378565306 /tools | |
parent | 738eb2c1a88d441eacc4149ce8f1c12a90267191 (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.cpp | 47 | ||||
-rw-r--r-- | tools/editor/editor_node.h | 1 | ||||
-rw-r--r-- | tools/editor/io_plugins/editor_import_collada.cpp | 12 | ||||
-rw-r--r-- | tools/editor/io_plugins/editor_import_collada.h | 2 | ||||
-rw-r--r-- | tools/editor/io_plugins/editor_mesh_import_plugin.cpp | 2 | ||||
-rw-r--r-- | tools/editor/io_plugins/editor_scene_import_plugin.cpp | 609 | ||||
-rw-r--r-- | tools/editor/io_plugins/editor_scene_import_plugin.h | 20 | ||||
-rw-r--r-- | tools/editor/plugins/baked_light_baker_cmpxchg.cpp | 37 | ||||
-rw-r--r-- | tools/editor/plugins/collision_polygon_2d_editor_plugin.cpp | 7 | ||||
-rw-r--r-- | tools/editor/plugins/mesh_editor_plugin.cpp | 55 | ||||
-rw-r--r-- | tools/editor/plugins/mesh_editor_plugin.h | 6 | ||||
-rw-r--r-- | tools/editor/spatial_editor_gizmos.cpp | 2 |
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)
|