From 5e3a4c13da5971b48ff8f0434165ea9da2084479 Mon Sep 17 00:00:00 2001 From: yg2f Date: Sat, 10 Jan 2015 15:11:44 +0100 Subject: fixes cubemap ressource editor bug this fixes the cubemap ressource editor bug described in issue #908. some other littles fixes will be required to allow the Environment ressource to create and load Cubemap Ressources more easily --- scene/resources/texture.cpp | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index dae055890b..889042f451 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -935,21 +935,21 @@ float CubeMap::get_lossy_storage_quality() const { bool CubeMap::_set(const StringName& p_name, const Variant& p_value) { - if (p_name=="side/left") + if (p_name=="side/left") { set_side(SIDE_LEFT,p_value); - if (p_name=="side/right") + } else if (p_name=="side/right") { set_side(SIDE_RIGHT,p_value); - if (p_name=="side/bottom") + } else if (p_name=="side/bottom") { set_side(SIDE_BOTTOM,p_value); - if (p_name=="side/top") + } else if (p_name=="side/top") { set_side(SIDE_TOP,p_value); - if (p_name=="side/front") + } else if (p_name=="side/front") { set_side(SIDE_FRONT,p_value); - if (p_name=="side/back") + } else if (p_name=="side/back") { set_side(SIDE_BACK,p_value); - else if (p_name=="flags") + } else if (p_name=="flags") { set_flags(p_value); - else if (p_name=="storage") { + } else if (p_name=="storage") { storage=Storage(p_value.operator int()); } else if (p_name=="lossy_quality") { lossy_storage_quality=p_value; @@ -962,25 +962,25 @@ bool CubeMap::_set(const StringName& p_name, const Variant& p_value) { bool CubeMap::_get(const StringName& p_name,Variant &r_ret) const { - if (p_name=="side/left") + if (p_name=="side/left") { r_ret=get_side(SIDE_LEFT); - if (p_name=="side/right") + } else if (p_name=="side/right") { r_ret=get_side(SIDE_RIGHT); - if (p_name=="side/bottom") + } else if (p_name=="side/bottom") { r_ret=get_side(SIDE_BOTTOM); - if (p_name=="side/top") + } else if (p_name=="side/top") { r_ret=get_side(SIDE_TOP); - if (p_name=="side/front") + } else if (p_name=="side/front") { r_ret=get_side(SIDE_FRONT); - if (p_name=="side/back") + } else if (p_name=="side/back") { r_ret=get_side(SIDE_BACK); - else if (p_name=="flags") + } else if (p_name=="flags") { r_ret= flags; - else if (p_name=="storage") + } else if (p_name=="storage") { r_ret= storage; - else if (p_name=="lossy_quality") + } else if (p_name=="lossy_quality") { r_ret= lossy_storage_quality; - else + } else return false; return true; -- cgit v1.2.3 From 6c4e1650fb8b7e06c8657ca1a5de167184fda6c0 Mon Sep 17 00:00:00 2001 From: Dana Olson Date: Sat, 10 Jan 2015 12:55:12 -0500 Subject: add option to automatically reload changed scripts --- tools/editor/plugins/script_editor_plugin.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/editor/plugins/script_editor_plugin.cpp b/tools/editor/plugins/script_editor_plugin.cpp index 55957887dc..20aeb05a50 100644 --- a/tools/editor/plugins/script_editor_plugin.cpp +++ b/tools/editor/plugins/script_editor_plugin.cpp @@ -630,7 +630,10 @@ bool ScriptEditor::_test_script_times_on_disk() { if (!all_ok) - disk_changed->call_deferred("popup_centered_ratio",0.5); + if (bool(EDITOR_DEF("text_editor/autoreload_changed_scripts",false))) + script_editor->_reload_scripts(); + else + disk_changed->call_deferred("popup_centered_ratio",0.5); return all_ok; } -- cgit v1.2.3 From d6d85a23c9061149c7996a3b434e6f9b25a81e49 Mon Sep 17 00:00:00 2001 From: "Bil Bas (Spooner)" Date: Sat, 10 Jan 2015 20:42:28 +0000 Subject: Ignored more generated files. --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 45bf531311..87f9986e59 100644 --- a/.gitignore +++ b/.gitignore @@ -12,12 +12,14 @@ drivers/gles2/shaders/*.h modules/register_module_types.cpp core/version.h core/method_bind.inc +core/method_bind_ext.inc core/script_encryption_key.cpp core/global_defaults.cpp tools/editor/register_exporters.cpp tools/editor/doc_data_compressed.h tools/editor/editor_icons.cpp -fpic +log.txt # Android specific platform/android/java/local.properties -- cgit v1.2.3 From 7a41f8c604143eec16c232cffda122b095c5108f Mon Sep 17 00:00:00 2001 From: "Bil Bas (Spooner)" Date: Sat, 10 Jan 2015 20:44:20 +0000 Subject: Added basic sprintf functionality (e.g. "fish %d %s" % [12, Vector2(1, 2)]) --- bin/tests/test_string.cpp | 79 +++++++++++++++++++++++++++++++++++++- core/ustring.cpp | 98 +++++++++++++++++++++++++++++++++++++++++++++++ core/ustring.h | 4 +- core/variant_op.cpp | 14 +++++++ 4 files changed, 193 insertions(+), 2 deletions(-) diff --git a/bin/tests/test_string.cpp b/bin/tests/test_string.cpp index 66238b066d..c932aeb3b4 100644 --- a/bin/tests/test_string.cpp +++ b/bin/tests/test_string.cpp @@ -487,7 +487,7 @@ struct test_27_data { bool test_27() { - OS::get_singleton()->print("\n\nTest 26: begins_with\n"); + OS::get_singleton()->print("\n\nTest 27: begins_with\n"); test_27_data tc[] = { {"res://foobar", "res://", true}, {"res", "res://", false}, @@ -504,11 +504,87 @@ bool test_27() { } if (!state) { OS::get_singleton()->print("\n\t Failure on:\n\t\tstring: ", tc[i].data, "\n\t\tbegin: ", tc[i].begin, "\n\t\texpected: ", tc[i].expected ? "true" : "false", "\n"); + break; } }; return state; }; + +bool test_28() { + + OS::get_singleton()->print("\n\nTest 28: sprintf\n"); + + bool success, state = true; + char output_format[] = "\tTest:\t%ls => %ls (%s)\n"; + String format, output; + Array args; + + // %% + format = "fish %% frog"; + args.clear(); + output = format.sprintf(args); + success = (format.sprintf(args) == String("fish % frog")); + OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL"); + if (!success) state = false; + + // Int + format = "fish %d frog"; + args.clear(); + args.push_back(5); + output = format.sprintf(args); + success = (format.sprintf(args) == String("fish 5 frog")); + OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL"); + if (!success) state = false; + + // Hex (lower) + format = "fish %x frog"; + args.clear(); + args.push_back(45); + output = format.sprintf(args); + success = (format.sprintf(args) == String("fish 2d frog")); + OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL"); + if (!success) state = false; + + // Hex (upper) + format = "fish %X frog"; + args.clear(); + args.push_back(45); + output = format.sprintf(args); + success = (format.sprintf(args) == String("fish 2D frog")); + OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL"); + if (!success) state = false; + + // Octal + format = "fish %o frog"; + args.clear(); + args.push_back(99); + output = format.sprintf(args); + success = (format.sprintf(args) == String("fish 143 frog")); + OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL"); + if (!success) state = false; + + // Real + format = "fish %f frog"; + args.clear(); + args.push_back(99.99); + output = format.sprintf(args); + success = (format.sprintf(args) == String("fish 99.990000 frog")); + OS::get_singleton()->print(output_format, format.c_str(), output.c_str(), success ? "OK" : "FAIL"); + if (!success) state = false; + + // String + format = "fish %s frog"; + args.clear(); + args.push_back("cheese"); + output = format.sprintf(args); + success = (format.sprintf(args) == String("fish cheese frog")); + OS::get_singleton()->print(output_format , format.c_str(), output.c_str(), success ? "OK" : "FAIL"); + if (!success) state = false; + + return state; +} + typedef bool (*TestFunc)(void); TestFunc test_funcs[] = { @@ -540,6 +616,7 @@ TestFunc test_funcs[] = { test_25, test_26, test_27, + test_28, 0 }; diff --git a/core/ustring.cpp b/core/ustring.cpp index 581cc29440..a7359f112f 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -34,6 +34,8 @@ #include "io/md5.h" #include "ucaps.h" #include "color.h" +#include "variant.h" +#include #define MAX_DIGITS 6 #define UPPERCASE(m_c) (((m_c)>='a' && (m_c)<='z')?((m_c)-('a'-'A')):(m_c)) #define LOWERCASE(m_c) (((m_c)>='A' && (m_c)<='Z')?((m_c)+('a'-'A')):(m_c)) @@ -3518,4 +3520,100 @@ String rtoss(double p_val) { return String::num_scientific(p_val); } +// sprintf is implemented in GDScript via: +// "fish %s pie" % "frog" +// "fish %s %d pie" % ["frog", 12] +const int FORMAT_BUFFER_SIZE = 1024; +const int OUTPUT_BUFFER_SIZE = 1024 * 100; +String String::sprintf(const Array& values) const { + + String formatted; + CharType* self = (CharType*)c_str(); + bool in_format = false; + int value_index = 0; + char format_format[FORMAT_BUFFER_SIZE] = "%d"; + + for (; *self; self++) { + const CharType c = *self; + + if (in_format) { // We have % - lets see what else we get. + switch (c) { + case '%': // Manage %% as % + formatted += chr(c); + in_format = false; + break; + + case 'd': // Integer (signed) + case 'o': // Octal + case 'x': // Hexadecimal (lowercase) + case 'X': // Hexadecimal (uppercase) + if (values[value_index].is_num()) { + char buffer[OUTPUT_BUFFER_SIZE]; + int value = values[value_index]; + format_format[1] = c; + format_format[2] = 0; + ::sprintf(buffer, format_format, value); + + formatted += String(buffer); + ++value_index; + in_format = false; + } else { + // TODO: Error? + } + + break; + + case 'f': // Float + if (values[value_index].is_num()) { + char buffer[OUTPUT_BUFFER_SIZE]; + double value = values[value_index]; + ::sprintf(buffer, "%f", value); + + formatted += String(buffer); + ++value_index; + in_format = false; + } else { + // TODO: Error? + } + + break; + + case 's': // String + String value = values[value_index]; + formatted += value; + ++value_index; + in_format = false; + break; + + // case '-': // Left justify + // break; + + // case '+': // Show + if positive. + // break; + + // case '0': case '1': case '2': case '3': case '4': + // case '5': case '6': case '7': case '8': case '9': + // break; + + // case '.': // Float separtor. + // break; + + // case '*': // Dyanmic width, based on value. + // break; + //default: + // TODO: error? + } + } else { // Not in format string. + switch (c) { + case '%': + in_format = true; + break; + default: + formatted += chr(c); + } + } + } + + return formatted; +} diff --git a/core/ustring.h b/core/ustring.h index e1d6761742..ccbbf5e5d2 100644 --- a/core/ustring.h +++ b/core/ustring.h @@ -31,6 +31,7 @@ #include "typedefs.h" #include "vector.h" +#include "array.h" /** @author red @@ -127,6 +128,7 @@ public: String insert(int p_at_pos,String p_string) const; String pad_decimals(int p_digits) const; String pad_zeros(int p_digits) const; + String sprintf(const Array& values) const; static String num(double p_num,int p_decimals=-1); static String num_scientific(double p_num); static String num_real(double p_num); @@ -203,7 +205,7 @@ public: String xml_unescape() const; String c_escape() const; String c_unescape() const; - + String percent_encode() const; String percent_decode() const; diff --git a/core/variant_op.cpp b/core/variant_op.cpp index ec43b1275c..533a9d6952 100644 --- a/core/variant_op.cpp +++ b/core/variant_op.cpp @@ -736,6 +736,20 @@ void Variant::evaluate(const Operator& p_op, const Variant& p_a, const Variant& } #endif _RETURN( p_a._data._int % p_b._data._int ); + + } else if (p_a.type==STRING) { + const String *str=reinterpret_cast(p_a._data._mem); + + if (p_b.type==ARRAY) { + // e.g. "frog %s %d" % ["fish", 12] + const Array *arr=reinterpret_cast(p_b._data._mem); + _RETURN(str->sprintf(*arr)); + } else { + // e.g. "frog %d" % 12 + Array arr; + arr.push_back(p_b); + _RETURN(str->sprintf(arr)); + } } r_valid=false; -- cgit v1.2.3 From bb6daaa02ede319dae34733221bdae8b4f999a99 Mon Sep 17 00:00:00 2001 From: marynate Date: Sun, 11 Jan 2015 11:04:57 +0800 Subject: Fix compile compile error on windows platform --- platform/windows/os_windows.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index a3a26ddb25..45d13da828 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -134,7 +134,7 @@ int OS_Windows::get_video_driver_count() const { } const char * OS_Windows::get_video_driver_name(int p_driver) const { - return p_driver=="GLES2"; + return "GLES2"; } OS::VideoMode OS_Windows::get_default_video_mode() const { -- cgit v1.2.3 From 2fd9292b12b6a5d8455ab3d7305ee55ebae64c9b Mon Sep 17 00:00:00 2001 From: Nathan Warden Date: Fri, 16 Jan 2015 23:17:12 -0500 Subject: Changed the "Start the scene (F5)." tooltip to say "Play the project (F5)." --- tools/editor/editor_node.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index f859d19504..692eeb77b8 100644 --- a/tools/editor/editor_node.cpp +++ b/tools/editor/editor_node.cpp @@ -3552,7 +3552,7 @@ EditorNode::EditorNode() { play_button->set_icon(gui_base->get_icon("MainPlay","EditorIcons")); play_button->set_focus_mode(Control::FOCUS_NONE); play_button->connect("pressed", this,"_menu_option",make_binds(RUN_PLAY)); - play_button->set_tooltip("Start the scene (F5)."); + play_button->set_tooltip("Play the project (F5)."); -- cgit v1.2.3 From 9f61a4881e018508e1914ddbb4e7740c11f0a272 Mon Sep 17 00:00:00 2001 From: marynate Date: Sun, 18 Jan 2015 02:06:29 +0800 Subject: Fix mingw windows build error --- platform/windows/os_windows.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index ce79133664..4fa061886d 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -57,7 +57,11 @@ static const WORD MAX_CONSOLE_LINES = 1500; extern "C" { +#ifdef _MSC_VER _declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; +#else + __attribute__((visibility("default"))) DWORD NvOptimusEnablement = 0x00000001; +#endif } //#define STDOUT_FILE -- cgit v1.2.3 From 5a4ef1c2cc400ff7fe67714435cadb070dc9cdd5 Mon Sep 17 00:00:00 2001 From: Dana Olson Date: Sat, 17 Jan 2015 14:05:26 -0500 Subject: fixes --- tools/editor/plugins/script_editor_plugin.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/editor/plugins/script_editor_plugin.cpp b/tools/editor/plugins/script_editor_plugin.cpp index 20aeb05a50..3070079fa1 100644 --- a/tools/editor/plugins/script_editor_plugin.cpp +++ b/tools/editor/plugins/script_editor_plugin.cpp @@ -630,7 +630,7 @@ bool ScriptEditor::_test_script_times_on_disk() { if (!all_ok) - if (bool(EDITOR_DEF("text_editor/autoreload_changed_scripts",false))) + if (bool(EDITOR_DEF("text_editor/auto_reload_changed_scripts",false))) script_editor->_reload_scripts(); else disk_changed->call_deferred("popup_centered_ratio",0.5); @@ -1805,6 +1805,7 @@ ScriptEditorPlugin::ScriptEditorPlugin(EditorNode *p_node) { script_editor->hide(); + EDITOR_DEF("text_editor/auto_reload_changed_scripts",false); EDITOR_DEF("external_editor/use_external_editor",false); EDITOR_DEF("external_editor/exec_path",""); EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING,"external_editor/exec_path",PROPERTY_HINT_GLOBAL_FILE)); -- cgit v1.2.3 From eac0de398fe48422f7e88509ff04a66667a95284 Mon Sep 17 00:00:00 2001 From: Dana Olson Date: Sat, 17 Jan 2015 14:19:57 -0500 Subject: ignore and remove .fscache files. closes #1249 --- .gitignore | 1 + demos/2d/hexamap/.fscache | 33 ------------------------------ demos/2d/polygon_path_finder_demo/.fscache | 4 ---- 3 files changed, 1 insertion(+), 37 deletions(-) delete mode 100644 demos/2d/hexamap/.fscache delete mode 100644 demos/2d/polygon_path_finder_demo/.fscache diff --git a/.gitignore b/.gitignore index 4aee83c13f..f3a1b9693c 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,7 @@ tools/editor/register_exporters.cpp tools/editor/doc_data_compressed.h tools/editor/editor_icons.cpp -fpic +.fscache # Android specific platform/android/java/local.properties diff --git a/demos/2d/hexamap/.fscache b/demos/2d/hexamap/.fscache deleted file mode 100644 index 60aa69b645..0000000000 --- a/demos/2d/hexamap/.fscache +++ /dev/null @@ -1,33 +0,0 @@ -::res://::1412302385 -WWT-01.png::ImageTexture::1412126473:: -WWT-02.png::ImageTexture::1412126474:: -WWT-03.png::ImageTexture::1412126474:: -WWT-04.png::ImageTexture::1412126474:: -WWT-05.png::ImageTexture::1412126474:: -WWT-06.png::ImageTexture::1412126474:: -WWT-07.png::ImageTexture::1412126474:: -WWT-08.png::ImageTexture::1412126474:: -WWT-09.png::ImageTexture::1412126474:: -WWT-10.png::ImageTexture::1412126474:: -WWT-11.png::ImageTexture::1412126475:: -WWT-12.png::ImageTexture::1412126475:: -WWT-13.png::ImageTexture::1412126475:: -WWT-14.png::ImageTexture::1412126475:: -WWT-15.png::ImageTexture::1412126475:: -WWT-16.png::ImageTexture::1412126475:: -WWT-17.png::ImageTexture::1412126475:: -WWT-18.png::ImageTexture::1412126475:: -WWT-19.png::ImageTexture::1412126476:: -WWT-20.png::ImageTexture::1412126476:: -WWT-21.png::ImageTexture::1412126476:: -WWT-22.png::ImageTexture::1412126476:: -WWT-23.png::ImageTexture::1412126476:: -WWT-24.png::ImageTexture::1412126476:: -WWT-25.png::ImageTexture::1412126476:: -WWT-26.png::ImageTexture::1412126476:: -map.scn::PackedScene::1412127344:: -tiles.scn::PackedScene::1412126994:: -tileset.res::TileSet::1412127001:: -troll.gd::GDScript::1412302377:: -troll.png::ImageTexture::1412302385:: -troll.scn::PackedScene::1412302380:: diff --git a/demos/2d/polygon_path_finder_demo/.fscache b/demos/2d/polygon_path_finder_demo/.fscache deleted file mode 100644 index f699ca5849..0000000000 --- a/demos/2d/polygon_path_finder_demo/.fscache +++ /dev/null @@ -1,4 +0,0 @@ -::res://::1421147952 -icon.png::ImageTexture::1420046079:: -new_scene_poly_with_holes.scn::PackedScene::1421147952:: -polygonpathfinder.gd::GDScript::1421146502:: -- cgit v1.2.3 From fa62125e05b30f6a7df482af924aa8e552760f07 Mon Sep 17 00:00:00 2001 From: Manuel Lagang Date: Sat, 17 Jan 2015 22:40:01 -0800 Subject: Modifiers are unset on events for the modifier key itself This patch removes modifiers when processing key events for the particular modifier key. For example, previously a Shift keypress would register as a Shift + Shift modifier event. This would cause issues when a modifier key as the action key in the input map, because unpresses of the modifier key don't match as matching inputs for that action. E.g. if Shift is used as an action, the stored action event is Shift + Shift modifier (as indicated in the editor as "Shift + Shift". The unpress event does not have the Shift modifier set, so the event of unpressing Shift + no modifier doesn't match the action which has the modifier set. This patch removes the shift modifier on just pressing the Shift key down, so the action event is registered as just Shift with no modifier (as indicated in the editor as "Shift"), which matches the unpress event. --- platform/windows/os_windows.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index ce79133664..bb911a99a4 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -589,10 +589,11 @@ LRESULT OS_Windows::WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam) { ERR_BREAK(key_event_pos >= KEY_EVENT_BUFFER_SIZE); + // Make sure we don't include modifiers for the modifier key itself. KeyEvent ke; - ke.mod_state.shift=shift_mem; - ke.mod_state.alt=alt_mem; - ke.mod_state.control=control_mem; + ke.mod_state.shift= (wParam != VK_SHIFT) ? shift_mem : false; + ke.mod_state.alt= (! (wParam == VK_MENU && (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN))) ? alt_mem : false; + ke.mod_state.control= (wParam != VK_CONTROL) ? control_mem : false; ke.mod_state.meta=meta_mem; ke.uMsg=uMsg; -- cgit v1.2.3 From a4f40ec3be67e6bd0498e18bc9c9f66274d29a48 Mon Sep 17 00:00:00 2001 From: Manuel Lagang Date: Sat, 17 Jan 2015 23:06:20 -0800 Subject: Fix whitespace on previous commit Choose tabs or spaces, not both! --- platform/windows/os_windows.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index bb911a99a4..57b6a8f816 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -589,7 +589,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam) { ERR_BREAK(key_event_pos >= KEY_EVENT_BUFFER_SIZE); - // Make sure we don't include modifiers for the modifier key itself. + // Make sure we don't include modifiers for the modifier key itself. KeyEvent ke; ke.mod_state.shift= (wParam != VK_SHIFT) ? shift_mem : false; ke.mod_state.alt= (! (wParam == VK_MENU && (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN))) ? alt_mem : false; -- cgit v1.2.3 From 6f3c09047ecea651a219c36dd9fa9f96b5f06be4 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Sun, 18 Jan 2015 09:51:11 -0300 Subject: -intentional breakage of shader graph to fix issues, existing graphs will be broken, sorry :( --- scene/resources/shader_graph.cpp | 20 +++++++++++++++++++- scene/resources/shader_graph.h | 5 ++++- servers/physics_2d/shape_2d_sw.cpp | 1 + servers/physics_2d/shape_2d_sw.h | 1 - tools/editor/plugins/script_editor_plugin.cpp | 2 +- 5 files changed, 25 insertions(+), 4 deletions(-) diff --git a/scene/resources/shader_graph.cpp b/scene/resources/shader_graph.cpp index 9703799a48..fcadf60bfe 100644 --- a/scene/resources/shader_graph.cpp +++ b/scene/resources/shader_graph.cpp @@ -263,12 +263,15 @@ void ShaderGraph::_bind_methods() { BIND_CONSTANT( NODE_XFORM_TO_VEC ); // 3 vec input ); 1 xform output BIND_CONSTANT( NODE_SCALAR_INTERP ); // scalar interpolation (with optional curve) BIND_CONSTANT( NODE_VEC_INTERP ); // vec3 interpolation (with optional curve) + BIND_CONSTANT( NODE_COLOR_RAMP ); + BIND_CONSTANT( NODE_CURVE_MAP ); BIND_CONSTANT( NODE_SCALAR_INPUT ); // scalar uniform (assignable in material) BIND_CONSTANT( NODE_VEC_INPUT ); // vec3 uniform (assignable in material) BIND_CONSTANT( NODE_RGB_INPUT ); // color uniform (assignable in material) BIND_CONSTANT( NODE_XFORM_INPUT ); // mat4 uniform (assignable in material) BIND_CONSTANT( NODE_TEXTURE_INPUT ); // texture input (assignable in material) BIND_CONSTANT( NODE_CUBEMAP_INPUT ); // cubemap input (assignable in material) + BIND_CONSTANT( NODE_DEFAULT_TEXTURE ); BIND_CONSTANT( NODE_OUTPUT ); // output (shader type dependent) BIND_CONSTANT( NODE_COMMENT ); // comment BIND_CONSTANT( NODE_TYPE_MAX ); @@ -519,12 +522,15 @@ void ShaderGraph::node_add(ShaderType p_type, NodeType p_node_type,int p_id) { case NODE_XFORM_TO_VEC: {} break; // 3 scalar input: {} break; 1 vec3 output case NODE_SCALAR_INTERP: {} break; // scalar interpolation (with optional curve) case NODE_VEC_INTERP: {} break; // vec3 interpolation (with optional curve) + case NODE_COLOR_RAMP: { node.param1=Array();} break; // vec3 interpolation (with optional curve) + case NODE_CURVE_MAP: { node.param1=Array();} break; // vec3 interpolation (with optional curve) case NODE_SCALAR_INPUT: {node.param1=_find_unique_name("Scalar"); node.param2=0;} break; // scalar uniform (assignable in material) case NODE_VEC_INPUT: {node.param1=_find_unique_name("Vec3");node.param2=Vector3();} break; // vec3 uniform (assignable in material) case NODE_RGB_INPUT: {node.param1=_find_unique_name("Color");node.param2=Color();} break; // color uniform (assignable in material) case NODE_XFORM_INPUT: {node.param1=_find_unique_name("XForm"); node.param2=Transform();} break; // mat4 uniform (assignable in material) case NODE_TEXTURE_INPUT: {node.param1=_find_unique_name("Tex"); } break; // texture input (assignable in material) - case NODE_CUBEMAP_INPUT: {node.param1=_find_unique_name("Cube"); } break; // cubemap input (assignable in material) + case NODE_CUBEMAP_INPUT: {node.param1=_find_unique_name("Cube"); } break; // cubemap input (assignable in material) + case NODE_DEFAULT_TEXTURE: {}; break; case NODE_OUTPUT: {} break; // output (shader type dependent) case NODE_COMMENT: {} break; // comment case NODE_TYPE_MAX: {}; @@ -1299,6 +1305,8 @@ const ShaderGraph::NodeSlotInfo ShaderGraph::node_slot_info[]= { {NODE_SCALAR_TO_VEC,{SLOT_TYPE_SCALAR,SLOT_TYPE_SCALAR,SLOT_TYPE_SCALAR},{SLOT_TYPE_VEC,SLOT_MAX}}, // 3 scalar input,{SLOT_MAX},{SLOT_MAX}}, 1 vec3 output {NODE_SCALAR_INTERP,{SLOT_TYPE_SCALAR,SLOT_TYPE_SCALAR,SLOT_TYPE_SCALAR},{SLOT_TYPE_SCALAR,SLOT_MAX}}, // scalar interpolation (with optional curve) {NODE_VEC_INTERP,{SLOT_TYPE_VEC,SLOT_TYPE_VEC,SLOT_TYPE_SCALAR},{SLOT_TYPE_VEC,SLOT_MAX}}, // vec3 interpolation (with optional curve) + {NODE_COLOR_RAMP,{SLOT_TYPE_SCALAR,SLOT_MAX},{SLOT_TYPE_VEC,SLOT_MAX}}, // vec3 interpolation (with optional curve) + {NODE_CURVE_MAP,{SLOT_TYPE_SCALAR,SLOT_MAX},{SLOT_TYPE_SCALAR,SLOT_MAX}}, // vec3 interpolation (with optional curve) {NODE_SCALAR_INPUT,{SLOT_MAX},{SLOT_TYPE_SCALAR,SLOT_MAX}}, // scalar uniform (assignable in material) {NODE_VEC_INPUT,{SLOT_MAX},{SLOT_TYPE_VEC,SLOT_MAX}}, // vec3 uniform (assignable in material) {NODE_RGB_INPUT,{SLOT_MAX},{SLOT_TYPE_VEC,SLOT_MAX}}, // color uniform (assignable in material) @@ -1987,6 +1995,12 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vectorid,0)+"=mix("+p_inputs[0]+","+p_inputs[1]+","+p_inputs[2]+");\n"; + }break; + case NODE_COLOR_RAMP: { + + }break; + case NODE_CURVE_MAP: { + }break; case NODE_SCALAR_INPUT: { String name = p_node->param1; @@ -2043,6 +2057,10 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vectorid,0)+"="+rname+".rgb;\n"; code += OUTNAME(p_node->id,1)+"="+rname+".a;\n"; }break; + case NODE_DEFAULT_TEXTURE: { + + + } break; case NODE_OUTPUT: { diff --git a/scene/resources/shader_graph.h b/scene/resources/shader_graph.h index 55d09b4c38..88818f5615 100644 --- a/scene/resources/shader_graph.h +++ b/scene/resources/shader_graph.h @@ -66,12 +66,15 @@ public: NODE_VEC_TO_XFORM, // 3 vec input, 1 xform output NODE_SCALAR_INTERP, // scalar interpolation (with optional curve) NODE_VEC_INTERP, // vec3 interpolation (with optional curve) - NODE_SCALAR_INPUT, // scalar uniform (assignable in material) + NODE_COLOR_RAMP, //take scalar, output vec3 + NODE_CURVE_MAP, //take scalar, otput scalar + NODE_SCALAR_INPUT, // scalar uniform (assignable in material) NODE_VEC_INPUT, // vec3 uniform (assignable in material) NODE_RGB_INPUT, // color uniform (assignable in material) NODE_XFORM_INPUT, // mat4 uniform (assignable in material) NODE_TEXTURE_INPUT, // texture input (assignable in material) NODE_CUBEMAP_INPUT, // cubemap input (assignable in material) + NODE_DEFAULT_TEXTURE, NODE_OUTPUT, // output (shader type dependent) NODE_COMMENT, // comment NODE_TYPE_MAX diff --git a/servers/physics_2d/shape_2d_sw.cpp b/servers/physics_2d/shape_2d_sw.cpp index 336eec73b5..ed63870a12 100644 --- a/servers/physics_2d/shape_2d_sw.cpp +++ b/servers/physics_2d/shape_2d_sw.cpp @@ -136,6 +136,7 @@ real_t LineShape2DSW::get_moment_of_inertia(float p_mass, const Vector2 &p_scale return 0; } + void LineShape2DSW::set_data(const Variant& p_data) { ERR_FAIL_COND(p_data.get_type()!=Variant::ARRAY); diff --git a/servers/physics_2d/shape_2d_sw.h b/servers/physics_2d/shape_2d_sw.h index 51ece9fc7e..931491efd5 100644 --- a/servers/physics_2d/shape_2d_sw.h +++ b/servers/physics_2d/shape_2d_sw.h @@ -85,7 +85,6 @@ public: virtual bool intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const=0; virtual real_t get_moment_of_inertia(float p_mass,const Vector2& p_scale) const=0; - virtual void set_data(const Variant& p_data)=0; virtual Variant get_data() const=0; diff --git a/tools/editor/plugins/script_editor_plugin.cpp b/tools/editor/plugins/script_editor_plugin.cpp index d90597ddfb..4b7d1cf0e0 100644 --- a/tools/editor/plugins/script_editor_plugin.cpp +++ b/tools/editor/plugins/script_editor_plugin.cpp @@ -1607,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 -- cgit v1.2.3 From a0511ed59a0e03232bf3abb49b3c916591453aef Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Mon, 19 Jan 2015 02:39:58 -0300 Subject: Color Ramp and Curve Map added to visual shader editing. Added Color Ramp and Curve Map to shader nodes. Fixed an issue that crashed Godot Editor right when opened. --- .gitignore | 1 + drivers/gles2/shaders/canvas.glsl | 9 +- scene/resources/shader_graph.cpp | 323 +++++++- scene/resources/shader_graph.h | 8 + tools/editor/icons/icon_graph_color_ramp.png | Bin 0 -> 290 bytes tools/editor/icons/icon_graph_curve_map.png | Bin 0 -> 619 bytes tools/editor/icons/icon_graph_default_texture.png | Bin 0 -> 326 bytes .../editor/plugins/shader_graph_editor_plugin.cpp | 835 ++++++++++++++++++++- tools/editor/plugins/shader_graph_editor_plugin.h | 74 +- 9 files changed, 1240 insertions(+), 10 deletions(-) create mode 100644 tools/editor/icons/icon_graph_color_ramp.png create mode 100644 tools/editor/icons/icon_graph_curve_map.png create mode 100644 tools/editor/icons/icon_graph_default_texture.png diff --git a/.gitignore b/.gitignore index 4aee83c13f..1e53f3712b 100644 --- a/.gitignore +++ b/.gitignore @@ -258,3 +258,4 @@ Desktop.ini # Recycle Bin used on file shares $RECYCLE.BIN/ logo.h +*.autosave diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl index 464cb9e188..5a26f7321e 100644 --- a/drivers/gles2/shaders/canvas.glsl +++ b/drivers/gles2/shaders/canvas.glsl @@ -46,14 +46,15 @@ void main() { color_interp = color_attrib; uv_interp = uv_attrib; - highp vec4 outvec = vec4(vertex, 1.0); + highp vec4 outvec = vec4(vertex, 1.0); { - vec2 src_vtx=outvec.xy; + vec2 src_vtx=outvec.xy; VERTEX_SHADER_CODE } - outvec = extra_matrix * outvec; - outvec = modelview_matrix * outvec; + outvec = extra_matrix * outvec; + outvec = modelview_matrix * outvec; + #ifdef USE_PIXEL_SNAP outvec.xy=floor(outvec.xy+0.5); diff --git a/scene/resources/shader_graph.cpp b/scene/resources/shader_graph.cpp index fcadf60bfe..9fc2f99a0a 100644 --- a/scene/resources/shader_graph.cpp +++ b/scene/resources/shader_graph.cpp @@ -221,6 +221,13 @@ void ShaderGraph::_bind_methods() { ObjectTypeDB::bind_method(_MD("comment_node_set_text","shader_type","id","text"),&ShaderGraph::comment_node_set_text); ObjectTypeDB::bind_method(_MD("comment_node_get_text","shader_type","id"),&ShaderGraph::comment_node_get_text); + ObjectTypeDB::bind_method(_MD("color_ramp_node_set_ramp","shader_type","id","colors","offsets"),&ShaderGraph::color_ramp_node_set_ramp); + ObjectTypeDB::bind_method(_MD("color_ramp_node_get_colors","shader_type","id"),&ShaderGraph::color_ramp_node_get_colors); + ObjectTypeDB::bind_method(_MD("color_ramp_node_get_offsets","shader_type","id"),&ShaderGraph::color_ramp_node_get_offsets); + + ObjectTypeDB::bind_method(_MD("curve_map_node_set_points","shader_type","id","points"),&ShaderGraph::curve_map_node_set_points); + ObjectTypeDB::bind_method(_MD("curve_map_node_get_points","shader_type","id"),&ShaderGraph::curve_map_node_get_points); + ObjectTypeDB::bind_method(_MD("connect_node:Error","shader_type","src_id","src_slot","dst_id","dst_slot"),&ShaderGraph::connect_node); ObjectTypeDB::bind_method(_MD("is_node_connected","shader_type","src_id","src_slot","dst_id","dst_slot"),&ShaderGraph::is_node_connected); ObjectTypeDB::bind_method(_MD("disconnect_node","shader_type","src_id","src_slot","dst_id","dst_slot"),&ShaderGraph::disconnect_node); @@ -522,8 +529,8 @@ void ShaderGraph::node_add(ShaderType p_type, NodeType p_node_type,int p_id) { case NODE_XFORM_TO_VEC: {} break; // 3 scalar input: {} break; 1 vec3 output case NODE_SCALAR_INTERP: {} break; // scalar interpolation (with optional curve) case NODE_VEC_INTERP: {} break; // vec3 interpolation (with optional curve) - case NODE_COLOR_RAMP: { node.param1=Array();} break; // vec3 interpolation (with optional curve) - case NODE_CURVE_MAP: { node.param1=Array();} break; // vec3 interpolation (with optional curve) + case NODE_COLOR_RAMP: { node.param1=DVector(); node.param2=DVector();} break; // vec3 interpolation (with optional curve) + case NODE_CURVE_MAP: { node.param1=DVector();} break; // vec3 interpolation (with optional curve) case NODE_SCALAR_INPUT: {node.param1=_find_unique_name("Scalar"); node.param2=0;} break; // scalar uniform (assignable in material) case NODE_VEC_INPUT: {node.param1=_find_unique_name("Vec3");node.param2=Vector3();} break; // vec3 uniform (assignable in material) case NODE_RGB_INPUT: {node.param1=_find_unique_name("Color");node.param2=Color();} break; // color uniform (assignable in material) @@ -970,6 +977,59 @@ ShaderGraph::VecFunc ShaderGraph::vec_func_node_get_function(ShaderType p_type, return VecFunc(func); } +void ShaderGraph::color_ramp_node_set_ramp(ShaderType p_type,int p_id,const DVector& p_colors, const DVector& p_offsets){ + + ERR_FAIL_INDEX(p_type,3); + ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); + ERR_FAIL_COND(p_colors.size()!=p_offsets.size()); + Node& n = shader[p_type].node_map[p_id]; + n.param1=p_colors; + n.param2=p_offsets; + _request_update(); + +} + +DVector ShaderGraph::color_ramp_node_get_colors(ShaderType p_type,int p_id) const{ + + ERR_FAIL_INDEX_V(p_type,3,DVector()); + ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),DVector()); + const Node& n = shader[p_type].node_map[p_id]; + return n.param1; + + +} + +DVector ShaderGraph::color_ramp_node_get_offsets(ShaderType p_type,int p_id) const{ + + ERR_FAIL_INDEX_V(p_type,3,DVector()); + ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),DVector()); + const Node& n = shader[p_type].node_map[p_id]; + return n.param2; + +} + + +void ShaderGraph::curve_map_node_set_points(ShaderType p_type,int p_id,const DVector& p_points) { + + ERR_FAIL_INDEX(p_type,3); + ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); + Node& n = shader[p_type].node_map[p_id]; + n.param1=p_points; + _request_update(); + +} + +DVector ShaderGraph::curve_map_node_get_points(ShaderType p_type,int p_id) const{ + + ERR_FAIL_INDEX_V(p_type,3,DVector()); + ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),DVector()); + const Node& n = shader[p_type].node_map[p_id]; + return n.param1; + +} + + + void ShaderGraph::input_node_set_name(ShaderType p_type,int p_id,const String& p_name){ ERR_FAIL_INDEX(p_type,3); @@ -1305,7 +1365,7 @@ const ShaderGraph::NodeSlotInfo ShaderGraph::node_slot_info[]= { {NODE_SCALAR_TO_VEC,{SLOT_TYPE_SCALAR,SLOT_TYPE_SCALAR,SLOT_TYPE_SCALAR},{SLOT_TYPE_VEC,SLOT_MAX}}, // 3 scalar input,{SLOT_MAX},{SLOT_MAX}}, 1 vec3 output {NODE_SCALAR_INTERP,{SLOT_TYPE_SCALAR,SLOT_TYPE_SCALAR,SLOT_TYPE_SCALAR},{SLOT_TYPE_SCALAR,SLOT_MAX}}, // scalar interpolation (with optional curve) {NODE_VEC_INTERP,{SLOT_TYPE_VEC,SLOT_TYPE_VEC,SLOT_TYPE_SCALAR},{SLOT_TYPE_VEC,SLOT_MAX}}, // vec3 interpolation (with optional curve) - {NODE_COLOR_RAMP,{SLOT_TYPE_SCALAR,SLOT_MAX},{SLOT_TYPE_VEC,SLOT_MAX}}, // vec3 interpolation (with optional curve) + {NODE_COLOR_RAMP,{SLOT_TYPE_SCALAR,SLOT_MAX},{SLOT_TYPE_VEC,SLOT_TYPE_SCALAR,SLOT_MAX}}, // vec3 interpolation (with optional curve) {NODE_CURVE_MAP,{SLOT_TYPE_SCALAR,SLOT_MAX},{SLOT_TYPE_SCALAR,SLOT_MAX}}, // vec3 interpolation (with optional curve) {NODE_SCALAR_INPUT,{SLOT_MAX},{SLOT_TYPE_SCALAR,SLOT_MAX}}, // scalar uniform (assignable in material) {NODE_VEC_INPUT,{SLOT_MAX},{SLOT_TYPE_VEC,SLOT_MAX}}, // vec3 uniform (assignable in material) @@ -1696,6 +1756,134 @@ void ShaderGraph::_update_shader() { emit_signal(SceneStringNames::get_singleton()->updated); } +void ShaderGraph::_plot_curve(const Vector2& p_a,const Vector2& p_b,const Vector2& p_c,const Vector2& p_d,uint8_t* p_heights,bool *p_useds) { + + 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=255; + int ymax=255; + + /* 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); + + p_heights[lastx] = lasty; + p_useds[lastx] = true; + + /* 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)) + { + p_useds[newx]=true; + p_heights[newx]=newy; + } + + lastx = newx; + lasty = newy; + } +} + + void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vector& p_inputs,String& code) { @@ -1998,8 +2186,125 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vector cramp; + cramp.resize(color_ramp_len*4); + { + + DVector colors=p_node->param1; + DVector offsets=p_node->param2; + int cc =colors.size(); + DVector::Write crw = cramp.write(); + DVector::Read cr = colors.read(); + DVector::Read ofr = offsets.read(); + + int at=0; + Color color_at(0,0,0,1); + for(int i=0;i<=cc;i++) { + + int pos; + Color to; + if (i==cc) { + if (at==color_ramp_len) + break; + pos=color_ramp_len; + to=Color(1,1,1,1); + } else { + to=cr[i]; + pos= MIN(ofr[i]*color_ramp_len,color_ramp_len); + } + for(int j=at;j it = memnew( ImageTexture ); + it->create_from_image(gradient,Texture::FLAG_FILTER|Texture::FLAG_MIPMAPS); + + String crampname= "cramp_"+itos(p_node->id); + set_default_texture_param(crampname,it); + + code +="uniform texture "+crampname+";\n"; + code +="vec4 "+crampname+"_r=tex("+crampname+",vec2("+p_inputs[0]+",0));\n"; + code += OUTNAME(p_node->id,0)+"="+crampname+"_r.rgb;\n"; + code += OUTNAME(p_node->id,1)+"="+crampname+"_r.a;\n"; + }break; case NODE_CURVE_MAP: { + static const int curve_map_len=256; + bool mapped[256]; + zeromem(mapped,sizeof(mapped)); + DVector cmap; + cmap.resize(curve_map_len); + { + + DVector points=p_node->param1; + int pc =points.size(); + DVector::Write cmw = cmap.write(); + DVector::Read pr = points.read(); + + Vector2 prev=Vector2(0,0); + Vector2 prev2=Vector2(0,0); + + for(int i=-1;i=pc) { + next=Vector2(1,1); + } else { + next=Vector2(pr[i+1].x,pr[i+1].y); + } + + if (i+2>=pc) { + next2=Vector2(1,1); + } else { + next2=Vector2(pr[i+2].x,pr[i+2].y); + } + + /*if (i==-1 && prev.offset==next.offset) { + prev=next; + continue; + }*/ + + _plot_curve(prev2,prev,next,next2,cmw.ptr(),mapped); + + prev2=prev; + prev=next; + } + + uint8_t pp=0; + for(int i=0;i it = memnew( ImageTexture ); + it->create_from_image(gradient,Texture::FLAG_FILTER|Texture::FLAG_MIPMAPS); + + String cmapname= "cmap_"+itos(p_node->id); + set_default_texture_param(cmapname,it); + + code +="uniform texture "+cmapname+";\n"; + code += OUTNAME(p_node->id,0)+"=tex("+cmapname+",vec2("+p_inputs[0]+",0)).r;\n"; }break; case NODE_SCALAR_INPUT: { @@ -2059,7 +2364,19 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vectorid); + code +="vec4 "+rname+"=tex(TEXTURE,"+p_inputs[0]+".xy);\n"; + code += OUTNAME(p_node->id,0)+"="+rname+".rgb;\n"; + code += OUTNAME(p_node->id,1)+"="+rname+".a;\n"; + + } else { + + code += OUTNAME(p_node->id,0)+"=vec3(0,0,0);\n"; + code += OUTNAME(p_node->id,1)+"=1.0;\n"; + + } } break; case NODE_OUTPUT: { diff --git a/scene/resources/shader_graph.h b/scene/resources/shader_graph.h index 88818f5615..ff2ca68335 100644 --- a/scene/resources/shader_graph.h +++ b/scene/resources/shader_graph.h @@ -175,6 +175,7 @@ private: void _update_shader(); void _request_update(); + void _plot_curve(const Vector2& p_a,const Vector2& p_b,const Vector2& p_c,const Vector2& p_d,uint8_t* p_heights,bool *p_useds); void _add_node_code(ShaderType p_type,Node *p_node,const Vector& p_inputs,String& code); Array _get_node_list(ShaderType p_type) const; @@ -316,6 +317,13 @@ public: void vec_func_node_set_function(ShaderType p_which,int p_id,VecFunc p_func); VecFunc vec_func_node_get_function(ShaderType p_which,int p_id) const; + void color_ramp_node_set_ramp(ShaderType p_which,int p_id,const DVector& p_colors, const DVector& p_offsets); + DVector color_ramp_node_get_colors(ShaderType p_which,int p_id) const; + DVector color_ramp_node_get_offsets(ShaderType p_which,int p_id) const; + + void curve_map_node_set_points(ShaderType p_which, int p_id, const DVector& p_points); + DVector curve_map_node_get_points(ShaderType p_which,int p_id) const; + void input_node_set_name(ShaderType p_which,int p_id,const String& p_name); String input_node_get_name(ShaderType p_which,int p_id); diff --git a/tools/editor/icons/icon_graph_color_ramp.png b/tools/editor/icons/icon_graph_color_ramp.png new file mode 100644 index 0000000000..9031b5ec53 Binary files /dev/null and b/tools/editor/icons/icon_graph_color_ramp.png differ diff --git a/tools/editor/icons/icon_graph_curve_map.png b/tools/editor/icons/icon_graph_curve_map.png new file mode 100644 index 0000000000..de5c32f09e Binary files /dev/null and b/tools/editor/icons/icon_graph_curve_map.png differ diff --git a/tools/editor/icons/icon_graph_default_texture.png b/tools/editor/icons/icon_graph_default_texture.png new file mode 100644 index 0000000000..da77ec9364 Binary files /dev/null and b/tools/editor/icons/icon_graph_default_texture.png differ diff --git a/tools/editor/plugins/shader_graph_editor_plugin.cpp b/tools/editor/plugins/shader_graph_editor_plugin.cpp index 0a206c4a45..39508464c1 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" + + +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;iconnect("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; + Vector 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()); + prev=next; + } + + for(int i=0;i& p_offsets,const Vector& p_colors) { + + ERR_FAIL_COND(p_offsets.size()!=p_colors.size()); + points.clear(); + for(int i=0;i GraphColorRampEdit::get_offsets() const{ + Vector ret; + for(int i=0;i GraphColorRampEdit::get_colors() const{ + + Vector ret; + for(int i=0;iadd_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;icurve[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()) { + 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& p_points) { + + + points.clear(); + for(int i=0;i GraphCurveMapEdit::get_points() const { + Vector ret; + for(int i=0;icast_to(); + + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + + + Vector offsets=cr->get_offsets(); + Vector colors=cr->get_colors(); + + DVector new_offsets; + DVector new_colors; + { + new_offsets.resize(offsets.size()); + new_colors.resize(colors.size()); + DVector::Write ow=new_offsets.write(); + DVector::Write cw=new_colors.write(); + for(int i=0;i old_offsets=graph->color_ramp_node_get_offsets(type,p_id); + DVector 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(); + + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + + + Vector points=cr->get_points(); + + DVector new_points; + { + new_points.resize(points.size()); + DVector::Write ow=new_points.write(); + for(int i=0;i 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) { @@ -1026,6 +1740,96 @@ void ShaderGraphView::_create_node(int p_id) { 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 offsets = graph->color_ramp_node_get_offsets(type,p_id); + DVector colors = graph->color_ramp_node_get_colors(type,p_id); + + int oc = offsets.size(); + + if (oc) { + DVector::Read rofs = offsets.read(); + DVector::Read rcol = colors.read(); + + Vector ofsv; + Vector colorv; + for(int i=0;iset_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 points = graph->curve_map_node_get_points(type,p_id); + + int oc = points.size(); + + if (oc) { + DVector::Read rofs = points.read(); + + + Vector ofsv; + for(int i=0;iset_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"); @@ -1173,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"); @@ -1360,6 +2186,8 @@ 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); } @@ -1455,13 +2283,16 @@ const char* ShaderGraphEditor::node_names[ShaderGraph::NODE_TYPE_MAX]={ "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) - "GraphScalarUniform:Scalar Uniform", // scalar uniform (assignable in material) + "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) - "Output", // output (shader type dependent) + "GraphDefaultTexture:CanvasItem Texture:", // cubemap input (assignable in material) + "Output", // output (shader type dependent) "GraphComment:Comment", // comment diff --git a/tools/editor/plugins/shader_graph_editor_plugin.h b/tools/editor/plugins/shader_graph_editor_plugin.h index bd983c59be..c6fb2f82b1 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 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& p_offsets,const Vector& p_colors); + Vector get_offsets() const; + Vector 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 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& p_points); + Vector get_points() const; + virtual Size2 get_minimum_size() const; + GraphCurveMapEdit(); +}; + class ShaderGraphView : public Node { OBJ_TYPE(ShaderGraphView,Node); @@ -95,7 +166,8 @@ 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 node_map; protected: -- cgit v1.2.3 From a8b318871c016a9ece8964daf02f4e85d31824ad Mon Sep 17 00:00:00 2001 From: Carl Olsson Date: Mon, 19 Jan 2015 23:07:25 +1000 Subject: Prep for tile transpose transform. --- core/object.h | 14 ++--- core/variant.h | 2 +- demos/2d/polygon_path_finder_demo/.fscache | 8 +-- scene/2d/tile_map.cpp | 33 +++++++++-- scene/2d/tile_map.h | 4 +- tools/editor/icons/icon_rotate_0.png | Bin 0 -> 207 bytes tools/editor/icons/icon_rotate_180.png | Bin 0 -> 303 bytes tools/editor/icons/icon_rotate_270.png | Bin 0 -> 343 bytes tools/editor/icons/icon_rotate_90.png | Bin 0 -> 256 bytes tools/editor/icons/icon_transpose.png | Bin 0 -> 258 bytes tools/editor/plugins/tile_map_editor_plugin.cpp | 72 +++++++++++++++++++----- tools/editor/plugins/tile_map_editor_plugin.h | 11 +++- 12 files changed, 109 insertions(+), 35 deletions(-) create mode 100644 tools/editor/icons/icon_rotate_0.png create mode 100644 tools/editor/icons/icon_rotate_180.png create mode 100644 tools/editor/icons/icon_rotate_270.png create mode 100644 tools/editor/icons/icon_rotate_90.png create mode 100644 tools/editor/icons/icon_transpose.png diff --git a/core/object.h b/core/object.h index 97ca50cb1a..3c493de157 100644 --- a/core/object.h +++ b/core/object.h @@ -35,13 +35,13 @@ #include "map.h" #include "vmap.h" -#define VARIANT_ARG_LIST const Variant& p_arg1=Variant(),const Variant& p_arg2=Variant(),const Variant& p_arg3=Variant(),const Variant& p_arg4=Variant(),const Variant& p_arg5=Variant() -#define VARIANT_ARG_PASS p_arg1,p_arg2,p_arg3,p_arg4,p_arg5 -#define VARIANT_ARG_DECLARE const Variant& p_arg1,const Variant& p_arg2,const Variant& p_arg3,const Variant& p_arg4,const Variant& p_arg5 -#define VARIANT_ARG_MAX 5 -#define VARIANT_ARGPTRS const Variant *argptr[5]={&p_arg1,&p_arg2,&p_arg3,&p_arg4,&p_arg5}; -#define VARIANT_ARGPTRS_PASS *argptr[0],*argptr[1],*argptr[2],*argptr[3],*argptr[4] -#define VARIANT_ARGS_FROM_ARRAY(m_arr) m_arr[0],m_arr[1],m_arr[2],m_arr[3],m_arr[4] +#define VARIANT_ARG_LIST const Variant& p_arg1=Variant(),const Variant& p_arg2=Variant(),const Variant& p_arg3=Variant(),const Variant& p_arg4=Variant(),const Variant& p_arg5=Variant(),const Variant& p_arg6=Variant() +#define VARIANT_ARG_PASS p_arg1,p_arg2,p_arg3,p_arg4,p_arg5,p_arg6 +#define VARIANT_ARG_DECLARE const Variant& p_arg1,const Variant& p_arg2,const Variant& p_arg3,const Variant& p_arg4,const Variant& p_arg5,const Variant& p_arg6 +#define VARIANT_ARG_MAX 6 +#define VARIANT_ARGPTRS const Variant *argptr[6]={&p_arg1,&p_arg2,&p_arg3,&p_arg4,&p_arg5,&p_arg6}; +#define VARIANT_ARGPTRS_PASS *argptr[0],*argptr[1],*argptr[2],*argptr[3],*argptr[4],*argptr[5] +#define VARIANT_ARGS_FROM_ARRAY(m_arr) m_arr[0],m_arr[1],m_arr[2],m_arr[3],m_arr[4],m_arr[5] /** @author Juan Linietsky diff --git a/core/variant.h b/core/variant.h index 47fc3f43ac..a3efc34452 100644 --- a/core/variant.h +++ b/core/variant.h @@ -387,7 +387,7 @@ public: }; Variant call(const StringName& p_method,const Variant** p_args,int p_argcount,CallError &r_error); - Variant call(const StringName& p_method,const Variant& p_arg1=Variant(),const Variant& p_arg2=Variant(),const Variant& p_arg3=Variant(),const Variant& p_arg4=Variant(),const Variant& p_arg5=Variant()); + Variant call(const StringName& p_method,const Variant& p_arg1=Variant(),const Variant& p_arg2=Variant(),const Variant& p_arg3=Variant(),const Variant& p_arg4=Variant(),const Variant& p_arg5=Variant(),const Variant& p_arg6=Variant()); static Variant construct(const Variant::Type,const Variant** p_args,int p_argcount,CallError &r_error); void get_method_list(List *p_list) const; diff --git a/demos/2d/polygon_path_finder_demo/.fscache b/demos/2d/polygon_path_finder_demo/.fscache index f699ca5849..bcec2f7a47 100644 --- a/demos/2d/polygon_path_finder_demo/.fscache +++ b/demos/2d/polygon_path_finder_demo/.fscache @@ -1,4 +1,4 @@ -::res://::1421147952 -icon.png::ImageTexture::1420046079:: -new_scene_poly_with_holes.scn::PackedScene::1421147952:: -polygonpathfinder.gd::GDScript::1421146502:: +::res://::1421669411 +icon.png::ImageTexture::1421499066:: +new_scene_poly_with_holes.scn::PackedScene::1421499066:: +polygonpathfinder.gd::GDScript::1421669411:: diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 9fcf34cee6..63a2867dac 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -29,6 +29,7 @@ #include "tile_map.h" #include "io/marshalls.h" #include "servers/physics_2d_server.h" +#include "method_bind_ext.inc" void TileMap::_notification(int p_what) { switch(p_what) { @@ -221,6 +222,10 @@ void TileMap::_update_dirty_quadrants() { rect.size.x=-rect.size.x; if (c.flip_v) rect.size.y=-rect.size.y; + if (c.transpose) { + //TODO + } + rect.pos+=tile_ofs; @@ -257,6 +262,11 @@ void TileMap::_update_dirty_quadrants() { xform.elements[2].y+=shape_ofs.y; } + if (c.transpose) { + //TODO + } else { + } + ps->body_add_shape(q.static_body,shape->get_rid(),xform); @@ -385,7 +395,7 @@ void TileMap::_make_quadrant_dirty(Map::Element *Q) { } -void TileMap::set_cell(int p_x,int p_y,int p_tile,bool p_flip_x,bool p_flip_y) { +void TileMap::set_cell(int p_x,int p_y,int p_tile,bool p_flip_x,bool p_flip_y,bool p_transpose) { PosKey pk(p_x,p_y); @@ -421,7 +431,7 @@ void TileMap::set_cell(int p_x,int p_y,int p_tile,bool p_flip_x,bool p_flip_y) { } else { ERR_FAIL_COND(!Q); // quadrant should exist... - if (E->get().id==p_tile && E->get().flip_h==p_flip_x && E->get().flip_v==p_flip_y) + if (E->get().id==p_tile && E->get().flip_h==p_flip_x && E->get().flip_v==p_flip_y && E->get().transpose==p_transpose) return; //nothing changed } @@ -432,6 +442,7 @@ void TileMap::set_cell(int p_x,int p_y,int p_tile,bool p_flip_x,bool p_flip_y) { c.id=p_tile; c.flip_h=p_flip_x; c.flip_v=p_flip_y; + c.transpose=p_transpose; _make_quadrant_dirty(Q); @@ -471,6 +482,17 @@ bool TileMap::is_cell_y_flipped(int p_x,int p_y) const { return E->get().flip_v; } +bool TileMap::is_cell_transposed(int p_x,int p_y) const { + + PosKey pk(p_x,p_y); + + const Map::Element *E=tile_map.find(pk); + + if (!E) + return false; + + return E->get().transpose; +} void TileMap::_recreate_quadrants() { @@ -535,11 +557,12 @@ void TileMap::_set_tile_data(const DVector& p_data) { uint32_t v = decode_uint32(&local[4]); bool flip_h = v&(1<<29); bool flip_v = v&(1<<30); + bool transpose = v&(1<<31); v&=(1<<29)-1; // if (x<-20 || y <-20 || x>4000 || y>4000) // continue; - set_cell(x,y,v,flip_h,flip_v); + set_cell(x,y,v,flip_h,flip_v,transpose); } @@ -562,6 +585,8 @@ DVector TileMap::_get_tile_data() const { val|=(1<<29); if (E->get().flip_v) val|=(1<<30); + if (E->get().transpose) + val|=(1<<31); encode_uint32(val,&ptr[4]); idx+=2; @@ -813,7 +838,7 @@ void TileMap::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_collision_bounce","value"),&TileMap::set_collision_bounce); ObjectTypeDB::bind_method(_MD("get_collision_bounce"),&TileMap::get_collision_bounce); - ObjectTypeDB::bind_method(_MD("set_cell","x","y","tile","flip_x","flip_y"),&TileMap::set_cell,DEFVAL(false),DEFVAL(false)); + ObjectTypeDB::bind_method(_MD("set_cell","x","y","tile","flip_x","flip_y","transpose"),&TileMap::set_cell,DEFVAL(false),DEFVAL(false),DEFVAL(false)); ObjectTypeDB::bind_method(_MD("get_cell","x","y"),&TileMap::get_cell); ObjectTypeDB::bind_method(_MD("is_cell_x_flipped","x","y"),&TileMap::is_cell_x_flipped); ObjectTypeDB::bind_method(_MD("is_cell_y_flipped","x","y"),&TileMap::is_cell_y_flipped); diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index 4e9e2e7e97..2809cdb378 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -85,6 +85,7 @@ private: int32_t id:24; bool flip_h:1; bool flip_v:1; + bool transpose:1; }; uint32_t _u32t; @@ -167,10 +168,11 @@ public: void set_center_y(bool p_enable); bool get_center_y() const; - void set_cell(int p_x,int p_y,int p_tile,bool p_flip_x=false,bool p_flip_y=false); + void set_cell(int p_x,int p_y,int p_tile,bool p_flip_x=false,bool p_flip_y=false,bool p_transpose=false); int get_cell(int p_x,int p_y) const; bool is_cell_x_flipped(int p_x,int p_y) const; bool is_cell_y_flipped(int p_x,int p_y) const; + bool is_cell_transposed(int p_x,int p_y) const; Rect2 get_item_rect() const; diff --git a/tools/editor/icons/icon_rotate_0.png b/tools/editor/icons/icon_rotate_0.png new file mode 100644 index 0000000000..85a4b4c420 Binary files /dev/null and b/tools/editor/icons/icon_rotate_0.png differ diff --git a/tools/editor/icons/icon_rotate_180.png b/tools/editor/icons/icon_rotate_180.png new file mode 100644 index 0000000000..c4c516cff5 Binary files /dev/null and b/tools/editor/icons/icon_rotate_180.png differ diff --git a/tools/editor/icons/icon_rotate_270.png b/tools/editor/icons/icon_rotate_270.png new file mode 100644 index 0000000000..6e0f2e62b8 Binary files /dev/null and b/tools/editor/icons/icon_rotate_270.png differ diff --git a/tools/editor/icons/icon_rotate_90.png b/tools/editor/icons/icon_rotate_90.png new file mode 100644 index 0000000000..f25b0e99a3 Binary files /dev/null and b/tools/editor/icons/icon_rotate_90.png differ diff --git a/tools/editor/icons/icon_transpose.png b/tools/editor/icons/icon_transpose.png new file mode 100644 index 0000000000..fab253c504 Binary files /dev/null and b/tools/editor/icons/icon_transpose.png differ diff --git a/tools/editor/plugins/tile_map_editor_plugin.cpp b/tools/editor/plugins/tile_map_editor_plugin.cpp index ce5ea58124..e387125b56 100644 --- a/tools/editor/plugins/tile_map_editor_plugin.cpp +++ b/tools/editor/plugins/tile_map_editor_plugin.cpp @@ -44,6 +44,11 @@ void TileMapEditor::_notification(int p_what) { mirror_x->set_icon( get_icon("MirrorX","EditorIcons")); mirror_y->set_icon( get_icon("MirrorY","EditorIcons")); + transpose->set_icon( get_icon("Transpose","EditorIcons")); + rotate_0->set_icon( get_icon("Rotate0","EditorIcons")); + rotate_90->set_icon( get_icon("Rotate90","EditorIcons")); + rotate_180->set_icon( get_icon("Rotate180","EditorIcons")); + rotate_270->set_icon( get_icon("Rotate270","EditorIcons")); } break; } @@ -85,24 +90,25 @@ void TileMapEditor::set_selected_tile(int p_tile) { } } -void TileMapEditor::_set_cell(const Point2i& p_pos,int p_value,bool p_flip_h, bool p_flip_v,bool p_with_undo) { +void TileMapEditor::_set_cell(const Point2i& p_pos,int p_value,bool p_flip_h, bool p_flip_v, bool p_transpose,bool p_with_undo) { ERR_FAIL_COND(!node); bool prev_flip_h=node->is_cell_x_flipped(p_pos.x,p_pos.y); bool prev_flip_v=node->is_cell_y_flipped(p_pos.x,p_pos.y); + bool prev_transpose=node->is_cell_transposed(p_pos.x,p_pos.y); int prev_val=node->get_cell(p_pos.x,p_pos.y); - if (p_value==prev_val && p_flip_h==prev_flip_h && p_flip_v==prev_flip_v) + if (p_value==prev_val && p_flip_h==prev_flip_h && p_flip_v==prev_transpose && p_flip_v==prev_transpose) return; //check that it's actually different if (p_with_undo) { - undo_redo->add_do_method(node,"set_cell",p_pos.x,p_pos.y,p_value,p_flip_h,p_flip_v); - undo_redo->add_undo_method(node,"set_cell",p_pos.x,p_pos.y,prev_val,prev_flip_h,prev_flip_v); + undo_redo->add_do_method(node,"set_cell",p_pos.x,p_pos.y,p_value,p_flip_h,p_flip_v,p_transpose); + undo_redo->add_undo_method(node,"set_cell",p_pos.x,p_pos.y,prev_val,prev_flip_h,prev_flip_v,prev_transpose); } else { - node->set_cell(p_pos.x,p_pos.y,p_value,p_flip_h,p_flip_v); + node->set_cell(p_pos.x,p_pos.y,p_value,p_flip_h,p_flip_v,p_transpose); } @@ -168,6 +174,7 @@ struct _TileMapEditorCopyData { int cell; bool flip_h; bool flip_v; + bool transpose; }; bool TileMapEditor::forward_input_event(const InputEvent& p_event) { @@ -214,7 +221,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { for (List<_TileMapEditorCopyData>::Element *E=dupdata.front();E;E=E->next()) { - _set_cell(E->get().pos+ofs,E->get().cell,E->get().flip_h,E->get().flip_v,true); + _set_cell(E->get().pos+ofs,E->get().cell,E->get().flip_h,E->get().flip_v,E->get().transpose,true); } undo_redo->commit_action(); @@ -239,6 +246,9 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { } else if (mb.mod.control) { tool=TOOL_PICKING; set_selected_tile(node->get_cell(over_tile.x, over_tile.y)); + mirror_x->set_pressed(node->is_cell_x_flipped(over_tile.x, over_tile.y)); + mirror_y->set_pressed(node->is_cell_y_flipped(over_tile.x, over_tile.y)); + transpose->set_pressed(node->is_cell_transposed(over_tile.x, over_tile.y)); canvas_item_editor->update(); return true; } else { @@ -248,7 +258,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { Point2i local =node->world_to_map((xform_inv.xform(Point2(mb.x,mb.y)))); paint_undo.clear(); paint_undo[local]=_get_op_from_cell(local); - node->set_cell(local.x,local.y,id,mirror_x->is_pressed(),mirror_y->is_pressed()); + node->set_cell(local.x,local.y,id,mirror_x->is_pressed(),mirror_y->is_pressed(),transpose->is_pressed()); return true; } } @@ -263,8 +273,8 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { for(Map::Element *E=paint_undo.front();E;E=E->next()) { Point2i p=E->key(); - undo_redo->add_do_method(node,"set_cell",p.x,p.y,node->get_cell(p.x,p.y),node->is_cell_x_flipped(p.x,p.y),node->is_cell_y_flipped(p.x,p.y)); - undo_redo->add_undo_method(node,"set_cell",p.x,p.y,E->get().idx,E->get().xf,E->get().yf); + undo_redo->add_do_method(node,"set_cell",p.x,p.y,node->get_cell(p.x,p.y),node->is_cell_x_flipped(p.x,p.y),node->is_cell_y_flipped(p.x,p.y),node->is_cell_transposed(p.x,p.y)); + undo_redo->add_undo_method(node,"set_cell",p.x,p.y,E->get().idx,E->get().xf,E->get().yf,E->get().tr); } undo_redo->commit_action(); @@ -289,7 +299,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { Point2i local =node->world_to_map(xform_inv.xform(Point2(mb.x,mb.y))); paint_undo.clear(); paint_undo[local]=_get_op_from_cell(local); - //node->set_cell(local.x,local.y,id,mirror_x->is_pressed(),mirror_y->is_pressed()); + //node->set_cell(local.x,local.y,id,mirror_x->is_pressed(),mirror_y->is_pressed(),transpose->is_pressed()); //return true; _set_cell(local,TileMap::INVALID_CELL); return true; @@ -302,9 +312,9 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { for(Map::Element *E=paint_undo.front();E;E=E->next()) { Point2i p=E->key(); - //undo_redo->add_do_method(node,"set_cell",p.x,p.y,node->get_cell(p.x,p.y),node->is_cell_x_flipped(p.x,p.y),node->is_cell_y_flipped(p.x,p.y)); - _set_cell(p,TileMap::INVALID_CELL,false,false,true); - undo_redo->add_undo_method(node,"set_cell",p.x,p.y,E->get().idx,E->get().xf,E->get().yf); + //undo_redo->add_do_method(node,"set_cell",p.x,p.y,node->get_cell(p.x,p.y),node->is_cell_x_flipped(p.x,p.y),node->is_cell_y_flipped(p.x,p.y),node->is_cell_transposed(p.x,p.y)); + _set_cell(p,TileMap::INVALID_CELL,false,false,false,true); + undo_redo->add_undo_method(node,"set_cell",p.x,p.y,E->get().idx,E->get().xf,E->get().yf,E->get().tr); } undo_redo->commit_action(); @@ -340,7 +350,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { 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()); + node->set_cell(over_tile.x,over_tile.y,id,mirror_x->is_pressed(),mirror_y->is_pressed(),transpose->is_pressed()); return true; } @@ -373,13 +383,16 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { if (!paint_undo.has(over_tile)) { 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()); + //node->set_cell(over_tile.x,over_tile.y,id,mirror_x->is_pressed(),mirror_y->is_pressed(),transpose->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)); + mirror_x->set_pressed(node->is_cell_x_flipped(over_tile.x, over_tile.y)); + mirror_y->set_pressed(node->is_cell_y_flipped(over_tile.x, over_tile.y)); + transpose->set_pressed(node->is_cell_transposed(over_tile.x, over_tile.y)); canvas_item_editor->update(); return true; } @@ -625,6 +638,9 @@ void TileMapEditor::_canvas_draw() { sc.x*=-1.0; if (mirror_y->is_pressed()) sc.y*=-1.0; + if (transpose->is_pressed()) { + //TODO + } if (r==Rect2()) { canvas_item_editor->draw_texture_rect(t,Rect2(from,t->get_size()*sc),false,Color(1,1,1,0.5)); @@ -744,6 +760,32 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) { mirror_y->set_tooltip("Mirror Y (S)"); mirror_y->set_focus_mode(FOCUS_NONE); canvas_item_editor_hb->add_child(mirror_y); + transpose = memnew( ToolButton ); + transpose->set_toggle_mode(true); + transpose->set_tooltip("Transpose"); + transpose->set_focus_mode(FOCUS_NONE); + canvas_item_editor_hb->add_child(transpose); + canvas_item_editor_hb->add_child(memnew(VSeparator)); + rotate_0 = memnew( ToolButton ); + rotate_0->set_toggle_mode(true); + rotate_0->set_tooltip("Rotate 0 degrees"); + rotate_0->set_focus_mode(FOCUS_NONE); + canvas_item_editor_hb->add_child(rotate_0); + rotate_90 = memnew( ToolButton ); + rotate_90->set_toggle_mode(true); + rotate_90->set_tooltip("Rotate 90 degrees"); + rotate_90->set_focus_mode(FOCUS_NONE); + canvas_item_editor_hb->add_child(rotate_90); + rotate_180 = memnew( ToolButton ); + rotate_180->set_toggle_mode(true); + rotate_180->set_tooltip("Rotate 180 degrees"); + rotate_180->set_focus_mode(FOCUS_NONE); + canvas_item_editor_hb->add_child(rotate_180); + rotate_270 = memnew( ToolButton ); + rotate_270->set_toggle_mode(true); + rotate_270->set_tooltip("Rotate 270 degrees"); + rotate_270->set_focus_mode(FOCUS_NONE); + canvas_item_editor_hb->add_child(rotate_270); canvas_item_editor_hb->hide(); tool=TOOL_NONE; diff --git a/tools/editor/plugins/tile_map_editor_plugin.h b/tools/editor/plugins/tile_map_editor_plugin.h index f3c590e228..dd278be2c8 100644 --- a/tools/editor/plugins/tile_map_editor_plugin.h +++ b/tools/editor/plugins/tile_map_editor_plugin.h @@ -73,6 +73,11 @@ class TileMapEditor : public VBoxContainer { Label *mirror_label; ToolButton *mirror_x; ToolButton *mirror_y; + ToolButton *transpose; + ToolButton *rotate_0; + ToolButton *rotate_90; + ToolButton *rotate_180; + ToolButton *rotate_270; HBoxContainer *canvas_item_editor_hb; @@ -81,8 +86,8 @@ class TileMapEditor : public VBoxContainer { int idx; 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) {} + bool tr; + CellOp() { idx=-1; xf=false; yf=false; tr=false; } }; Map paint_undo; @@ -94,7 +99,7 @@ class TileMapEditor : public VBoxContainer { void _canvas_draw(); void _menu_option(int p_option); - void _set_cell(const Point2i& p_pos, int p_value, bool p_flip_h=false, bool p_flip_v=false, bool p_with_undo=false); + void _set_cell(const Point2i& p_pos, int p_value, bool p_flip_h=false, bool p_flip_v=false, bool p_transpose=false, bool p_with_undo=false); void _canvas_mouse_enter(); void _canvas_mouse_exit(); -- cgit v1.2.3 From 92cc7b840eff99e90b64caad6883aefbe4c3dd1e Mon Sep 17 00:00:00 2001 From: Nathan Warden Date: Mon, 19 Jan 2015 15:47:50 -0500 Subject: Fixed a bug where a user could add a cyclical dependency, causing a crash. --- tools/editor/scene_tree_dock.cpp | 29 ++++++++++++++++++++++++++++- tools/editor/scene_tree_dock.h | 1 + 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/tools/editor/scene_tree_dock.cpp b/tools/editor/scene_tree_dock.cpp index cff3913579..d8d713ee40 100644 --- a/tools/editor/scene_tree_dock.cpp +++ b/tools/editor/scene_tree_dock.cpp @@ -79,7 +79,15 @@ Node* SceneTreeDock::instance(const String& p_file) { //accept->get_cancel()->hide(); accept->get_ok()->set_text("Ugh"); accept->set_text(String("Error loading scene from ")+p_file); - accept->popup_centered(Size2(300,70));; + accept->popup_centered(Size2(300,70)); + return NULL; + } + + if (_cyclical_dependency_exists(edited_scene->get_filename(), instanced_scene)) { + + accept->get_ok()->set_text("Ok"); + accept->set_text(String("Cannot instance the scene '")+p_file+String("' because the current scene exists within one of its' nodes.")); + accept->popup_centered(Size2(300,90)); return NULL; } @@ -100,6 +108,25 @@ Node* SceneTreeDock::instance(const String& p_file) { } +bool SceneTreeDock::_cyclical_dependency_exists(const String& p_target_scene_path, Node* p_desired_node) { + int childCount = p_desired_node->get_child_count(); + + if (p_desired_node->get_filename()==p_target_scene_path) { + return true; + } + + for (int i=0;iget_child(i); + + if(_cyclical_dependency_exists(p_target_scene_path,child)) { + return true; + } + } + + return false; +} + + static String _get_name_num_separator() { switch(EditorSettings::get_singleton()->get("scenetree_editor/duplicate_node_name_num_separator").operator int()) { case 0: return ""; diff --git a/tools/editor/scene_tree_dock.h b/tools/editor/scene_tree_dock.h index ac5391f3b9..92ebfc5bee 100644 --- a/tools/editor/scene_tree_dock.h +++ b/tools/editor/scene_tree_dock.h @@ -102,6 +102,7 @@ class SceneTreeDock : public VBoxContainer { void _load_request(const String& p_path); void _script_open_request(const Ref