diff options
Diffstat (limited to 'tools/editor/plugins')
| -rw-r--r-- | tools/editor/plugins/canvas_item_editor_plugin.cpp | 11 | ||||
| -rw-r--r-- | tools/editor/plugins/canvas_item_editor_plugin.h | 3 | ||||
| -rw-r--r-- | tools/editor/plugins/path_2d_editor_plugin.cpp | 4 | ||||
| -rw-r--r-- | tools/editor/plugins/script_editor_plugin.cpp | 14 | ||||
| -rw-r--r-- | tools/editor/plugins/shader_editor_plugin.cpp | 73 | ||||
| -rw-r--r-- | tools/editor/plugins/shader_editor_plugin.h | 6 | ||||
| -rw-r--r-- | tools/editor/plugins/shader_graph_editor_plugin.cpp | 1072 | ||||
| -rw-r--r-- | tools/editor/plugins/shader_graph_editor_plugin.h | 85 | ||||
| -rw-r--r-- | tools/editor/plugins/tile_map_editor_plugin.cpp | 79 | ||||
| -rw-r--r-- | tools/editor/plugins/tile_map_editor_plugin.h | 6 |
10 files changed, 1181 insertions, 172 deletions
diff --git a/tools/editor/plugins/canvas_item_editor_plugin.cpp b/tools/editor/plugins/canvas_item_editor_plugin.cpp index 43ebebeb2..514f4b652 100644 --- a/tools/editor/plugins/canvas_item_editor_plugin.cpp +++ b/tools/editor/plugins/canvas_item_editor_plugin.cpp @@ -2688,6 +2688,11 @@ HSplitContainer *CanvasItemEditor::get_palette_split() { return palette_split; } +VSplitContainer *CanvasItemEditor::get_bottom_split() { + + return bottom_split; +} + CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { tool = TOOL_SELECT; @@ -2702,9 +2707,13 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) { add_child( hb ); hb->set_area_as_parent_rect(); + bottom_split = memnew( VSplitContainer ); + bottom_split->set_v_size_flags(SIZE_EXPAND_FILL); + add_child(bottom_split); + palette_split = memnew( HSplitContainer); palette_split->set_v_size_flags(SIZE_EXPAND_FILL); - add_child(palette_split); + bottom_split->add_child(palette_split); Control *vp_base = memnew (Control); vp_base->set_v_size_flags(SIZE_EXPAND_FILL); diff --git a/tools/editor/plugins/canvas_item_editor_plugin.h b/tools/editor/plugins/canvas_item_editor_plugin.h index c56570d43..6648d486e 100644 --- a/tools/editor/plugins/canvas_item_editor_plugin.h +++ b/tools/editor/plugins/canvas_item_editor_plugin.h @@ -290,8 +290,8 @@ class CanvasItemEditor : public VBoxContainer { void _viewport_input_event(const InputEvent& p_event); void _viewport_draw(); -private: HSplitContainer *palette_split; + VSplitContainer *bottom_split; friend class CanvasItemEditorPlugin; protected: @@ -346,6 +346,7 @@ public: void add_control_to_menu_panel(Control *p_control); HSplitContainer *get_palette_split(); + VSplitContainer *get_bottom_split(); Control *get_viewport_control() { return viewport; } diff --git a/tools/editor/plugins/path_2d_editor_plugin.cpp b/tools/editor/plugins/path_2d_editor_plugin.cpp index 33ea5f358..49239343a 100644 --- a/tools/editor/plugins/path_2d_editor_plugin.cpp +++ b/tools/editor/plugins/path_2d_editor_plugin.cpp @@ -195,7 +195,7 @@ bool Path2DEditor::forward_input_event(const InputEvent& p_event) { Ref<Curve2D> curve = node->get_curve(); - Vector2 new_pos = moving_from + xform.basis_xform( gpoint - moving_screen_from ); + Vector2 new_pos = moving_from + xform.affine_inverse().basis_xform(gpoint - moving_screen_from); switch(action) { case ACTION_MOVING_POINT: { @@ -439,7 +439,7 @@ bool Path2DEditor::forward_input_event(const InputEvent& p_event) { Ref<Curve2D> curve = node->get_curve(); - Vector2 new_pos = moving_from + xform.basis_xform( gpoint - moving_screen_from ); + Vector2 new_pos = moving_from + xform.affine_inverse().basis_xform(gpoint - moving_screen_from); switch(action) { diff --git a/tools/editor/plugins/script_editor_plugin.cpp b/tools/editor/plugins/script_editor_plugin.cpp index 55957887d..4b7d1cf0e 100644 --- a/tools/editor/plugins/script_editor_plugin.cpp +++ b/tools/editor/plugins/script_editor_plugin.cpp @@ -188,7 +188,7 @@ void ScriptTextEditor::apply_code() { if (script.is_null()) return; - print_line("applying code"); +// print_line("applying code"); script->set_source_code(get_text_edit()->get_text()); script->update_exports(); } @@ -210,6 +210,7 @@ void ScriptTextEditor::_load_theme_settings() { get_text_edit()->add_color_override("font_selected_color",EDITOR_DEF("text_editor/text_selected_color",Color(1,1,1))); get_text_edit()->add_color_override("selection_color",EDITOR_DEF("text_editor/selection_color",Color(0.2,0.2,1))); get_text_edit()->add_color_override("brace_mismatch_color",EDITOR_DEF("text_editor/brace_mismatch_color",Color(1,0.2,0.2))); + get_text_edit()->add_color_override("current_line_color",EDITOR_DEF("text_editor/current_line_color",Color(0.3,0.5,0.8,0.15))); Color keyword_color= EDITOR_DEF("text_editor/keyword_color",Color(0.5,0.0,0.2)); @@ -1033,9 +1034,12 @@ void ScriptEditor::_menu_option(int p_option) { editor->emit_signal("request_help", text); } break; case WINDOW_CLOSE: { - - erase_tab_confirm->set_text("Close Tab?:\n\""+current->get_name()+"\""); - erase_tab_confirm->popup_centered(Point2(250,80)); + if (current->get_text_edit()->get_version()!=current->get_text_edit()->get_saved_version()) { + erase_tab_confirm->set_text("Close and save changes?\n\""+current->get_name()+"\""); + erase_tab_confirm->popup_centered(Point2(250,80)); + } else { + _close_current_tab(); + } } break; case WINDOW_MOVE_LEFT: { @@ -1603,7 +1607,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { edit_menu->get_popup()->add_item("Clone Down",EDIT_CLONE_DOWN,KEY_MASK_CMD|KEY_B); edit_menu->get_popup()->add_separator(); #ifdef OSX_ENABLED - edit_menu->get_popup()->add_item("Complete Symbol",EDIT_COMPLETE,KEY_MASK_META|KEY_SPACE); + edit_menu->get_popup()->add_item("Complete Symbol",EDIT_COMPLETE,KEY_MASK_CTRL|KEY_SPACE); #else edit_menu->get_popup()->add_item("Complete Symbol",EDIT_COMPLETE,KEY_MASK_CMD|KEY_SPACE); #endif diff --git a/tools/editor/plugins/shader_editor_plugin.cpp b/tools/editor/plugins/shader_editor_plugin.cpp index 3166383fc..2fcd4e8cd 100644 --- a/tools/editor/plugins/shader_editor_plugin.cpp +++ b/tools/editor/plugins/shader_editor_plugin.cpp @@ -57,9 +57,9 @@ void ShaderTextEditor::set_edited_shader(const Ref<Shader>& p_shader,ShaderLangu _load_theme_settings(); - if (p_type==ShaderLanguage::SHADER_MATERIAL_LIGHT) + if (p_type==ShaderLanguage::SHADER_MATERIAL_LIGHT || p_type==ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT) get_text_edit()->set_text(shader->get_light_code()); - else if (p_type==ShaderLanguage::SHADER_MATERIAL_VERTEX) + else if (p_type==ShaderLanguage::SHADER_MATERIAL_VERTEX || p_type==ShaderLanguage::SHADER_CANVAS_ITEM_VERTEX) get_text_edit()->set_text(shader->get_vertex_code()); else get_text_edit()->set_text(shader->get_fragment_code()); @@ -81,6 +81,7 @@ void ShaderTextEditor::_load_theme_settings() { get_text_edit()->add_color_override("font_selected_color",EDITOR_DEF("text_editor/text_selected_color",Color(1,1,1))); get_text_edit()->add_color_override("selection_color",EDITOR_DEF("text_editor/selection_color",Color(0.2,0.2,1))); get_text_edit()->add_color_override("brace_mismatch_color",EDITOR_DEF("text_editor/brace_mismatch_color",Color(1,0.2,0.2))); + get_text_edit()->add_color_override("current_line_color",EDITOR_DEF("text_editor/current_line_color",Color(0.3,0.5,0.8,0.15))); Color keyword_color= EDITOR_DEF("text_editor/keyword_color",Color(0.5,0.0,0.2)); @@ -131,17 +132,12 @@ void ShaderTextEditor::_validate_script() { String errortxt; int line,col; - String code; - if (type==ShaderLanguage::SHADER_MATERIAL_LIGHT) - code=get_text_edit()->get_text(); - else if (type==ShaderLanguage::SHADER_MATERIAL_VERTEX) - code=get_text_edit()->get_text(); - else - code=get_text_edit()->get_text(); - + String code=get_text_edit()->get_text(); //List<StringName> params; //shader->get_param_list(¶ms); + print_line("compile: type: "+itos(type)+" code:\n"+code); + Error err = ShaderLanguage::compile(code,type,NULL,NULL,&errortxt,&line,&col); if (err!=OK) { @@ -233,25 +229,7 @@ void ShaderEditor::_menu_option(int p_option) { goto_line_dialog->popup_find_line(current->get_text_edit()); } break; - case SHADER_POST_PROCESS_MODE:{ - - fragment_editor->set_edited_shader(shader,ShaderLanguage::SHADER_POST_PROCESS); - fragment_editor->_validate_script(); - apply_shaders(); - settings_menu->get_popup()->set_item_checked( settings_menu->get_popup()->get_item_index(SHADER_MATERIAL_MODE), false); - settings_menu->get_popup()->set_item_checked( settings_menu->get_popup()->get_item_index(SHADER_POST_PROCESS_MODE), true); - - - } break; - case SHADER_MATERIAL_MODE: { - fragment_editor->set_edited_shader(shader,ShaderLanguage::SHADER_MATERIAL_FRAGMENT); - fragment_editor->_validate_script(); - apply_shaders(); - settings_menu->get_popup()->set_item_checked( settings_menu->get_popup()->get_item_index(SHADER_MATERIAL_MODE), true); - settings_menu->get_popup()->set_item_checked( settings_menu->get_popup()->get_item_index(SHADER_POST_PROCESS_MODE), false); - - } break; } } @@ -408,18 +386,17 @@ void ShaderEditor::edit(const Ref<Shader>& p_shader) { shader=p_shader; if (shader->get_mode()==Shader::MODE_MATERIAL) { + vertex_editor->set_edited_shader(p_shader,ShaderLanguage::SHADER_MATERIAL_VERTEX); fragment_editor->set_edited_shader(p_shader,ShaderLanguage::SHADER_MATERIAL_FRAGMENT); light_editor->set_edited_shader(shader,ShaderLanguage::SHADER_MATERIAL_LIGHT); - settings_menu->get_popup()->set_item_checked( settings_menu->get_popup()->get_item_index(SHADER_MATERIAL_MODE), true); - settings_menu->get_popup()->set_item_checked( settings_menu->get_popup()->get_item_index(SHADER_POST_PROCESS_MODE), false); - } else { + } else if (shader->get_mode()==Shader::MODE_CANVAS_ITEM) { - fragment_editor->set_edited_shader(p_shader,ShaderLanguage::SHADER_POST_PROCESS); - settings_menu->get_popup()->set_item_checked( settings_menu->get_popup()->get_item_index(SHADER_MATERIAL_MODE), false); - settings_menu->get_popup()->set_item_checked( settings_menu->get_popup()->get_item_index(SHADER_POST_PROCESS_MODE), true); + vertex_editor->set_edited_shader(p_shader,ShaderLanguage::SHADER_CANVAS_ITEM_VERTEX); + fragment_editor->set_edited_shader(p_shader,ShaderLanguage::SHADER_CANVAS_ITEM_FRAGMENT); + light_editor->set_edited_shader(shader,ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT); } - vertex_editor->set_edited_shader(shader,ShaderLanguage::SHADER_MATERIAL_VERTEX); + //vertex_editor->set_edited_shader(shader,ShaderLanguage::SHADER_MATERIAL_VERTEX); // see if already has it @@ -495,15 +472,6 @@ ShaderEditor::ShaderEditor() { search_menu->get_popup()->add_item("Goto Line..",SEARCH_GOTO_LINE,KEY_MASK_CMD|KEY_G); search_menu->get_popup()->connect("item_pressed", this,"_menu_option"); - settings_menu = memnew( MenuButton ); - add_child(settings_menu); - settings_menu->set_pos(Point2(90,-1)); - settings_menu->set_text("Shader"); - settings_menu->get_popup()->add_check_item("Material Mode",SHADER_MATERIAL_MODE); - settings_menu->get_popup()->set_item_checked(settings_menu->get_popup()->get_item_index(SHADER_MATERIAL_MODE),true); - settings_menu->get_popup()->add_check_item("Post Process Mode",SHADER_POST_PROCESS_MODE); - - settings_menu->get_popup()->connect("item_pressed", this,"_menu_option"); tab_container->connect("tab_changed", this,"_tab_changed"); @@ -550,7 +518,13 @@ void ShaderEditorPlugin::edit(Object *p_object) { bool ShaderEditorPlugin::handles(Object *p_object) const { - return p_object->is_type("Shader"); + Shader *shader=p_object->cast_to<Shader>(); + if (!shader) + return false; + if (_2d) + return shader->get_mode()==Shader::MODE_CANVAS_ITEM; + else + return shader->get_mode()==Shader::MODE_MATERIAL; } void ShaderEditorPlugin::make_visible(bool p_visible) { @@ -596,12 +570,15 @@ void ShaderEditorPlugin::apply_changes() { shader_editor->apply_shaders(); } -ShaderEditorPlugin::ShaderEditorPlugin(EditorNode *p_node) { +ShaderEditorPlugin::ShaderEditorPlugin(EditorNode *p_node, bool p_2d) { editor=p_node; shader_editor = memnew( ShaderEditor ); - - SpatialEditor::get_singleton()->get_shader_split()->add_child(shader_editor); + _2d=p_2d; + if (p_2d) + add_custom_control(CONTAINER_CANVAS_EDITOR_BOTTOM,shader_editor); + else + add_custom_control(CONTAINER_SPATIAL_EDITOR_BOTTOM,shader_editor); // editor->get_viewport()->add_child(shader_editor); // shader_editor->set_area_as_parent_rect(); diff --git a/tools/editor/plugins/shader_editor_plugin.h b/tools/editor/plugins/shader_editor_plugin.h index 49caee5da..daaa0ccb9 100644 --- a/tools/editor/plugins/shader_editor_plugin.h +++ b/tools/editor/plugins/shader_editor_plugin.h @@ -79,9 +79,6 @@ class ShaderEditor : public Control { SEARCH_REPLACE, //SEARCH_LOCATE_SYMBOL, SEARCH_GOTO_LINE, - SHADER_MATERIAL_MODE, - SHADER_POST_PROCESS_MODE, - SHADER_SHADE_MODEL_MODE, }; @@ -134,6 +131,7 @@ class ShaderEditorPlugin : public EditorPlugin { OBJ_TYPE( ShaderEditorPlugin, EditorPlugin ); + bool _2d; ShaderEditor *shader_editor; EditorNode *editor; public: @@ -152,7 +150,7 @@ public: virtual void save_external_data(); virtual void apply_changes(); - ShaderEditorPlugin(EditorNode *p_node); + ShaderEditorPlugin(EditorNode *p_node,bool p_2d); ~ShaderEditorPlugin(); }; diff --git a/tools/editor/plugins/shader_graph_editor_plugin.cpp b/tools/editor/plugins/shader_graph_editor_plugin.cpp index 710f11e72..508e8b4cb 100644 --- a/tools/editor/plugins/shader_graph_editor_plugin.cpp +++ b/tools/editor/plugins/shader_graph_editor_plugin.cpp @@ -32,6 +32,642 @@ #include "scene/gui/menu_button.h" #include "scene/gui/panel.h" #include "spatial_editor_plugin.h" +#include "os/keyboard.h" +#include "canvas_item_editor_plugin.h" + +void GraphColorRampEdit::_input_event(const InputEvent& p_event) { + + if (p_event.type==InputEvent::KEY && p_event.key.pressed && p_event.key.scancode==KEY_DELETE && grabbed!=-1) { + + points.remove(grabbed); + grabbed=-1; + update(); + emit_signal("ramp_changed"); + accept_event(); + } + + if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && p_event.mouse_button.pressed) { + + update(); + int x = p_event.mouse_button.x; + int total_w = get_size().width-get_size().height-3; + if (x>total_w+3) { + + if (grabbed==-1) + return; + Size2 ms = Size2(350, picker->get_combined_minimum_size().height+10); + picker->set_color(points[grabbed].color); + popup->set_pos(get_global_pos()-Size2(0,ms.height)); + popup->set_size(ms); + popup->popup(); + return; + } + + + float ofs = CLAMP(x/float(total_w),0,1); + + grabbed=-1; + grabbing=true; + int pos=-1; + for(int i=0;i<points.size();i++) { + + if (ABS(x-points[i].offset*total_w)<4) { + grabbed=i; + } + if (points[i].offset<ofs) + pos=i; + } + + grabbed_at=ofs; + //grab or select + if (grabbed!=-1) { + return; + } + //insert + + + Point p; + p.offset=ofs; + + Point prev; + Point next; + + if (pos==-1) { + + prev.color=Color(0,0,0); + prev.offset=0; + if (points.size()) { + next=points[0]; + } else { + next.color=Color(1,1,1); + next.offset=1.0; + } + } else { + + if (pos==points.size()-1) { + next.color=Color(1,1,1); + next.offset=1.0; + } else { + next=points[pos+1]; + } + prev=points[pos]; + + } + + p.color=prev.color.linear_interpolate(next.color,(p.offset-prev.offset)/(next.offset-prev.offset)); + + points.push_back(p); + points.sort(); + for(int i=0;i<points.size();i++) { + if (points[i].offset==ofs) { + grabbed=i; + break; + } + } + + emit_signal("ramp_changed"); + + } + + if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && !p_event.mouse_button.pressed) { + + if (grabbing) { + grabbing=false; + emit_signal("ramp_changed"); + } + update(); + } + + if (p_event.type==InputEvent::MOUSE_MOTION && grabbing) { + + int total_w = get_size().width-get_size().height-3; + + int x = p_event.mouse_motion.x; + float newofs = CLAMP(x/float(total_w),0,1); + + bool valid=true; + for(int i=0;i<points.size();i++) { + + if (points[i].offset==newofs && i!=grabbed) { + valid=false; + } + } + + if (!valid) + return; + + points[grabbed].offset=newofs; + + points.sort(); + for(int i=0;i<points.size();i++) { + if (points[i].offset==newofs) { + grabbed=i; + break; + } + } + + emit_signal("ramp_changed"); + + update(); + } +} + +void GraphColorRampEdit::_notification(int p_what){ + + if (p_what==NOTIFICATION_ENTER_TREE) { + picker->connect("color_changed",this,"_color_changed"); + } + if (p_what==NOTIFICATION_DRAW) { + + + Point prev; + prev.offset=0; + prev.color=Color(0,0,0); + int w = get_size().x; + int h = get_size().y; + + int total_w = get_size().width-get_size().height-3; + + for(int i=-1;i<points.size();i++) { + + Point next; + if (i+1==points.size()) { + next.color=Color(1,1,1); + next.offset=1; + } else { + next=points[i+1]; + } + + if (prev.offset==next.offset) { + prev=next; + continue; + } + + Vector<Vector2> points; + Vector<Color> colors; + points.push_back(Vector2(prev.offset*total_w,h)); + points.push_back(Vector2(prev.offset*total_w,0)); + points.push_back(Vector2(next.offset*total_w,0)); + points.push_back(Vector2(next.offset*total_w,h)); + colors.push_back(prev.color); + colors.push_back(prev.color); + colors.push_back(next.color); + colors.push_back(next.color); + draw_primitive(points,colors,Vector<Point2>()); + prev=next; + } + + for(int i=0;i<points.size();i++) { + + Color col=i==grabbed?Color(1,0.0,0.0,0.9):Color(1,1,1,0.8); + + draw_line(Vector2(points[i].offset*total_w,0),Vector2(points[i].offset*total_w,h-1),Color(0,0,0,0.7)); + draw_line(Vector2(points[i].offset*total_w-1,h/2),Vector2(points[i].offset*total_w-1,h-1),col); + draw_line(Vector2(points[i].offset*total_w+1,h/2),Vector2(points[i].offset*total_w+1,h-1),col); + draw_line(Vector2(points[i].offset*total_w-1,h/2),Vector2(points[i].offset*total_w+1,h/2),col); + draw_line(Vector2(points[i].offset*total_w-1,h-1),Vector2(points[i].offset*total_w+1,h-1),col); + + } + + if (grabbed!=-1) { + + draw_rect(Rect2(total_w+3,0,h,h),points[grabbed].color); + } + + if (has_focus()) { + + draw_line(Vector2(-1,-1),Vector2(total_w+1,-1),Color(1,1,1,0.6)); + draw_line(Vector2(total_w+1,-1),Vector2(total_w+1,h+1),Color(1,1,1,0.6)); + draw_line(Vector2(total_w+1,h+1),Vector2(-1,h+1),Color(1,1,1,0.6)); + draw_line(Vector2(-1,-1),Vector2(-1,h+1),Color(1,1,1,0.6)); + } + + } +} + +Size2 GraphColorRampEdit::get_minimum_size() const { + + return Vector2(0,16); +} + + +void GraphColorRampEdit::_color_changed(const Color& p_color) { + + if (grabbed==-1) + return; + points[grabbed].color=p_color; + update(); + emit_signal("ramp_changed"); + +} + +void GraphColorRampEdit::set_ramp(const Vector<float>& p_offsets,const Vector<Color>& p_colors) { + + ERR_FAIL_COND(p_offsets.size()!=p_colors.size()); + points.clear(); + for(int i=0;i<p_offsets.size();i++) { + Point p; + p.offset=p_offsets[i]; + p.color=p_colors[i]; + points.push_back(p); + } + + points.sort(); + update(); +} + +Vector<float> GraphColorRampEdit::get_offsets() const{ + Vector<float> ret; + for(int i=0;i<points.size();i++) + ret.push_back(points[i].offset); + return ret; +} +Vector<Color> GraphColorRampEdit::get_colors() const{ + + Vector<Color> ret; + for(int i=0;i<points.size();i++) + ret.push_back(points[i].color); + return ret; +} + + +void GraphColorRampEdit::_bind_methods(){ + + ObjectTypeDB::bind_method(_MD("_input_event"),&GraphColorRampEdit::_input_event); + ObjectTypeDB::bind_method(_MD("_color_changed"),&GraphColorRampEdit::_color_changed); + ADD_SIGNAL(MethodInfo("ramp_changed")); +} + +GraphColorRampEdit::GraphColorRampEdit(){ + + grabbed=-1; + grabbing=false; + set_focus_mode(FOCUS_ALL); + + popup = memnew( PopupPanel ); + picker = memnew( ColorPicker ); + popup->add_child(picker); + popup->set_child_rect(picker); + add_child(popup); + +} +//////////// + +void GraphCurveMapEdit::_input_event(const InputEvent& p_event) { + + if (p_event.type==InputEvent::KEY && p_event.key.pressed && p_event.key.scancode==KEY_DELETE && grabbed!=-1) { + + points.remove(grabbed); + grabbed=-1; + update(); + emit_signal("curve_changed"); + accept_event(); + } + + if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && p_event.mouse_button.pressed) { + + update(); + Point2 p = Vector2(p_event.mouse_button.x,p_event.mouse_button.y)/get_size(); + p.y=1.0-p.y; + grabbed=-1; + grabbing=true; + + for(int i=0;i<points.size();i++) { + + Vector2 ps = p*get_size(); + Vector2 pt = Vector2(points[i].offset,points[i].height)*get_size(); + if (ps.distance_to(pt)<4) { + grabbed=i; + } + + } + + + //grab or select + if (grabbed!=-1) { + return; + } + //insert + + + Point np; + np.offset=p.x; + np.height=p.y; + + points.push_back(np); + points.sort(); + for(int i=0;i<points.size();i++) { + if (points[i].offset==p.x && points[i].height==p.y) { + grabbed=i; + break; + } + } + + emit_signal("curve_changed"); + + } + + if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && !p_event.mouse_button.pressed) { + + if (grabbing) { + grabbing=false; + emit_signal("curve_changed"); + } + update(); + } + + if (p_event.type==InputEvent::MOUSE_MOTION && grabbing) { + + Point2 p = Vector2(p_event.mouse_button.x,p_event.mouse_button.y)/get_size(); + p.y=1.0-p.y; + + p.x = CLAMP(p.x,0.0,1.0); + p.y = CLAMP(p.y,0.0,1.0); + + bool valid=true; + + for(int i=0;i<points.size();i++) { + + if (points[i].offset==p.x && points[i].height==p.y && i!=grabbed) { + valid=false; + } + } + + if (!valid) + return; + + points[grabbed].offset=p.x; + points[grabbed].height=p.y; + + points.sort(); + for(int i=0;i<points.size();i++) { + if (points[i].offset==p.x && points[i].height==p.y) { + grabbed=i; + break; + } + } + + emit_signal("curve_changed"); + + update(); + } +} + +void GraphCurveMapEdit::_plot_curve(const Vector2& p_a,const Vector2& p_b,const Vector2& p_c,const Vector2& p_d) { + + float geometry[4][4]; + float tmp1[4][4]; + float tmp2[4][4]; + float deltas[4][4]; + double x, dx, dx2, dx3; + double y, dy, dy2, dy3; + double d, d2, d3; + int lastx, lasty; + int newx, newy; + int ntimes; + int i,j; + + int xmax=get_size().x; + int ymax=get_size().y; + + /* construct the geometry matrix from the segment */ + for (i = 0; i < 4; i++) { + geometry[i][2] = 0; + geometry[i][3] = 0; + } + + geometry[0][0] = (p_a[0] * xmax); + geometry[1][0] = (p_b[0] * xmax); + geometry[2][0] = (p_c[0] * xmax); + geometry[3][0] = (p_d[0] * xmax); + + geometry[0][1] = (p_a[1] * ymax); + geometry[1][1] = (p_b[1] * ymax); + geometry[2][1] = (p_c[1] * ymax); + geometry[3][1] = (p_d[1] * ymax); + + /* subdivide the curve ntimes (1000) times */ + ntimes = 4 * xmax; + /* ntimes can be adjusted to give a finer or coarser curve */ + d = 1.0 / ntimes; + d2 = d * d; + d3 = d * d * d; + + /* construct a temporary matrix for determining the forward differencing deltas */ + tmp2[0][0] = 0; tmp2[0][1] = 0; tmp2[0][2] = 0; tmp2[0][3] = 1; + tmp2[1][0] = d3; tmp2[1][1] = d2; tmp2[1][2] = d; tmp2[1][3] = 0; + tmp2[2][0] = 6*d3; tmp2[2][1] = 2*d2; tmp2[2][2] = 0; tmp2[2][3] = 0; + tmp2[3][0] = 6*d3; tmp2[3][1] = 0; tmp2[3][2] = 0; tmp2[3][3] = 0; + + /* compose the basis and geometry matrices */ + + static const float CR_basis[4][4] = + { + { -0.5, 1.5, -1.5, 0.5 }, + { 1.0, -2.5, 2.0, -0.5 }, + { -0.5, 0.0, 0.5, 0.0 }, + { 0.0, 1.0, 0.0, 0.0 }, + }; + + for (i = 0; i < 4; i++) + { + for (j = 0; j < 4; j++) + { + tmp1[i][j] = (CR_basis[i][0] * geometry[0][j] + + CR_basis[i][1] * geometry[1][j] + + CR_basis[i][2] * geometry[2][j] + + CR_basis[i][3] * geometry[3][j]); + } + } + /* compose the above results to get the deltas matrix */ + + for (i = 0; i < 4; i++) + { + for (j = 0; j < 4; j++) + { + deltas[i][j] = (tmp2[i][0] * tmp1[0][j] + + tmp2[i][1] * tmp1[1][j] + + tmp2[i][2] * tmp1[2][j] + + tmp2[i][3] * tmp1[3][j]); + } + } + + + /* extract the x deltas */ + x = deltas[0][0]; + dx = deltas[1][0]; + dx2 = deltas[2][0]; + dx3 = deltas[3][0]; + + /* extract the y deltas */ + y = deltas[0][1]; + dy = deltas[1][1]; + dy2 = deltas[2][1]; + dy3 = deltas[3][1]; + + + lastx = CLAMP (x, 0, xmax); + lasty = CLAMP (y, 0, ymax); + +/* if (fix255) + { + cd->curve[cd->outline][lastx] = lasty; + } + else + { + cd->curve_ptr[cd->outline][lastx] = lasty; + if(gb_debug) printf("bender_plot_curve xmax:%d ymax:%d\n", (int)xmax, (int)ymax); + } +*/ + /* loop over the curve */ + for (i = 0; i < ntimes; i++) + { + /* increment the x values */ + x += dx; + dx += dx2; + dx2 += dx3; + + /* increment the y values */ + y += dy; + dy += dy2; + dy2 += dy3; + + newx = CLAMP ((Math::round (x)), 0, xmax); + newy = CLAMP ((Math::round (y)), 0, ymax); + + /* if this point is different than the last one...then draw it */ + if ((lastx != newx) || (lasty != newy)) + { +#if 0 + /* + if(fix255) + { + /* use fixed array size (for the curve graph) */ + cd->curve[cd->outline][newx] = newy; + } + else + { + /* use dynamic allocated curve_ptr (for the real curve) */ + cd->curve_ptr[cd->outline][newx] = newy; + + if(gb_debug) printf("outline: %d cX: %d cY: %d\n", (int)cd->outline, (int)newx, (int)newy); + } +#endif + draw_line(Vector2(lastx,ymax-lasty),Vector2(newx,ymax-newy),Color(0.8,0.8,0.8,0.8),2.0); + } + + lastx = newx; + lasty = newy; + } +} + + +void GraphCurveMapEdit::_notification(int p_what){ + + if (p_what==NOTIFICATION_DRAW) { + + draw_style_box(get_stylebox("bg","Tree"),Rect2(Point2(),get_size())); + + int w = get_size().x; + int h = get_size().y; + + Vector2 prev=Vector2(0,0); + Vector2 prev2=Vector2(0,0); + + for(int i=-1;i<points.size();i++) { + + Vector2 next; + Vector2 next2; + if (i+1>=points.size()) { + next=Vector2(1,1); + } else { + next=Vector2(points[i+1].offset,points[i+1].height); + } + + if (i+2>=points.size()) { + next2=Vector2(1,1); + } else { + next2=Vector2(points[i+2].offset,points[i+2].height); + } + + /*if (i==-1 && prev.offset==next.offset) { + prev=next; + continue; + }*/ + + _plot_curve(prev2,prev,next,next2); + + prev2=prev; + prev=next; + } + + for(int i=0;i<points.size();i++) { + + Color col=i==grabbed?Color(1,0.0,0.0,0.9):Color(1,1,1,0.8); + + + draw_rect(Rect2( Vector2(points[i].offset,1.0-points[i].height)*get_size()-Vector2(2,2),Vector2(5,5)),col); + } + +/* if (grabbed!=-1) { + + draw_rect(Rect2(total_w+3,0,h,h),points[grabbed].color); + } +*/ + if (has_focus()) { + + draw_line(Vector2(-1,-1),Vector2(w+1,-1),Color(1,1,1,0.6)); + draw_line(Vector2(w+1,-1),Vector2(w+1,h+1),Color(1,1,1,0.6)); + draw_line(Vector2(w+1,h+1),Vector2(-1,h+1),Color(1,1,1,0.6)); + draw_line(Vector2(-1,-1),Vector2(-1,h+1),Color(1,1,1,0.6)); + } + + } +} + +Size2 GraphCurveMapEdit::get_minimum_size() const { + + return Vector2(64,64); +} + + + +void GraphCurveMapEdit::set_points(const Vector<Vector2>& p_points) { + + + points.clear(); + for(int i=0;i<p_points.size();i++) { + Point p; + p.offset=p_points[i].x; + p.height=p_points[i].y; + points.push_back(p); + } + + points.sort(); + update(); +} + +Vector<Vector2> GraphCurveMapEdit::get_points() const { + Vector<Vector2> ret; + for(int i=0;i<points.size();i++) + ret.push_back(Vector2(points[i].offset,points[i].height)); + return ret; +} + +void GraphCurveMapEdit::_bind_methods(){ + + ObjectTypeDB::bind_method(_MD("_input_event"),&GraphCurveMapEdit::_input_event); + ADD_SIGNAL(MethodInfo("curve_changed")); +} + +GraphCurveMapEdit::GraphCurveMapEdit(){ + + grabbed=-1; + grabbing=false; + set_focus_mode(FOCUS_ALL); + +} + ////cbacks /// @@ -200,7 +836,7 @@ void ShaderGraphView::_vec_input_changed(double p_value, int p_id,Array p_arr){ } void ShaderGraphView::_xform_input_changed(int p_id, Node *p_button){ - print_line("XFIC"); + ToolButton *tb = p_button->cast_to<ToolButton>(); ped_popup->set_pos(tb->get_global_pos()+Vector2(0,tb->get_size().height)); ped_popup->set_size(tb->get_size()); @@ -306,6 +942,84 @@ void ShaderGraphView::_comment_edited(int p_id,Node* p_button) { } +void ShaderGraphView::_color_ramp_changed(int p_id,Node* p_ramp) { + + GraphColorRampEdit *cr=p_ramp->cast_to<GraphColorRampEdit>(); + + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + + + Vector<float> offsets=cr->get_offsets(); + Vector<Color> colors=cr->get_colors(); + + DVector<float> new_offsets; + DVector<Color> new_colors; + { + new_offsets.resize(offsets.size()); + new_colors.resize(colors.size()); + DVector<float>::Write ow=new_offsets.write(); + DVector<Color>::Write cw=new_colors.write(); + for(int i=0;i<new_offsets.size();i++) { + ow[i]=offsets[i]; + cw[i]=colors[i]; + } + + } + + + DVector<float> old_offsets=graph->color_ramp_node_get_offsets(type,p_id); + DVector<Color> old_colors=graph->color_ramp_node_get_colors(type,p_id); + + if (old_offsets.size()!=new_offsets.size()) + ur->create_action("Add/Remove to Color Ramp"); + else + ur->create_action("Modify Color Ramp",true); + + ur->add_do_method(graph.ptr(),"color_ramp_node_set_ramp",type,p_id,new_colors,new_offsets); + ur->add_undo_method(graph.ptr(),"color_ramp_node_set_ramp",type,p_id,old_colors,old_offsets); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + block_update=true; + ur->commit_action(); + block_update=false; +} + +void ShaderGraphView::_curve_changed(int p_id,Node* p_curve) { + + GraphCurveMapEdit *cr=p_curve->cast_to<GraphCurveMapEdit>(); + + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + + + Vector<Point2> points=cr->get_points(); + + DVector<Vector2> new_points; + { + new_points.resize(points.size()); + DVector<Vector2>::Write ow=new_points.write(); + for(int i=0;i<new_points.size();i++) { + ow[i]=points[i]; + } + + } + + + DVector<Vector2> old_points=graph->curve_map_node_get_points(type,p_id); + + if (old_points.size()!=new_points.size()) + ur->create_action("Add/Remove to Curve Map"); + else + ur->create_action("Modify Curve Map",true); + + ur->add_do_method(graph.ptr(),"curve_map_node_set_points",type,p_id,new_points); + ur->add_undo_method(graph.ptr(),"curve_map_node_set_points",type,p_id,old_points); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + block_update=true; + ur->commit_action(); + block_update=false; +} + void ShaderGraphView::_input_name_changed(const String& p_name, int p_id, Node *p_line_edit) { @@ -385,6 +1099,41 @@ void ShaderGraphView::_connection_request(const String& p_from, int p_from_slot, } +void ShaderGraphView::_disconnection_request(const String& p_from, int p_from_slot,const String& p_to,int p_to_slot) { + + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + + int from_idx=-1; + int to_idx=-1; + for (Map<int,GraphNode*>::Element *E=node_map.front();E;E=E->next()) { + + if (p_from==E->get()->get_name()) + from_idx=E->key(); + if (p_to==E->get()->get_name()) + to_idx=E->key(); + } + + ERR_FAIL_COND(from_idx==-1); + ERR_FAIL_COND(to_idx==-1); + + if (!graph->is_node_connected(type,from_idx,p_from_slot,to_idx,p_to_slot)) + return; //nothing to disconnect + + ur->create_action("Disconnect Graph Nodes"); + + List<ShaderGraph::Connection> conns; + + graph->get_node_connections(type,&conns); + //disconnect/reconnect dependencies + ur->add_do_method(graph.ptr(),"disconnect_node",type,from_idx,p_from_slot,to_idx,p_to_slot); + ur->add_undo_method(graph.ptr(),"connect_node",type,from_idx,p_from_slot,to_idx,p_to_slot); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + ur->commit_action(); + + +} + void ShaderGraphView::_node_removed(int p_id) { UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); @@ -410,7 +1159,7 @@ void ShaderGraphView::_node_removed(int p_id) { void ShaderGraphView::_node_moved(const Vector2& p_from, const Vector2& p_to,int p_id) { - print_line("moved from "+p_from+" to "+p_to); + ERR_FAIL_COND(!node_map.has(p_id)); UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); ur->create_action("Move Shader Graph Node"); @@ -433,8 +1182,8 @@ void ShaderGraphView::_create_node(int p_id) { GraphNode *gn = memnew( GraphNode ); gn->set_show_close_button(true); Color typecol[4]={ - Color(0.2,1,0.2), - Color(0.7,0.1,1), + Color(0.9,0.4,1), + Color(0.8,1,0.2), Color(1,0.2,0.2), Color(0,1,1) }; @@ -710,14 +1459,9 @@ void ShaderGraphView::_create_node(int p_id) { } break; // mat4 x mat4 - case ShaderGraph::NODE_XFORM_VEC_MULT: - case ShaderGraph::NODE_XFORM_VEC_INV_MULT: { - - if (graph->node_get_type(type,p_id)==ShaderGraph::NODE_XFORM_VEC_INV_MULT) - gn->set_title("XFVecMult"); - else - gn->set_title("XFVecInvMult"); + case ShaderGraph::NODE_XFORM_VEC_MULT: { + gn->set_title("XFVecMult"); Button *button = memnew( Button("RotOnly")); button->set_toggle_mode(true); @@ -739,6 +1483,32 @@ void ShaderGraphView::_create_node(int p_id) { gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); + } break; + case ShaderGraph::NODE_XFORM_VEC_INV_MULT: { + + gn->set_title("XFVecInvMult"); + + + Button *button = memnew( Button("RotOnly")); + button->set_toggle_mode(true); + button->set_pressed(graph->xform_vec_mult_node_get_no_translation(type,p_id)); + button->connect("toggled",this,"_xform_inv_rev_changed",varray(p_id)); + + gn->add_child(button); + + gn->add_child( memnew(Label("vec"))); + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("xf"))); + hbc->add_spacer(); + Label *l = memnew(Label("out")); + l->set_align(Label::ALIGN_RIGHT); + hbc->add_child( l); + gn->add_child(hbc); + + gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); + gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + } break; // mat4 x vec3 inverse mult (with no-translation option) case ShaderGraph::NODE_SCALAR_FUNC: { @@ -967,9 +1737,99 @@ void ShaderGraphView::_create_node(int p_id) { gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); - gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); + gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); } break; // vec3 interpolation (with optional curve) + case ShaderGraph::NODE_COLOR_RAMP: { + + gn->set_title("ColorRamp"); + GraphColorRampEdit * ramp = memnew( GraphColorRampEdit ); + + DVector<real_t> offsets = graph->color_ramp_node_get_offsets(type,p_id); + DVector<Color> colors = graph->color_ramp_node_get_colors(type,p_id); + + int oc = offsets.size(); + + if (oc) { + DVector<real_t>::Read rofs = offsets.read(); + DVector<Color>::Read rcol = colors.read(); + + Vector<float> ofsv; + Vector<Color> colorv; + for(int i=0;i<oc;i++) { + ofsv.push_back(rofs[i]); + colorv.push_back(rcol[i]); + } + + ramp->set_ramp(ofsv,colorv); + + } + + ramp->connect("ramp_changed",this,"_color_ramp_changed",varray(p_id,ramp)); + ramp->set_custom_minimum_size(Size2(128,1)); + gn->add_child(ramp); + + + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("c"))); + hbc->add_spacer(); + Label *l=memnew(Label("rgb")); + l->set_align(Label::ALIGN_RIGHT); + hbc->add_child( l); + gn->add_child(hbc); + l=memnew(Label("alpha")); + l->set_align(Label::ALIGN_RIGHT); + gn->add_child( l); + + + gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + gn->set_slot(2,false,ShaderGraph::SLOT_MAX,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + + + } break; // scalar interpolation (with optional curve) + case ShaderGraph::NODE_CURVE_MAP: { + + gn->set_title("CurveMap"); + GraphCurveMapEdit * map = memnew( GraphCurveMapEdit ); + + DVector<Vector2> points = graph->curve_map_node_get_points(type,p_id); + + int oc = points.size(); + + if (oc) { + DVector<Vector2>::Read rofs = points.read(); + + + Vector<Vector2> ofsv; + for(int i=0;i<oc;i++) { + ofsv.push_back(rofs[i]); + } + + map->set_points(ofsv); + + } + map->connect("curve_changed",this,"_curve_changed",varray(p_id,map)); + + //map->connect("map_changed",this,"_curve_map_changed",varray(p_id,map)); + map->set_custom_minimum_size(Size2(128,64)); + gn->add_child(map); + + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("c"))); + hbc->add_spacer(); + Label *l=memnew(Label("cmap")); + l->set_align(Label::ALIGN_RIGHT); + hbc->add_child( l); + gn->add_child(hbc); + + + gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + + + } break; // scalar interpolation (with optional curve) + case ShaderGraph::NODE_SCALAR_INPUT: { gn->set_title("ScalarUniform"); @@ -1117,6 +1977,28 @@ void ShaderGraphView::_create_node(int p_id) { gn->set_slot(3,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); } break; // cubemap input (assignable in material) + case ShaderGraph::NODE_DEFAULT_TEXTURE: { + + gn->set_title("CanvasItemTex"); + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("UV"))); + hbc->add_spacer(); + Label *l=memnew(Label("RGB")); + l->set_align(Label::ALIGN_RIGHT); + hbc->add_child(l); + gn->add_child(hbc); + l = memnew( Label ); + l->set_text("Alpha"); + l->set_align(Label::ALIGN_RIGHT); + gn->add_child(l); + + gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + gn->set_slot(1,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + + + } break; // screen texture sampler (takes UV) (only usable in fragment case Shader) + case ShaderGraph::NODE_OUTPUT: { gn->set_title("Output"); @@ -1157,7 +2039,7 @@ void ShaderGraphView::_create_node(int p_id) { graph_edit->add_child(gn); node_map[p_id]=gn; gn->set_offset(graph->node_get_pos(type,p_id)); - print_line("NODE "+itos(p_id)+" OFS "+gn->get_offset()); + } @@ -1180,7 +2062,7 @@ void ShaderGraphView::_update_graph() { List<int> nl; graph->get_node_list(type,&nl); - print_line("graph nodes: "+itos(nl.size())); + for(List<int>::Element *E=nl.front();E;E=E->next()) { _create_node(E->get()); @@ -1199,11 +2081,29 @@ void ShaderGraphView::_update_graph() { } +void ShaderGraphView::_sg_updated() { + + if (!graph.is_valid()) + return; + switch(graph->get_graph_error(type)) { + case ShaderGraph::GRAPH_OK: status->set_text(""); break; + case ShaderGraph::GRAPH_ERROR_CYCLIC: status->set_text("Error: Cyclic Connection Link"); break; + case ShaderGraph::GRAPH_ERROR_MISSING_CONNECTIONS: status->set_text("Error: Missing Input Connections"); break; + } +} + void ShaderGraphView::set_graph(Ref<ShaderGraph> p_graph){ - print_line("GRAPH EDIT: "+itos(p_graph.is_valid())); + + if (graph.is_valid()) { + graph->disconnect("updated",this,"_sg_updated"); + } graph=p_graph; + if (graph.is_valid()) { + graph->connect("updated",this,"_sg_updated"); + } _update_graph(); + _sg_updated(); } @@ -1262,6 +2162,7 @@ void ShaderGraphView::_bind_methods() { ObjectTypeDB::bind_method("_move_node",&ShaderGraphView::_move_node); ObjectTypeDB::bind_method("_node_removed",&ShaderGraphView::_node_removed); ObjectTypeDB::bind_method("_connection_request",&ShaderGraphView::_connection_request); + ObjectTypeDB::bind_method("_disconnection_request",&ShaderGraphView::_disconnection_request); ObjectTypeDB::bind_method("_scalar_const_changed",&ShaderGraphView::_scalar_const_changed); ObjectTypeDB::bind_method("_vec_const_changed",&ShaderGraphView::_vec_const_changed); @@ -1285,7 +2186,10 @@ void ShaderGraphView::_bind_methods() { ObjectTypeDB::bind_method("_variant_edited",&ShaderGraphView::_variant_edited); ObjectTypeDB::bind_method("_cube_edited",&ShaderGraphView::_cube_edited); ObjectTypeDB::bind_method("_comment_edited",&ShaderGraphView::_comment_edited); + ObjectTypeDB::bind_method("_color_ramp_changed",&ShaderGraphView::_color_ramp_changed); + ObjectTypeDB::bind_method("_curve_changed",&ShaderGraphView::_curve_changed); + ObjectTypeDB::bind_method("_sg_updated",&ShaderGraphView::_sg_updated); } ShaderGraphView::ShaderGraphView(ShaderGraph::ShaderType p_type) { @@ -1295,8 +2199,15 @@ ShaderGraphView::ShaderGraphView(ShaderGraph::ShaderType p_type) { block_update=false; ped_popup = memnew( CustomPropertyEditor ); graph_edit->add_child(ped_popup); - - + status = memnew( Label ); + graph_edit->get_top_layer()->add_child(status); + status->set_pos(Vector2(5,5)); + status->add_color_override("font_color_shadow",Color(0,0,0)); + status->add_color_override("font_color",Color(1,0.4,0.3)); + status->add_constant_override("shadow_as_outline",1); + status->add_constant_override("shadow_offset_x",2); + status->add_constant_override("shadow_offset_y",2); + status->set_text(""); } @@ -1318,6 +2229,25 @@ void ShaderGraphEditor::_add_node(int p_type) { void ShaderGraphEditor::_notification(int p_what) { if (p_what==NOTIFICATION_ENTER_TREE) { + + for(int i=0;i<ShaderGraph::NODE_TYPE_MAX;i++) { + + if (i==ShaderGraph::NODE_OUTPUT) + continue; + if (!_2d && i==ShaderGraph::NODE_DEFAULT_TEXTURE) + continue; + + String nn = node_names[i]; + String ic = nn.get_slice(":",0); + String v = nn.get_slice(":",1); + bool addsep=false; + if (nn.ends_with(":")) { + addsep=true; + } + menu->get_popup()->add_icon_item(get_icon(ic,"EditorIcons"),v,i); + if (addsep) + menu->get_popup()->add_separator(); + } menu->get_popup()->connect("item_pressed",this,"_add_node"); @@ -1332,62 +2262,53 @@ void ShaderGraphEditor::_bind_methods() { const char* ShaderGraphEditor::node_names[ShaderGraph::NODE_TYPE_MAX]={ - "Input", // all inputs (shader type dependent) - "Scalar Constant", //scalar constant - "Vector Constant", //vec3 constant - "RGB Constant", //rgb constant (shows a color picker instead) - "XForm Constant", // 4x4 matrix constant - "Time:", // time in seconds - "Screen Sample", // screen texture sampler (takes uv) (only usable in fragment shader) - "Scalar Operator", // scalar vs scalar op (mul", add", div", etc) - "Vector Operator", // vec3 vs vec3 op (mul",ad",div",crossprod",etc) - "Scalar+Vector Operator", // vec3 vs scalar op (mul", add", div", etc) - "RGB Operator:", // vec3 vs vec3 rgb op (with scalar amount)", like brighten", darken", burn", dodge", multiply", etc. - "XForm Multiply", // mat4 x mat4 - "XForm+Vector Multiply", // mat4 x vec3 mult (with no-translation option) - "XForm+Vector InvMultiply:", // mat4 x vec3 inverse mult (with no-translation option) - "Scalar Function", // scalar function (sin", cos", etc) - "Vector Function", // vector function (normalize", negate", reciprocal", rgb2hsv", hsv2rgb", etc", etc) - "Vector Length", // vec3 length - "Dot Product:", // vec3 . vec3 (dot product -> scalar output) - "Vector -> Scalars", // 1 vec3 input", 3 scalar outputs - "Scalars -> Vector", // 3 scalar input", 1 vec3 output - "XForm -> Vectors", // 3 vec input", 1 xform output - "Vectors -> XForm:", // 3 vec input", 1 xform output - "Scalar Interpolate", // scalar interpolation (with optional curve) - "Vector Interpolate:", // vec3 interpolation (with optional curve) - "Scalar Uniform", // scalar uniform (assignable in material) - "Vector Uniform", // vec3 uniform (assignable in material) - "RGB Uniform", // color uniform (assignable in material) - "XForm Uniform", // mat4 uniform (assignable in material) - "Texture Uniform", // texture input (assignable in material) - "CubeMap Uniform:", // cubemap input (assignable in material) - "Output", // output (shader type dependent) - "Comment", // comment + "GraphInput:Input", // all inputs (shader type dependent) + "GraphScalar:Scalar Constant", //scalar constant + "GraphVector:Vector Constant", //vec3 constant + "GraphRgb:RGB Constant", //rgb constant (shows a color picker instead) + "GraphXform:XForm Constant", // 4x4 matrix constant + "GraphTime:Time:", // time in seconds + "GraphTexscreen:Screen Sample", // screen texture sampler (takes uv) (only usable in fragment shader) + "GraphScalarOp:Scalar Operator", // scalar vs scalar op (mul", add", div", etc) + "GraphVecOp:Vector Operator", // vec3 vs vec3 op (mul",ad",div",crossprod",etc) + "GraphVecScalarOp:Scalar+Vector Operator", // vec3 vs scalar op (mul", add", div", etc) + "GraphRgbOp:RGB Operator:", // vec3 vs vec3 rgb op (with scalar amount)", like brighten", darken", burn", dodge", multiply", etc. + "GraphXformMult:XForm Multiply", // mat4 x mat4 + "GraphXformVecMult:XForm+Vector Multiply", // mat4 x vec3 mult (with no-translation option) + "GraphXformVecImult:Form+Vector InvMultiply:", // mat4 x vec3 inverse mult (with no-translation option) + "GraphXformScalarFunc:Scalar Function", // scalar function (sin", cos", etc) + "GraphXformVecFunc:Vector Function", // vector function (normalize", negate", reciprocal", rgb2hsv", hsv2rgb", etc", etc) + "GraphVecLength:Vector Length", // vec3 length + "GraphVecDp:Dot Product:", // vec3 . vec3 (dot product -> scalar output) + "GraphVecToScalars:Vector -> Scalars", // 1 vec3 input", 3 scalar outputs + "GraphScalarsToVec:Scalars -> Vector", // 3 scalar input", 1 vec3 output + "GraphXformToVecs:XForm -> Vectors", // 3 vec input", 1 xform output + "GraphVecsToXform:Vectors -> XForm:", // 3 vec input", 1 xform output + "GraphScalarInterp:Scalar Interpolate", // scalar interpolation (with optional curve) + "GraphVecInterp:Vector Interpolate:", // vec3 interpolation (with optional curve) + "GraphColorRamp:Color Ramp", // vec3 interpolation (with optional curve) + "GraphCurveMap:Curve Remap:", // vec3 interpolation (with optional curve) + "GraphScalarUniform:Scalar Uniform", // scalar uniform (assignable in material) + "GraphVectorUniform:Vector Uniform", // vec3 uniform (assignable in material) + "GraphRgbUniform:RGB Uniform", // color uniform (assignable in material) + "GraphXformUniform:XForm Uniform", // mat4 uniform (assignable in material) + "GraphTextureUniform:Texture Uniform", // texture input (assignable in material) + "GraphCubeUniform:CubeMap Uniform:", // cubemap input (assignable in material) + "GraphDefaultTexture:CanvasItem Texture:", // cubemap input (assignable in material) + "Output", // output (shader type dependent) + "GraphComment:Comment", // comment }; -ShaderGraphEditor::ShaderGraphEditor() { +ShaderGraphEditor::ShaderGraphEditor(bool p_2d) { + _2d=p_2d; HBoxContainer *hbc = memnew( HBoxContainer ); menu = memnew( MenuButton ); - menu->set_text("Add.."); + menu->set_text("Add Node.."); hbc->add_child(menu); add_child(hbc); - for(int i=0;i<ShaderGraph::NODE_TYPE_MAX;i++) { - if (i==ShaderGraph::NODE_OUTPUT) - continue; - String v = node_names[i]; - bool addsep=false; - if (v.ends_with(":")) { - addsep=true; - v=v.substr(0,v.length()-1); - } - menu->get_popup()->add_item(v,i); - if (addsep) - menu->get_popup()->add_separator(); - } tabs = memnew(TabContainer); tabs->set_v_size_flags(SIZE_EXPAND_FILL); @@ -1404,8 +2325,13 @@ ShaderGraphEditor::ShaderGraphEditor() { graph_edits[i]->get_graph_edit()->set_name(sname[i]); tabs->add_child(graph_edits[i]->get_graph_edit()); graph_edits[i]->get_graph_edit()->connect("connection_request",graph_edits[i],"_connection_request"); + graph_edits[i]->get_graph_edit()->connect("disconnection_request",graph_edits[i],"_disconnection_request"); + graph_edits[i]->get_graph_edit()->set_right_disconnects(true); + } + tabs->set_current_tab(1); + set_custom_minimum_size(Size2(100,300)); } @@ -1417,7 +2343,13 @@ void ShaderGraphEditorPlugin::edit(Object *p_object) { bool ShaderGraphEditorPlugin::handles(Object *p_object) const { - return p_object->is_type("ShaderGraph"); + ShaderGraph *shader=p_object->cast_to<ShaderGraph>(); + if (!shader) + return false; + if (_2d) + return shader->get_mode()==Shader::MODE_CANVAS_ITEM; + else + return shader->get_mode()==Shader::MODE_MATERIAL; } void ShaderGraphEditorPlugin::make_visible(bool p_visible) { @@ -1431,12 +2363,16 @@ void ShaderGraphEditorPlugin::make_visible(bool p_visible) { } -ShaderGraphEditorPlugin::ShaderGraphEditorPlugin(EditorNode *p_node) { +ShaderGraphEditorPlugin::ShaderGraphEditorPlugin(EditorNode *p_node, bool p_2d) { + _2d=p_2d; editor=p_node; - shader_editor = memnew( ShaderGraphEditor ); + shader_editor = memnew( ShaderGraphEditor(p_2d) ); shader_editor->hide(); - SpatialEditor::get_singleton()->get_shader_split()->add_child(shader_editor); + if (p_2d) + CanvasItemEditor::get_singleton()->get_bottom_split()->add_child(shader_editor); + else + SpatialEditor::get_singleton()->get_shader_split()->add_child(shader_editor); // editor->get_viewport()->add_child(shader_editor); diff --git a/tools/editor/plugins/shader_graph_editor_plugin.h b/tools/editor/plugins/shader_graph_editor_plugin.h index 26dbd1ac6..1726302e9 100644 --- a/tools/editor/plugins/shader_graph_editor_plugin.h +++ b/tools/editor/plugins/shader_graph_editor_plugin.h @@ -45,6 +45,77 @@ */ +class GraphColorRampEdit : public Control { + + OBJ_TYPE(GraphColorRampEdit,Control); + + + struct Point { + + float offset; + Color color; + bool operator<(const Point& p_ponit) const { + return offset<p_ponit.offset; + } + }; + + PopupPanel *popup; + ColorPicker *picker; + + + bool grabbing; + int grabbed; + float grabbed_at; + Vector<Point> points; + + void _color_changed(const Color& p_color); + +protected: + void _input_event(const InputEvent& p_event); + void _notification(int p_what); + static void _bind_methods(); +public: + + void set_ramp(const Vector<float>& p_offsets,const Vector<Color>& p_colors); + Vector<float> get_offsets() const; + Vector<Color> get_colors() const; + virtual Size2 get_minimum_size() const; + GraphColorRampEdit(); +}; + + +class GraphCurveMapEdit : public Control { + + OBJ_TYPE(GraphCurveMapEdit,Control); + + + struct Point { + + float offset; + float height; + bool operator<(const Point& p_ponit) const { + return offset<p_ponit.offset; + } + }; + + + bool grabbing; + int grabbed; + Vector<Point> points; + + void _plot_curve(const Vector2& p_a,const Vector2& p_b,const Vector2& p_c,const Vector2& p_d); +protected: + void _input_event(const InputEvent& p_event); + void _notification(int p_what); + static void _bind_methods(); +public: + + void set_points(const Vector<Vector2>& p_points); + Vector<Vector2> get_points() const; + virtual Size2 get_minimum_size() const; + GraphCurveMapEdit(); +}; + class ShaderGraphView : public Node { OBJ_TYPE(ShaderGraphView,Node); @@ -54,6 +125,7 @@ class ShaderGraphView : public Node { CustomPropertyEditor *ped_popup; bool block_update; + Label *status; GraphEdit *graph_edit; Ref<ShaderGraph> graph; int edited_id; @@ -66,6 +138,8 @@ class ShaderGraphView : public Node { void _connection_request(const String& p_from, int p_from_slot,const String& p_to,int p_to_slot); + void _disconnection_request(const String& p_from, int p_from_slot,const String& p_to,int p_to_slot); + void _node_removed(int p_id); void _node_moved(const Vector2& p_from, const Vector2& p_to,int p_id); void _move_node(int p_id,const Vector2& p_to); @@ -92,8 +166,9 @@ class ShaderGraphView : public Node { void _cube_edited(int p_id,Node* p_button); void _variant_edited(); void _comment_edited(int p_id,Node* p_button); - - + void _color_ramp_changed(int p_id,Node* p_ramp); + void _curve_changed(int p_id,Node* p_curve); + void _sg_updated(); Map<int,GraphNode*> node_map; protected: void _notification(int p_what); @@ -116,6 +191,7 @@ class ShaderGraphEditor : public VBoxContainer { ShaderGraphView *graph_edits[ShaderGraph::SHADER_TYPE_MAX]; static const char* node_names[ShaderGraph::NODE_TYPE_MAX]; + bool _2d; void _add_node(int p_type); protected: void _notification(int p_what); @@ -123,13 +199,14 @@ protected: public: void edit(Ref<ShaderGraph> p_shader); - ShaderGraphEditor(); + ShaderGraphEditor(bool p_2d); }; class ShaderGraphEditorPlugin : public EditorPlugin { OBJ_TYPE( ShaderGraphEditorPlugin, EditorPlugin ); + bool _2d; ShaderGraphEditor *shader_editor; EditorNode *editor; @@ -141,7 +218,7 @@ public: virtual bool handles(Object *p_node) const; virtual void make_visible(bool p_visible); - ShaderGraphEditorPlugin(EditorNode *p_node); + ShaderGraphEditorPlugin(EditorNode *p_node,bool p_2d); ~ShaderGraphEditorPlugin(); }; diff --git a/tools/editor/plugins/tile_map_editor_plugin.cpp b/tools/editor/plugins/tile_map_editor_plugin.cpp index a7e6a0d1f..ce5ea5812 100644 --- a/tools/editor/plugins/tile_map_editor_plugin.cpp +++ b/tools/editor/plugins/tile_map_editor_plugin.cpp @@ -73,6 +73,18 @@ int TileMapEditor::get_selected_tile() const { return item->get_metadata(0); } +void TileMapEditor::set_selected_tile(int p_tile) { + TreeItem *item = palette->get_root()->get_children(); + while (item) { + if ((int)item->get_metadata(0) == p_tile) { + item->select(0); + palette->ensure_cursor_is_visible(); + break; + } + item = item->get_next(); + } +} + void TileMapEditor::_set_cell(const Point2i& p_pos,int p_value,bool p_flip_h, bool p_flip_v,bool p_with_undo) { ERR_FAIL_COND(!node); @@ -224,28 +236,25 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { canvas_item_editor->update(); return true; + } else if (mb.mod.control) { + tool=TOOL_PICKING; + set_selected_tile(node->get_cell(over_tile.x, over_tile.y)); + canvas_item_editor->update(); + return true; } else { int id = get_selected_tile(); if (id!=TileMap::INVALID_CELL) { tool=TOOL_PAINTING; Point2i local =node->world_to_map((xform_inv.xform(Point2(mb.x,mb.y)))); paint_undo.clear(); - CellOp op; - op.idx = node->get_cell(local.x,local.y); - if (op.idx>=0) { - if (node->is_cell_x_flipped(local.x,local.y)) - op.xf=true; - if (node->is_cell_y_flipped(local.x,local.y)) - op.yf=true; - } - paint_undo[local]=op; + paint_undo[local]=_get_op_from_cell(local); node->set_cell(local.x,local.y,id,mirror_x->is_pressed(),mirror_y->is_pressed()); return true; } } } else { - if (tool==TOOL_PAINTING || tool == TOOL_SELECTING) { + if (tool==TOOL_PAINTING || tool == TOOL_SELECTING || tool == TOOL_PICKING) { if (tool==TOOL_PAINTING) { @@ -279,15 +288,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { tool=TOOL_ERASING; Point2i local =node->world_to_map(xform_inv.xform(Point2(mb.x,mb.y))); paint_undo.clear(); - CellOp op; - op.idx = node->get_cell(local.x,local.y); - if (op.idx>=0) { - if (node->is_cell_x_flipped(local.x,local.y)) - op.xf=true; - if (node->is_cell_y_flipped(local.x,local.y)) - op.yf=true; - } - paint_undo[local]=op; + paint_undo[local]=_get_op_from_cell(local); //node->set_cell(local.x,local.y,id,mirror_x->is_pressed(),mirror_y->is_pressed()); //return true; _set_cell(local,TileMap::INVALID_CELL); @@ -337,15 +338,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { if (!paint_undo.has(over_tile)) { - CellOp op; - op.idx = node->get_cell(over_tile.x,over_tile.y); - if (op.idx>=0) { - if (node->is_cell_x_flipped(over_tile.x,over_tile.y)) - op.xf=true; - if (node->is_cell_y_flipped(over_tile.x,over_tile.y)) - op.yf=true; - } - paint_undo[over_tile]=op; + paint_undo[over_tile]=_get_op_from_cell(over_tile); } node->set_cell(over_tile.x,over_tile.y,id,mirror_x->is_pressed(),mirror_y->is_pressed()); @@ -374,25 +367,22 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { return true; } + if (tool==TOOL_ERASING) { Point2i local =over_tile; if (!paint_undo.has(over_tile)) { - - CellOp op; - op.idx = node->get_cell(over_tile.x,over_tile.y); - if (op.idx>=0) { - if (node->is_cell_x_flipped(over_tile.x,over_tile.y)) - op.xf=true; - if (node->is_cell_y_flipped(over_tile.x,over_tile.y)) - op.yf=true; - } - paint_undo[over_tile]=op; + paint_undo[over_tile]=_get_op_from_cell(over_tile); } //node->set_cell(over_tile.x,over_tile.y,id,mirror_x->is_pressed(),mirror_y->is_pressed()); _set_cell(local,TileMap::INVALID_CELL); return true; } + if (tool==TOOL_PICKING) { + set_selected_tile(node->get_cell(over_tile.x, over_tile.y)); + canvas_item_editor->update(); + return true; + } } break; case InputEvent::KEY: { @@ -710,6 +700,19 @@ void TileMapEditor::_bind_methods() { } +TileMapEditor::CellOp TileMapEditor::_get_op_from_cell(const Point2i& p_pos) +{ + CellOp op; + op.idx = node->get_cell(p_pos.x,p_pos.y); + if (op.idx>=0) { + if (node->is_cell_x_flipped(p_pos.x,p_pos.y)) + op.xf=true; + if (node->is_cell_y_flipped(p_pos.x,p_pos.y)) + op.yf=true; + } + return op; +} + TileMapEditor::TileMapEditor(EditorNode *p_editor) { node=NULL; diff --git a/tools/editor/plugins/tile_map_editor_plugin.h b/tools/editor/plugins/tile_map_editor_plugin.h index ef869591b..f3c590e22 100644 --- a/tools/editor/plugins/tile_map_editor_plugin.h +++ b/tools/editor/plugins/tile_map_editor_plugin.h @@ -51,7 +51,8 @@ class TileMapEditor : public VBoxContainer { TOOL_PAINTING, TOOL_SELECTING, TOOL_ERASING, - TOOL_DUPLICATING + TOOL_DUPLICATING, + TOOL_PICKING }; Tool tool; @@ -81,11 +82,13 @@ class TileMapEditor : public VBoxContainer { bool xf; bool yf; CellOp() { idx=-1; xf=false; yf=false; } + CellOp(const CellOp& p_other) : idx(p_other.idx), xf(p_other.xf), yf(p_other.yf) {} }; Map<Point2i,CellOp> paint_undo; int get_selected_tile() const; + void set_selected_tile(int p_tile); void _update_palette(); void _canvas_draw(); @@ -102,6 +105,7 @@ protected: void _notification(int p_what); void _node_removed(Node *p_node); static void _bind_methods(); + CellOp _get_op_from_cell(const Point2i& p_pos); public: HBoxContainer *get_canvas_item_editor_hb() const { return canvas_item_editor_hb; } |
