summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bin/tests/test_math.cpp400
-rw-r--r--core/input_map.cpp58
-rw-r--r--core/input_map.h1
-rw-r--r--core/object_type_db.cpp174
-rw-r--r--core/object_type_db.h15
-rw-r--r--core/os/input_event.cpp2
-rw-r--r--doc/base/classes.xml10
-rw-r--r--drivers/gles2/rasterizer_gles2.cpp4
-rw-r--r--drivers/gles2/shader_compiler_gles2.cpp1
-rw-r--r--drivers/gles2/shaders/canvas.glsl4
-rw-r--r--drivers/gles2/shaders/material.glsl4
-rw-r--r--drivers/vorbis/SCsub4
-rw-r--r--main/input_default.cpp7
-rw-r--r--main/main.cpp5
-rw-r--r--scene/2d/camera_2d.cpp70
-rw-r--r--scene/2d/camera_2d.h5
-rw-r--r--scene/main/canvas_layer.cpp60
-rw-r--r--scene/main/canvas_layer.h8
-rw-r--r--scene/main/viewport.cpp54
-rw-r--r--scene/main/viewport.h2
-rw-r--r--scene/resources/shader_graph.cpp4
-rw-r--r--servers/visual/shader_language.cpp1
-rw-r--r--tools/editor/editor_node.cpp25
-rw-r--r--tools/editor/editor_node.h9
-rw-r--r--tools/editor/editor_plugin.cpp19
-rw-r--r--tools/editor/editor_plugin.h4
-rw-r--r--tools/editor/plugins/script_editor_plugin.cpp31
-rw-r--r--tools/editor/plugins/shader_graph_editor_plugin.cpp2
28 files changed, 847 insertions, 136 deletions
diff --git a/bin/tests/test_math.cpp b/bin/tests/test_math.cpp
index 4b686e8af8..e5667bff64 100644
--- a/bin/tests/test_math.cpp
+++ b/bin/tests/test_math.cpp
@@ -40,12 +40,376 @@
#include "scene/resources/texture.h"
#include "vmap.h"
#include "os/os.h"
+#include "os/file_access.h"
#include "method_ptrcall.h"
namespace TestMath {
+class GetClassAndNamespace {
+
+ String code;
+ int idx;
+ int line;
+ String error_str;
+ bool error;
+ Variant value;
+
+ String class_name;
+
+ enum Token {
+ TK_BRACKET_OPEN,
+ TK_BRACKET_CLOSE,
+ TK_CURLY_BRACKET_OPEN,
+ TK_CURLY_BRACKET_CLOSE,
+ TK_PERIOD,
+ TK_COLON,
+ TK_COMMA,
+ TK_SYMBOL,
+ TK_IDENTIFIER,
+ TK_STRING,
+ TK_NUMBER,
+ TK_EOF,
+ TK_ERROR
+ };
+
+
+ Token get_token() {
+
+ while (true) {
+ switch(code[idx]) {
+
+ case '\n': {
+
+ line++;
+ idx++;
+ break;
+ };
+ case 0: {
+ return TK_EOF;
+
+ } break;
+ case '{': {
+
+ idx++;
+ return TK_CURLY_BRACKET_OPEN;
+ };
+ case '}': {
+
+ idx++;
+ return TK_CURLY_BRACKET_CLOSE;
+ };
+ case '[': {
+
+ idx++;
+ return TK_BRACKET_OPEN;
+ };
+ case ']': {
+
+ idx++;
+ return TK_BRACKET_CLOSE;
+ };
+ case ':': {
+
+ idx++;
+ return TK_COLON;
+ };
+ case ',': {
+
+ idx++;
+ return TK_COMMA;
+ };
+ case '.': {
+
+ idx++;
+ return TK_PERIOD;
+ };
+ case '#': {
+ //compiler directive
+ while(code[idx]!='\n' && code[idx]!=0) {
+ idx++;
+ }
+ continue;
+ } break;
+ case '/': {
+
+
+ switch(code[idx+1]) {
+ case '*': { // block comment
+
+ idx+=2;
+ while(true) {
+ if (code[idx]==0) {
+ error_str="Unterminated comment";
+ error=true;
+ return TK_ERROR;
+ } if (code[idx]=='*' &&code[idx+1]=='/') {
+
+ idx+=2;
+ break;
+ } if (code[idx]=='\n') {
+ line++;
+ }
+
+ idx++;
+ }
+
+ } break;
+ case '/': { // line comment skip
+
+ while(code[idx]!='\n' && code[idx]!=0) {
+ idx++;
+ }
+
+ } break;
+ default: {
+ value="/";
+ idx++;
+ return TK_SYMBOL;
+ }
+
+ }
+
+ continue; // a comment
+ } break;
+ case '\'':
+ case '"': {
+
+ CharType begin_str = code[idx];
+ idx++;
+ String tk_string=String();
+ while(true) {
+ if (code[idx]==0) {
+ error_str="Unterminated String";
+ error=true;
+ return TK_ERROR;
+ } else if (code[idx]==begin_str) {
+ idx++;
+ break;
+ } else if (code[idx]=='\\') {
+ //escaped characters...
+ idx++;
+ CharType next = code[idx];
+ if (next==0) {
+ error_str="Unterminated String";
+ error=true;
+ return TK_ERROR;
+ }
+ CharType res=0;
+
+ switch(next) {
+
+ case 'b': res=8; break;
+ case 't': res=9; break;
+ case 'n': res=10; break;
+ case 'f': res=12; break;
+ case 'r': res=13; break;
+ /* too much, not needed for now
+ case 'u': {
+ //hexnumbarh - oct is deprecated
+
+
+ for(int j=0;j<4;j++) {
+ CharType c = code[idx+j+1];
+ if (c==0) {
+ r_err_str="Unterminated String";
+ return ERR_PARSE_ERROR;
+ }
+ if (!((c>='0' && c<='9') || (c>='a' && c<='f') || (c>='A' && c<='F'))) {
+
+ r_err_str="Malformed hex constant in string";
+ return ERR_PARSE_ERROR;
+ }
+ CharType v;
+ if (c>='0' && c<='9') {
+ v=c-'0';
+ } else if (c>='a' && c<='f') {
+ v=c-'a';
+ v+=10;
+ } else if (c>='A' && c<='F') {
+ v=c-'A';
+ v+=10;
+ } else {
+ ERR_PRINT("BUG");
+ v=0;
+ }
+
+ res<<=4;
+ res|=v;
+
+
+ }
+ idx+=4; //will add at the end anyway
+
+
+ } break;*/
+ case '\"': res='\"'; break;
+ case '\\': res='\\'; break;
+ //case '/': res='/'; break;
+ default: {
+ res = next;
+ //r_err_str="Invalid escape sequence";
+ //return ERR_PARSE_ERROR;
+ } break;
+ }
+
+ tk_string+=res;
+
+ } else {
+ if (code[idx]=='\n')
+ line++;
+ tk_string+=code[idx];
+ }
+ idx++;
+ }
+
+ value=tk_string;
+
+ return TK_STRING;
+
+ } break;
+ default: {
+
+ if (code[idx]<=32) {
+ idx++;
+ break;
+ }
+
+ if ( (code[idx]>=33 && code[idx]<=47) || (code[idx]>=58 && code[idx]<=64) || (code[idx]>=91 && code[idx]<=96) || (code[idx]>=123 && code[idx]<=127)){
+ value=String::chr(code[idx]);
+ idx++;
+ return TK_SYMBOL;
+ }
+
+ if (code[idx]=='-' || (code[idx]>='0' && code[idx]<='9')) {
+ //a number
+ const CharType *rptr;
+ double number = String::to_double(&code[idx],&rptr);
+ idx+=(rptr - &code[idx]);
+ value=number;
+ return TK_NUMBER;
+
+ } else if ((code[idx]>='A' && code[idx]<='Z') || (code[idx]>='a' && code[idx]<='z') || code[idx]>127) {
+
+ String id;
+
+ while((code[idx]>='A' && code[idx]<='Z') || (code[idx]>='a' && code[idx]<='z') || code[idx]>127) {
+
+ id+=code[idx];
+ idx++;
+ }
+
+ value=id;
+ return TK_IDENTIFIER;
+ } else {
+ error_str="Unexpected character.";
+ error=true;
+ return TK_ERROR;
+ }
+ }
+
+ }
+ }
+ }
+
+public:
+ Error parse(const String& p_code,const String& p_known_class_name=String()) {
+
+ code=p_code;
+ idx=0;
+ line=0;
+ error_str=String();
+ error=false;
+ value=Variant();
+ class_name=String();
+
+ bool use_next_class=false;
+ Token tk = get_token();
+
+ Map<int,String> namespace_stack;
+ int curly_stack=0;
+
+
+ while(!error || tk!=TK_EOF) {
+
+ if (tk==TK_BRACKET_OPEN) {
+ tk = get_token();
+ if (tk==TK_IDENTIFIER && String(value)=="ScriptClass") {
+ if (get_token()==TK_BRACKET_CLOSE) {
+ use_next_class=true;
+ }
+ }
+ } else if (tk==TK_IDENTIFIER && String(value)=="class") {
+ tk = get_token();
+ if (tk==TK_IDENTIFIER) {
+ String name = value;
+ if (use_next_class || p_known_class_name==name) {
+ for (Map<int,String>::Element *E=namespace_stack.front();E;E=E->next()) {
+ class_name+=E->get()+".";
+ }
+ class_name+=String(value);
+ break;
+ }
+ }
+
+ } else if (tk==TK_IDENTIFIER && String(value)=="namespace") {
+ String name;
+ int at_level = curly_stack;
+ while(true) {
+ tk = get_token();
+ if (tk==TK_IDENTIFIER) {
+ name+=String(value);
+ }
+
+ tk = get_token();
+ if (tk==TK_PERIOD) {
+ name+=".";
+ } else if (tk==TK_CURLY_BRACKET_OPEN) {
+ curly_stack++;
+ break;
+ } else {
+ break; //whathever else
+ }
+
+ }
+
+ if (name!=String()) {
+ namespace_stack[at_level]=name;
+ }
+
+ } else if (tk==TK_CURLY_BRACKET_OPEN) {
+ curly_stack++;
+ } else if (tk==TK_CURLY_BRACKET_CLOSE) {
+ curly_stack--;
+ if (namespace_stack.has(curly_stack)) {
+ namespace_stack.erase(curly_stack);
+ }
+ }
+
+ tk = get_token();
+ }
+
+ if (error)
+ return ERR_PARSE_ERROR;
+
+
+
+ return OK;
+
+ }
+
+ String get_error() {
+ return error_str;
+ }
+
+ String get_class() {
+ return class_name;
+ }
+
+};
+
+
void test_vec(Plane p_vec) {
@@ -113,7 +477,41 @@ uint32_t ihash3( uint32_t a)
MainLoop* test() {
- print_line(itos(Math::step_decimals( 0.0001 )));
+
+ List<String> cmdlargs = OS::get_singleton()->get_cmdline_args();
+
+ if (cmdlargs.empty()) {
+ //try editor!
+ return NULL;
+ }
+
+ String test = cmdlargs.back()->get();
+
+ FileAccess *fa = FileAccess::open(test,FileAccess::READ);
+
+ if (!fa) {
+ ERR_EXPLAIN("Could not open file: "+test);
+ ERR_FAIL_V(NULL);
+ }
+
+
+ Vector<uint8_t> buf;
+ int flen = fa->get_len();
+ buf.resize(fa->get_len()+1);
+ fa->get_buffer(&buf[0],flen);
+ buf[flen]=0;
+
+
+ String code;
+ code.parse_utf8((const char*)&buf[0]);
+
+ GetClassAndNamespace getclass;
+ if (getclass.parse(code)) {
+ print_line("Parse error: "+getclass.get_error());
+ } else {
+ print_line("Found class: "+getclass.get_class());
+ }
+
return NULL;
{
diff --git a/core/input_map.cpp b/core/input_map.cpp
index 3a0f9596f5..09cb7ce426 100644
--- a/core/input_map.cpp
+++ b/core/input_map.cpp
@@ -232,64 +232,6 @@ bool InputMap::event_is_action(const InputEvent& p_event, const StringName& p_ac
return _find_event(E->get().inputs,p_event)!=NULL;
}
-bool InputMap::event_is_joy_motion_action_pressed(const InputEvent& p_event) const {
-
- ERR_FAIL_COND_V(p_event.type!=InputEvent::JOYSTICK_MOTION,false);
- bool pressed=false;
-
- //this could be optimized by having a separate list of joymotions?
-
- for (Map<StringName, Action>::Element *A=input_map.front();A;A=A->next()) {
-
- for (List<InputEvent>::Element *E=A->get().inputs.front();E;E=E->next()) {
-
- const InputEvent& e=E->get();
- if(e.type!=p_event.type)
- continue;
- if (e.type!=InputEvent::KEY && e.device!=p_event.device)
- continue;
-
- switch(p_event.type) {
-
- case InputEvent::KEY: {
-
- if (e.key.scancode==p_event.key.scancode && e.key.mod == p_event.key.mod)
- return e.key.pressed;
-
- } break;
- case InputEvent::JOYSTICK_BUTTON: {
-
- if (e.joy_button.button_index==p_event.joy_button.button_index) {
- return e.joy_button.pressed;
- }
-
- } break;
- case InputEvent::MOUSE_BUTTON: {
-
- if (e.mouse_button.button_index==p_event.mouse_button.button_index) {
- return e.mouse_button.pressed;
- }
-
- } break;
- case InputEvent::JOYSTICK_MOTION: {
-
- if (e.joy_motion.axis==p_event.joy_motion.axis) {
- if (
- (e.joy_motion.axis_value * p_event.joy_motion.axis_value >0) && //same axis
- ABS(e.joy_motion.axis_value)>0.5 && ABS(p_event.joy_motion.axis_value)>0.5 )
- pressed=true;
- }
-
- } break;
- }
-
- }
- }
-
- return pressed;
-
-}
-
const Map<StringName, InputMap::Action>& InputMap::get_action_map() const {
return input_map;
}
diff --git a/core/input_map.h b/core/input_map.h
index a224765d8c..21c479588d 100644
--- a/core/input_map.h
+++ b/core/input_map.h
@@ -72,7 +72,6 @@ public:
const List<InputEvent> *get_action_list(const StringName& p_action);
bool event_is_action(const InputEvent& p_event, const StringName& p_action) const;
- bool event_is_joy_motion_action_pressed(const InputEvent& p_event) const;
const Map<StringName, Action>& get_action_map() const;
void load_from_globals();
diff --git a/core/object_type_db.cpp b/core/object_type_db.cpp
index aa641923e6..e121dc9e98 100644
--- a/core/object_type_db.cpp
+++ b/core/object_type_db.cpp
@@ -189,6 +189,14 @@ MethodDefinition _MD(const char* p_name,const char *p_arg1,const char *p_arg2,co
#endif
+
+ObjectTypeDB::APIType ObjectTypeDB::current_api=API_CORE;
+
+void ObjectTypeDB::set_current_api(APIType p_api) {
+
+ current_api=p_api;
+}
+
HashMap<StringName,ObjectTypeDB::TypeInfo,StringNameHasher> ObjectTypeDB::types;
HashMap<StringName,StringName,StringNameHasher> ObjectTypeDB::resource_base_extensions;
HashMap<StringName,StringName,StringNameHasher> ObjectTypeDB::compat_types;
@@ -258,6 +266,171 @@ StringName ObjectTypeDB::type_inherits_from(const StringName& p_type) {
return ti->inherits;
}
+ObjectTypeDB::APIType ObjectTypeDB::get_api_type(const StringName &p_type) {
+
+ OBJTYPE_LOCK;
+
+ TypeInfo *ti = types.getptr(p_type);
+ ERR_FAIL_COND_V(!ti,API_NONE);
+ return ti->api;
+}
+
+uint64_t ObjectTypeDB::get_api_hash(APIType p_api) {
+
+#ifdef DEBUG_METHODS_ENABLED
+
+ uint64_t hash = hash_djb2_one_64(HashMapHahserDefault::hash(VERSION_FULL_NAME));
+
+ List<StringName> names;
+
+ const StringName *k=NULL;
+
+ while((k=types.next(k))) {
+
+ names.push_back(*k);
+ }
+ //must be alphabetically sorted for hash to compute
+ names.sort_custom<StringName::AlphCompare>();
+
+ for (List<StringName>::Element *E=names.front();E;E=E->next()) {
+
+ TypeInfo *t = types.getptr(E->get());
+ ERR_FAIL_COND_V(!t,0);
+ if (t->api!=p_api)
+ continue;
+ hash = hash_djb2_one_64(t->name.hash(),hash);
+ hash = hash_djb2_one_64(t->inherits.hash(),hash);
+
+ { //methods
+
+ List<StringName> snames;
+
+ k=NULL;
+
+ while((k=t->method_map.next(k))) {
+
+ snames.push_back(*k);
+ }
+
+ snames.sort_custom<StringName::AlphCompare>();
+
+ for (List<StringName>::Element *F=snames.front();F;F=F->next()) {
+
+ MethodBind *mb = t->method_map[F->get()];
+ hash = hash_djb2_one_64( mb->get_name().hash(), hash);
+ hash = hash_djb2_one_64( mb->get_argument_count(), hash);
+ hash = hash_djb2_one_64( mb->get_argument_type(-1), hash); //return
+
+ for(int i=0;i<mb->get_argument_count();i++) {
+ hash = hash_djb2_one_64( mb->get_argument_info(i).type, hash );
+ hash = hash_djb2_one_64( mb->get_argument_info(i).name.hash(), hash );
+ hash = hash_djb2_one_64( mb->get_argument_info(i).hint, hash );
+ hash = hash_djb2_one_64( mb->get_argument_info(i).hint_string.hash(), hash );
+ }
+
+ hash = hash_djb2_one_64( mb->get_default_argument_count(), hash);
+
+ for(int i=0;i<mb->get_default_argument_count();i++) {
+ //hash should not change, i hope for tis
+ Variant da = mb->get_default_argument(i);
+ hash = hash_djb2_one_64( da.hash(), hash );
+ }
+
+ hash = hash_djb2_one_64( mb->get_hint_flags(), hash);
+
+ }
+ }
+
+
+ { //constants
+
+ List<StringName> snames;
+
+ k=NULL;
+
+ while((k=t->constant_map.next(k))) {
+
+ snames.push_back(*k);
+ }
+
+ snames.sort_custom<StringName::AlphCompare>();
+
+ for (List<StringName>::Element *F=snames.front();F;F=F->next()) {
+
+ hash = hash_djb2_one_64(F->get().hash(), hash);
+ hash = hash_djb2_one_64( t->constant_map[F->get()], hash);
+ }
+ }
+
+
+ { //signals
+
+ List<StringName> snames;
+
+ k=NULL;
+
+ while((k=t->signal_map.next(k))) {
+
+ snames.push_back(*k);
+ }
+
+ snames.sort_custom<StringName::AlphCompare>();
+
+ for (List<StringName>::Element *F=snames.front();F;F=F->next()) {
+
+ MethodInfo &mi = t->signal_map[F->get()];
+ hash = hash_djb2_one_64( F->get().hash(), hash);
+ for(int i=0;i<mi.arguments.size();i++) {
+ hash = hash_djb2_one_64( mi.arguments[i].type, hash);
+ }
+ }
+ }
+
+ { //properties
+
+ List<StringName> snames;
+
+ k=NULL;
+
+ while((k=t->property_setget.next(k))) {
+
+ snames.push_back(*k);
+ }
+
+ snames.sort_custom<StringName::AlphCompare>();
+
+ for (List<StringName>::Element *F=snames.front();F;F=F->next()) {
+
+ PropertySetGet *psg=t->property_setget.getptr(F->get());
+
+ hash = hash_djb2_one_64( F->get().hash(), hash);
+ hash = hash_djb2_one_64( psg->setter.hash(), hash);
+ hash = hash_djb2_one_64( psg->getter.hash(), hash);
+
+ }
+ }
+
+ //property list
+ for (List<PropertyInfo>::Element *F=t->property_list.front();F;F=F->next()) {
+
+ hash = hash_djb2_one_64( F->get().name.hash(), hash);
+ hash = hash_djb2_one_64( F->get().type, hash);
+ hash = hash_djb2_one_64( F->get().hint, hash);
+ hash = hash_djb2_one_64( F->get().hint_string.hash(), hash);
+ hash = hash_djb2_one_64( F->get().usage, hash);
+ }
+
+
+ }
+
+
+ return hash;
+#else
+ return 0;
+#endif
+
+}
+
bool ObjectTypeDB::type_exists(const StringName &p_type) {
OBJTYPE_LOCK;
@@ -309,6 +482,7 @@ void ObjectTypeDB::_add_type2(const StringName& p_type, const StringName& p_inhe
TypeInfo &ti=types[name];
ti.name=name;
ti.inherits=p_inherits;
+ ti.api=current_api;
if (ti.inherits) {
diff --git a/core/object_type_db.h b/core/object_type_db.h
index 725b424c9a..9e9029ff2f 100644
--- a/core/object_type_db.h
+++ b/core/object_type_db.h
@@ -109,7 +109,13 @@ static _FORCE_INLINE_ const char* _MD(const char* m_name, ...) { return m_name;
#endif
class ObjectTypeDB {
-
+public:
+ enum APIType {
+ API_CORE,
+ API_EDITOR,
+ API_NONE
+ };
+public:
struct PropertySetGet {
int index;
@@ -122,6 +128,7 @@ class ObjectTypeDB {
struct TypeInfo {
+ APIType api;
TypeInfo *inherits_ptr;
HashMap<StringName,MethodBind*,StringNameHasher> method_map;
HashMap<StringName,int,StringNameHasher> constant_map;
@@ -161,6 +168,7 @@ class ObjectTypeDB {
#endif
+ static APIType current_api;
static void _add_type2(const StringName& p_type, const StringName& p_inherits);
public:
@@ -236,6 +244,9 @@ public:
static bool is_type(const StringName &p_type,const StringName& p_inherits);
static bool can_instance(const StringName &p_type);
static Object *instance(const StringName &p_type);
+ static APIType get_api_type(const StringName &p_type);
+
+ static uint64_t get_api_hash(APIType p_api);
#if 0
template<class N, class M>
@@ -499,6 +510,8 @@ public:
static void add_compatibility_type(const StringName& p_type,const StringName& p_fallback);
static void init();
+
+ static void set_current_api(APIType p_api);
static void cleanup();
};
diff --git a/core/os/input_event.cpp b/core/os/input_event.cpp
index 9d920724e1..9982767be1 100644
--- a/core/os/input_event.cpp
+++ b/core/os/input_event.cpp
@@ -204,7 +204,7 @@ bool InputEvent::is_pressed() const {
case MOUSE_BUTTON: return mouse_button.pressed;
case JOYSTICK_BUTTON: return joy_button.pressed;
case SCREEN_TOUCH: return screen_touch.pressed;
- case JOYSTICK_MOTION: return InputMap::get_singleton()->event_is_joy_motion_action_pressed(*this);
+ case JOYSTICK_MOTION: return ABS(joy_motion.axis_value) > 0.5;
case ACTION: return action.pressed;
default: {}
}
diff --git a/doc/base/classes.xml b/doc/base/classes.xml
index 916ca09c92..f6ea8b08ee 100644
--- a/doc/base/classes.xml
+++ b/doc/base/classes.xml
@@ -11697,6 +11697,13 @@
Get the general settings for the editor (the same window that appears in the Settings menu).
</description>
</method>
+ <method name="get_editor_viewport">
+ <return type="Control">
+ </return>
+ <description>
+ Get the main editor control. Use this as a parent for main screens.
+ </description>
+ </method>
<method name="get_name" qualifiers="virtual">
<return type="String">
</return>
@@ -16640,7 +16647,8 @@
<argument index="3" name="duration" type="float" default="0">
</argument>
<description>
- Starts to vibrate the joystick. Joysticks usually come with two rumble motors, a strong and a weak one. weak_magnitude is the strength of the weak motor (between 0 and 1) and strong_magnitude is the strength of the strong motor (between 0 and 1). duration is the duration of the effect in seconds (a duration of 0 will play the vibration indefinitely).
+ Starts to vibrate the joystick. Joysticks usually come with two rumble motors, a strong and a weak one. weak_magnitude is the strength of the weak motor (between 0 and 1) and strong_magnitude is the strength of the strong motor (between 0 and 1). duration is the duration of the effect in seconds (a duration of 0 will try to play the vibration indefinitely).
+ Note that not every hardware is compatible with long effect durations, it is recommended to restart an effect if in need to play it for more than a few seconds.
</description>
</method>
<method name="stop_joy_vibration">
diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp
index 8350fb0674..d5becc0bfc 100644
--- a/drivers/gles2/rasterizer_gles2.cpp
+++ b/drivers/gles2/rasterizer_gles2.cpp
@@ -4666,7 +4666,7 @@ void RasterizerGLES2::_update_shader( Shader* p_shader) const {
enablers.push_back("#define USE_LIGHT_SHADER_CODE\n");
}
if (light_flags.uses_shadow_color) {
- enablers.push_back("#define USE_LIGHT_SHADOW_COLOR\n");
+ enablers.push_back("#define USE_OUTPUT_SHADOW_COLOR\n");
}
if (light_flags.uses_time || fragment_flags.uses_time || vertex_flags.uses_time) {
enablers.push_back("#define USE_TIME\n");
@@ -4709,7 +4709,7 @@ void RasterizerGLES2::_update_shader( Shader* p_shader) const {
enablers.push_back("#define USE_TEXPIXEL_SIZE\n");
}
if (light_flags.uses_shadow_color) {
- enablers.push_back("#define USE_LIGHT_SHADOW_COLOR\n");
+ enablers.push_back("#define USE_OUTPUT_SHADOW_COLOR\n");
}
if (vertex_flags.uses_worldvec) {
diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp
index 3be0fdab17..d4636ed444 100644
--- a/drivers/gles2/shader_compiler_gles2.cpp
+++ b/drivers/gles2/shader_compiler_gles2.cpp
@@ -904,6 +904,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT]["LIGHT_VEC"]="light_vec";
mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT]["LIGHT_HEIGHT"]="light_height";
mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT]["LIGHT_COLOR"]="light";
+ mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT]["LIGHT_SHADOW"]="light_shadow_color";
mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT]["LIGHT_UV"]="light_uv";
mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT]["LIGHT"]="light_out";
mode_replace_table[ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT]["SHADOW"]="shadow_color";
diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl
index 285abd30ff..5f4767940d 100644
--- a/drivers/gles2/shaders/canvas.glsl
+++ b/drivers/gles2/shaders/canvas.glsl
@@ -244,7 +244,7 @@ FRAGMENT_SHADER_CODE
vec2 light_uv = light_uv_interp.xy;
vec4 light = texture2D(light_texture,light_uv) * light_color;
-#if defined(USE_LIGHT_SHADOW_COLOR)
+#if defined(USE_OUTPUT_SHADOW_COLOR)
vec4 shadow_color=vec4(0.0,0.0,0.0,0.0);
#endif
@@ -380,7 +380,7 @@ LIGHT_SHADER_CODE
#endif
-#if defined(USE_LIGHT_SHADOW_COLOR)
+#if defined(USE_OUTPUT_SHADOW_COLOR)
color=mix(shadow_color,color,shadow_attenuation);
#else
//color*=shadow_attenuation;
diff --git a/drivers/gles2/shaders/material.glsl b/drivers/gles2/shaders/material.glsl
index fd778f3442..477a451f2f 100644
--- a/drivers/gles2/shaders/material.glsl
+++ b/drivers/gles2/shaders/material.glsl
@@ -1185,7 +1185,7 @@ FRAGMENT_SHADER_CODE
vec3 mdiffuse = diffuse.rgb;
vec3 light;
-#if defined(USE_LIGHT_SHADOW_COLOR)
+#if defined(USE_OUTPUT_SHADOW_COLOR)
vec3 shadow_color=vec3(0.0,0.0,0.0);
#endif
@@ -1209,7 +1209,7 @@ LIGHT_SHADER_CODE
#endif
diffuse.rgb = const_light_mult * ambient_light *diffuse.rgb + light * attenuation * shadow_attenuation;
-#if defined(USE_LIGHT_SHADOW_COLOR)
+#if defined(USE_OUTPUT_SHADOW_COLOR)
diffuse.rgb += light * shadow_color * attenuation * (1.0 - shadow_attenuation);
#endif
diff --git a/drivers/vorbis/SCsub b/drivers/vorbis/SCsub
index 87805cc2d8..4afafcc4ba 100644
--- a/drivers/vorbis/SCsub
+++ b/drivers/vorbis/SCsub
@@ -5,7 +5,7 @@ sources = [
]
sources_lib = [
- "vorbis/analysis.c",
+ #"vorbis/analysis.c",
#"vorbis/barkmel.c",
"vorbis/bitrate.c",
"vorbis/block.c",
@@ -27,7 +27,7 @@ sources_lib = [
"vorbis/smallft.c",
"vorbis/synthesis.c",
#"vorbis/tone.c",
- "vorbis/vorbisenc.c",
+ #"vorbis/vorbisenc.c",
"vorbis/vorbisfile.c",
"vorbis/window.c",
]
diff --git a/main/input_default.cpp b/main/input_default.cpp
index 089772edc5..2020f7a5ad 100644
--- a/main/input_default.cpp
+++ b/main/input_default.cpp
@@ -849,6 +849,13 @@ uint32_t InputDefault::joy_axis(uint32_t p_last_id, int p_device, int p_axis, co
return p_last_id;
}
+ if (ABS(joy.last_axis[p_axis]) > 0.5 && joy.last_axis[p_axis] * p_value.value < 0) {
+ //changed direction quickly, insert fake event to release pending inputmap actions
+ JoyAxis jx;
+ jx.min = p_value.min;
+ jx.value = p_value.value < 0 ? 0.1 : -0.1;
+ p_last_id = joy_axis(p_last_id, p_device, p_axis, jx);
+ }
joy.last_axis[p_axis] = p_value.value;
float val = p_value.min == 0 ? -1.0f + 2.0f * p_value.value : p_value.value;
diff --git a/main/main.cpp b/main/main.cpp
index ec4386ab20..d2ba38b094 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -994,8 +994,11 @@ Error Main::setup2() {
}
}
#ifdef TOOLS_ENABLED
+ ObjectTypeDB::set_current_api(ObjectTypeDB::API_EDITOR);
EditorNode::register_editor_types();
ObjectTypeDB::register_type<PCKPacker>(); // todo: move somewhere else
+ ObjectTypeDB::set_current_api(ObjectTypeDB::API_CORE);
+
#endif
MAIN_PRINT("Main: Load Scripts, Modules, Drivers");
@@ -1022,6 +1025,8 @@ Error Main::setup2() {
_start_success=true;
locale=String();
+ ObjectTypeDB::set_current_api(ObjectTypeDB::API_NONE); //no more api is registered at this point
+
MAIN_PRINT("Main: Done");
return OK;
diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp
index e576aa10e0..f33faaabd8 100644
--- a/scene/2d/camera_2d.cpp
+++ b/scene/2d/camera_2d.cpp
@@ -44,6 +44,9 @@ void Camera2D::_update_scroll() {
}
if (current) {
+
+ ERR_FAIL_COND( custom_viewport && !ObjectDB::get_instance(custom_viewport_id) );
+
Matrix32 xform = get_camera_transform();
if (viewport) {
@@ -73,8 +76,9 @@ Matrix32 Camera2D::get_camera_transform() {
if (!get_tree())
return Matrix32();
- Size2 screen_size = get_viewport_rect().size;
- screen_size=get_viewport_rect().size;
+ ERR_FAIL_COND_V( custom_viewport && !ObjectDB::get_instance(custom_viewport_id), Matrix32() );
+
+ Size2 screen_size = viewport->get_visible_rect().size;
Point2 new_camera_pos = get_global_transform().get_origin();
@@ -240,14 +244,10 @@ void Camera2D::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE: {
- viewport = NULL;
- Node *n=this;
- while(n){
-
- viewport = n->cast_to<Viewport>();
- if (viewport)
- break;
- n=n->get_parent();
+ if (custom_viewport && ObjectDB::get_instance(custom_viewport_id)) {
+ viewport=custom_viewport;
+ } else {
+ viewport=get_viewport();
}
canvas = get_canvas();
@@ -270,8 +270,8 @@ void Camera2D::_notification(int p_what) {
} break;
case NOTIFICATION_EXIT_TREE: {
- if (is_current()) {
- if (viewport) {
+ if (is_current()) {
+ if (viewport && !(custom_viewport && !ObjectDB::get_instance(custom_viewport_id))) {
viewport->set_canvas_transform( Matrix32() );
}
}
@@ -447,8 +447,10 @@ void Camera2D::reset_smoothing() {
void Camera2D::align() {
- Size2 screen_size = get_viewport_rect().size;
- screen_size=get_viewport_rect().size;
+ ERR_FAIL_COND( custom_viewport && !ObjectDB::get_instance(custom_viewport_id) );
+
+ Size2 screen_size = viewport->get_visible_rect().size;
+
Point2 current_camera_pos = get_global_transform().get_origin();
if (anchor_mode==ANCHOR_MODE_DRAG_CENTER) {
if (h_ofs<0) {
@@ -549,6 +551,42 @@ bool Camera2D::is_follow_smoothing_enabled() const {
return smoothing_enabled;
}
+void Camera2D::set_custom_viewport(Node *p_viewport) {
+ ERR_FAIL_NULL(p_viewport);
+ if (is_inside_tree()) {
+ remove_from_group(group_name);
+ remove_from_group(canvas_group_name);
+ }
+
+ custom_viewport=p_viewport->cast_to<Viewport>();
+
+ if (custom_viewport) {
+ custom_viewport_id=custom_viewport->get_instance_ID();
+ } else {
+ custom_viewport_id=0;
+ }
+
+ if (is_inside_tree()) {
+
+ if (custom_viewport)
+ viewport=custom_viewport;
+ else
+ viewport=get_viewport();
+
+ RID vp = viewport->get_viewport();
+ group_name = "__cameras_"+itos(vp.get_id());
+ canvas_group_name ="__cameras_c"+itos(canvas.get_id());
+ add_to_group(group_name);
+ add_to_group(canvas_group_name);
+ }
+
+}
+
+Node* Camera2D::get_custom_viewport() const {
+
+ return custom_viewport;
+}
+
void Camera2D::_bind_methods() {
@@ -597,6 +635,8 @@ void Camera2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_zoom","zoom"),&Camera2D::set_zoom);
ObjectTypeDB::bind_method(_MD("get_zoom"),&Camera2D::get_zoom);
+ ObjectTypeDB::bind_method(_MD("set_custom_viewport","viewport:Viewport"),&Camera2D::set_custom_viewport);
+ ObjectTypeDB::bind_method(_MD("get_custom_viewport:Viewport"),&Camera2D::get_custom_viewport);
ObjectTypeDB::bind_method(_MD("set_follow_smoothing","follow_smoothing"),&Camera2D::set_follow_smoothing);
ObjectTypeDB::bind_method(_MD("get_follow_smoothing"),&Camera2D::get_follow_smoothing);
@@ -662,6 +702,8 @@ Camera2D::Camera2D() {
first=true;
smoothing_enabled=false;
limit_smoothing_enabled=false;
+ custom_viewport=NULL;
+ custom_viewport_id=0;
smoothing=5.0;
zoom = Vector2(1, 1);
diff --git a/scene/2d/camera_2d.h b/scene/2d/camera_2d.h
index 9f3e4254bb..a4d6dc5b96 100644
--- a/scene/2d/camera_2d.h
+++ b/scene/2d/camera_2d.h
@@ -48,6 +48,8 @@ protected:
Point2 smoothed_camera_pos;
bool first;
+ ObjectID custom_viewport_id; // to check validity
+ Viewport *custom_viewport;
Viewport *viewport;
StringName group_name;
@@ -128,6 +130,9 @@ public:
Point2 get_camera_screen_center() const;
+ void set_custom_viewport(Node *p_viewport);
+ Node* get_custom_viewport() const;
+
Vector2 get_camera_pos() const;
void force_update_scroll();
void reset_smoothing();
diff --git a/scene/main/canvas_layer.cpp b/scene/main/canvas_layer.cpp
index c31a57f819..8e238c7d77 100644
--- a/scene/main/canvas_layer.cpp
+++ b/scene/main/canvas_layer.cpp
@@ -168,20 +168,13 @@ void CanvasLayer::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE: {
- Node *n = this;
- vp=NULL;
+ if (custom_viewport && ObjectDB::get_instance(custom_viewport_id)) {
- while(n) {
+ vp=custom_viewport;
+ } else {
+ vp=Node::get_viewport();
- if (n->cast_to<Viewport>()) {
-
- vp = n->cast_to<Viewport>();
- break;
- }
- n=n->get_parent();
}
-
-
ERR_FAIL_COND(!vp);
viewport=vp->get_viewport();
@@ -205,6 +198,7 @@ Size2 CanvasLayer::get_viewport_size() const {
if (!is_inside_tree())
return Size2(1,1);
+
Rect2 r = vp->get_visible_rect();
return r.size;
}
@@ -215,6 +209,43 @@ RID CanvasLayer::get_viewport() const {
return viewport;
}
+void CanvasLayer::set_custom_viewport(Node *p_viewport) {
+ ERR_FAIL_NULL(p_viewport);
+ if (is_inside_tree()) {
+ VisualServer::get_singleton()->viewport_remove_canvas(viewport,canvas->get_canvas());
+ viewport=RID();
+ }
+
+ custom_viewport=p_viewport->cast_to<Viewport>();
+
+ if (custom_viewport) {
+ custom_viewport_id=custom_viewport->get_instance_ID();
+ } else {
+ custom_viewport_id=0;
+ }
+
+ if (is_inside_tree()) {
+
+
+ if (custom_viewport)
+ vp=custom_viewport;
+ else
+ vp=Node::get_viewport();
+
+ viewport = vp->get_viewport();
+
+ VisualServer::get_singleton()->viewport_attach_canvas(viewport,canvas->get_canvas());
+ VisualServer::get_singleton()->viewport_set_canvas_layer(viewport,canvas->get_canvas(),layer);
+ VisualServer::get_singleton()->viewport_set_canvas_transform(viewport,canvas->get_canvas(),transform);
+ }
+
+}
+
+Node* CanvasLayer::get_custom_viewport() const {
+
+ return custom_viewport;
+}
+
void CanvasLayer::_bind_methods() {
@@ -241,8 +272,11 @@ void CanvasLayer::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_scale","scale"),&CanvasLayer::set_scale);
ObjectTypeDB::bind_method(_MD("get_scale"),&CanvasLayer::get_scale);
+ ObjectTypeDB::bind_method(_MD("set_custom_viewport","viewport:Viewport"),&CanvasLayer::set_custom_viewport);
+ ObjectTypeDB::bind_method(_MD("get_custom_viewport:Viewport"),&CanvasLayer::get_custom_viewport);
+
ObjectTypeDB::bind_method(_MD("get_world_2d:World2D"),&CanvasLayer::get_world_2d);
- ObjectTypeDB::bind_method(_MD("get_viewport"),&CanvasLayer::get_viewport);
+// ObjectTypeDB::bind_method(_MD("get_viewport"),&CanvasLayer::get_viewport);
ADD_PROPERTY( PropertyInfo(Variant::INT,"layer",PROPERTY_HINT_RANGE,"-128,128,1"),_SCS("set_layer"),_SCS("get_layer") );
//ADD_PROPERTY( PropertyInfo(Variant::MATRIX32,"transform",PROPERTY_HINT_RANGE),_SCS("set_transform"),_SCS("get_transform") );
@@ -260,4 +294,6 @@ CanvasLayer::CanvasLayer() {
locrotscale_dirty=false;
layer=1;
canvas = Ref<World2D>( memnew(World2D) );
+ custom_viewport=NULL;
+ custom_viewport_id=0;
}
diff --git a/scene/main/canvas_layer.h b/scene/main/canvas_layer.h
index a3e8211a43..6aad90a09d 100644
--- a/scene/main/canvas_layer.h
+++ b/scene/main/canvas_layer.h
@@ -45,6 +45,10 @@ class CanvasLayer : public Node {
int layer;
Matrix32 transform;
Ref<World2D> canvas;
+
+ ObjectID custom_viewport_id; // to check validity
+ Viewport *custom_viewport;
+
RID viewport;
Viewport *vp;
@@ -55,6 +59,7 @@ class CanvasLayer : public Node {
void _update_xform();
void _update_locrotscale();
+
protected:
void _notification(int p_what);
@@ -85,6 +90,9 @@ public:
RID get_viewport() const;
+ void set_custom_viewport(Node *p_viewport);
+ Node* get_custom_viewport() const;
+
CanvasLayer();
};
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 347d72aecd..b22d1fcdf4 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -359,13 +359,7 @@ void Viewport::_notification(int p_what) {
_update_listener_2d();
_update_rect();
- if (world_2d.is_valid()) {
- find_world_2d()->_register_viewport(this,Rect2());
-//best to defer this and not do it here, as it can annoy a lot of setup logic if user
-//adds a node and then moves it, will get enter/exit screen/viewport notifications
-//unnecesarily
-// update_worlds();
- }
+ find_world_2d()->_register_viewport(this,Rect2());
add_to_group("_viewports");
if (get_tree()->is_debugging_collisions_hint()) {
@@ -1001,19 +995,34 @@ bool Viewport::has_transparent_background() const {
return transparent_bg;
}
-#if 0
void Viewport::set_world_2d(const Ref<World2D>& p_world_2d) {
+ if (world_2d==p_world_2d)
+ return;
+
+ if (parent && parent->find_world_2d()==p_world_2d) {
+ WARN_PRINT("Unable to use parent world as world_2d");
+ return;
+ }
+
+ if (is_inside_tree()) {
+ find_world_2d()->_remove_viewport(this);
+ VisualServer::get_singleton()->viewport_remove_canvas(viewport,current_canvas);
+ }
+
+ if (p_world_2d.is_valid())
+ world_2d=p_world_2d;
+ else {
+ WARN_PRINT("Invalid world");
+ world_2d=Ref<World2D>( memnew( World2D ));
+ }
- world_2d=p_world_2d;
_update_listener_2d();
- if (is_inside_scene()) {
- if (current_canvas.is_valid())
- VisualServer::get_singleton()->viewport_remove_canvas(viewport,current_canvas);
+ if (is_inside_tree()) {
current_canvas=find_world_2d()->get_canvas();
VisualServer::get_singleton()->viewport_attach_canvas(viewport,current_canvas);
+ find_world_2d()->_register_viewport(this,Rect2());
}
-
}
Ref<World2D> Viewport::find_world_2d() const{
@@ -1025,13 +1034,6 @@ Ref<World2D> Viewport::find_world_2d() const{
else
return Ref<World2D>();
}
-#endif
-
-Ref<World2D> Viewport::find_world_2d() const{
-
- return world_2d;
-}
-
void Viewport::_propagate_enter_world(Node *p_node) {
@@ -1141,6 +1143,11 @@ Ref<World> Viewport::get_world() const{
return world;
}
+Ref<World2D> Viewport::get_world_2d() const{
+
+ return world_2d;
+}
+
Ref<World> Viewport::find_world() const{
if (own_world.is_valid())
@@ -1303,6 +1310,9 @@ void Viewport::render_target_clear() {
void Viewport::set_render_target_filter(bool p_enable) {
+ if(!render_target)
+ return;
+
render_target_texture->set_flags(p_enable?int(Texture::FLAG_FILTER):int(0));
}
@@ -2587,8 +2597,8 @@ void Viewport::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_rect","rect"), &Viewport::set_rect);
ObjectTypeDB::bind_method(_MD("get_rect"), &Viewport::get_rect);
- //ObjectTypeDB::bind_method(_MD("set_world_2d","world_2d:World2D"), &Viewport::set_world_2d);
- //ObjectTypeDB::bind_method(_MD("get_world_2d:World2D"), &Viewport::get_world_2d);
+ ObjectTypeDB::bind_method(_MD("set_world_2d","world_2d:World2D"), &Viewport::set_world_2d);
+ ObjectTypeDB::bind_method(_MD("get_world_2d:World2D"), &Viewport::get_world_2d);
ObjectTypeDB::bind_method(_MD("find_world_2d:World2D"), &Viewport::find_world_2d);
ObjectTypeDB::bind_method(_MD("set_world","world:World"), &Viewport::set_world);
ObjectTypeDB::bind_method(_MD("get_world:World"), &Viewport::get_world);
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index 145f642fd3..f657f0507d 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -305,9 +305,11 @@ public:
RID get_viewport() const;
void set_world(const Ref<World>& p_world);
+ void set_world_2d(const Ref<World2D>& p_world_2d);
Ref<World> get_world() const;
Ref<World> find_world() const;
+ Ref<World2D> get_world_2d() const;
Ref<World2D> find_world_2d() const;
diff --git a/scene/resources/shader_graph.cpp b/scene/resources/shader_graph.cpp
index 40ae26ba5d..02faa9425d 100644
--- a/scene/resources/shader_graph.cpp
+++ b/scene/resources/shader_graph.cpp
@@ -1483,6 +1483,8 @@ const ShaderGraph::InOutParamInfo ShaderGraph::inout_param_info[]={
{MODE_CANVAS_ITEM,SHADER_TYPE_LIGHT,"LightColor","LIGHT_COLOR.rgb","",SLOT_TYPE_VEC,SLOT_IN},
{MODE_CANVAS_ITEM,SHADER_TYPE_LIGHT,"LightAlpha","LIGHT_COLOR.a","",SLOT_TYPE_SCALAR,SLOT_IN},
{MODE_CANVAS_ITEM,SHADER_TYPE_LIGHT,"LightHeight","LIGHT_HEIGHT","",SLOT_TYPE_SCALAR,SLOT_IN},
+ {MODE_CANVAS_ITEM,SHADER_TYPE_LIGHT,"ShadowColor","LIGHT_SHADOW.rgb","",SLOT_TYPE_VEC,SLOT_IN},
+ {MODE_CANVAS_ITEM,SHADER_TYPE_LIGHT,"ShadowAlpha","LIGHT_SHADOW.a","",SLOT_TYPE_SCALAR,SLOT_IN},
{MODE_CANVAS_ITEM,SHADER_TYPE_LIGHT,"TexPixelSize","vec3(TEXTURE_PIXEL_SIZE,0)","",SLOT_TYPE_VEC,SLOT_IN},
{MODE_CANVAS_ITEM,SHADER_TYPE_LIGHT,"Var1","VAR1.rgb","",SLOT_TYPE_VEC,SLOT_IN},
{MODE_CANVAS_ITEM,SHADER_TYPE_LIGHT,"Var2","VAR2.rgb","",SLOT_TYPE_VEC,SLOT_IN},
@@ -1490,6 +1492,8 @@ const ShaderGraph::InOutParamInfo ShaderGraph::inout_param_info[]={
//canvas item light out
{MODE_CANVAS_ITEM,SHADER_TYPE_LIGHT,"LightColor","LIGHT.rgb","",SLOT_TYPE_VEC,SLOT_OUT},
{MODE_CANVAS_ITEM,SHADER_TYPE_LIGHT,"LightAlpha","LIGHT.a","",SLOT_TYPE_SCALAR,SLOT_OUT},
+ {MODE_CANVAS_ITEM,SHADER_TYPE_LIGHT,"ShadowColor","SHADOW.rgb","",SLOT_TYPE_VEC,SLOT_OUT},
+ {MODE_CANVAS_ITEM,SHADER_TYPE_LIGHT,"ShadowAlpha","SHADOW.a","",SLOT_TYPE_SCALAR,SLOT_OUT},
//end
{MODE_MATERIAL,SHADER_TYPE_FRAGMENT,NULL,NULL,NULL,SLOT_TYPE_SCALAR,SLOT_OUT},
diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp
index 09b3ada509..fdf3cb622d 100644
--- a/servers/visual/shader_language.cpp
+++ b/servers/visual/shader_language.cpp
@@ -1180,6 +1180,7 @@ const ShaderLanguage::BuiltinsDef ShaderLanguage::ci_light_builtins_defs[]={
{ "LIGHT_HEIGHT", TYPE_FLOAT},
{ "LIGHT_COLOR", TYPE_VEC4},
{ "LIGHT_UV", TYPE_VEC2},
+ { "LIGHT_SHADOW", TYPE_VEC4},
{ "LIGHT", TYPE_VEC4},
{ "SHADOW", TYPE_VEC4},
{ "POINT_COORD", TYPE_VEC2},
diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp
index dd84b30add..0e4a2fe30b 100644
--- a/tools/editor/editor_node.cpp
+++ b/tools/editor/editor_node.cpp
@@ -1217,6 +1217,7 @@ void EditorNode::_dialog_action(String p_file) {
//_save_scene(p_file);
_save_scene_with_preview(p_file);
+ _call_build();
_run(true);
}
} break;
@@ -2636,6 +2637,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
} break;
case RUN_PLAY: {
_menu_option_confirm(RUN_STOP,true);
+ _call_build();
_run(false);
} break;
@@ -2671,6 +2673,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
} break;
case RUN_PLAY_SCENE: {
_menu_option_confirm(RUN_STOP,true);
+ _call_build();
_run(true);
} break;
@@ -2682,6 +2685,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
}
if (run_native->is_deploy_debug_remote_enabled()){
_menu_option_confirm(RUN_STOP,true);
+ _call_build();
emit_signal("play_pressed");
editor_run.run_native_notify();
}
@@ -3012,7 +3016,7 @@ void EditorNode::remove_editor_plugin(EditorPlugin *p_editor) {
for(int i=0;i<singleton->main_editor_buttons.size();i++) {
- if (p_editor->get_name()==singleton->main_editor_buttons[i]->get_name()) {
+ if (p_editor->get_name()==singleton->main_editor_buttons[i]->get_text()) {
memdelete( singleton->main_editor_buttons[i] );
singleton->main_editor_buttons.remove(i);
@@ -4042,6 +4046,7 @@ void EditorNode::_quick_opened() {
void EditorNode::_quick_run() {
+ _call_build();
_run(false,quick_run->get_selected());
}
@@ -5244,6 +5249,24 @@ void EditorNode::add_plugin_init_callback(EditorPluginInitializeCallback p_callb
EditorPluginInitializeCallback EditorNode::plugin_init_callbacks[EditorNode::MAX_INIT_CALLBACKS];
+int EditorNode::build_callback_count=0;
+
+void EditorNode::add_build_callback(EditorBuildCallback p_callback) {
+
+ ERR_FAIL_COND(build_callback_count==MAX_INIT_CALLBACKS);
+
+ build_callbacks[build_callback_count++]=p_callback;
+}
+
+EditorPluginInitializeCallback EditorNode::build_callbacks[EditorNode::MAX_BUILD_CALLBACKS];
+
+void EditorNode::_call_build() {
+
+ for(int i=0;i<build_callback_count;i++) {
+ build_callbacks[i]();
+ }
+}
+
void EditorNode::_bind_methods() {
diff --git a/tools/editor/editor_node.h b/tools/editor/editor_node.h
index 96242a144d..2fae5daced 100644
--- a/tools/editor/editor_node.h
+++ b/tools/editor/editor_node.h
@@ -95,6 +95,7 @@
typedef void (*EditorNodeInitCallback)();
typedef void (*EditorPluginInitializeCallback)();
+typedef void (*EditorBuildCallback)();
class EditorPluginList;
@@ -580,13 +581,18 @@ private:
void _toggle_distraction_free_mode();
enum {
- MAX_INIT_CALLBACKS=128
+ MAX_INIT_CALLBACKS=128,
+ MAX_BUILD_CALLBACKS=128
};
static int plugin_init_callback_count;
static EditorPluginInitializeCallback plugin_init_callbacks[MAX_INIT_CALLBACKS];
+
+ void _call_build();
+ static int build_callback_count;
+ static EditorBuildCallback build_callbacks[MAX_BUILD_CALLBACKS];
protected:
void _notification(int p_what);
static void _bind_methods();
@@ -754,6 +760,7 @@ public:
void get_singleton(const char* arg1, bool arg2);
static void add_init_callback(EditorNodeInitCallback p_callback) { _init_callbacks.push_back(p_callback); }
+ static void add_build_callback(EditorBuildCallback p_callback);
diff --git a/tools/editor/editor_plugin.cpp b/tools/editor/editor_plugin.cpp
index 55f0e52c88..4b82d5e59c 100644
--- a/tools/editor/editor_plugin.cpp
+++ b/tools/editor/editor_plugin.cpp
@@ -71,6 +71,11 @@ void EditorPlugin::remove_control_from_bottom_panel(Control *p_control) {
}
+Control * EditorPlugin::get_editor_viewport() {
+
+ return EditorNode::get_singleton()->get_viewport();
+}
+
void EditorPlugin::add_control_to_container(CustomControlContainer p_location,Control *p_control) {
switch(p_location) {
@@ -315,6 +320,16 @@ Control *EditorPlugin::get_base_control() {
return EditorNode::get_singleton()->get_gui_base();
}
+void EditorPlugin::make_bottom_panel_item_visible(Control * p_item) {
+
+ EditorNode::get_singleton()->make_bottom_panel_item_visible(p_item);
+}
+
+void EditorPlugin::hide_bottom_panel() {
+
+ EditorNode::get_singleton()->hide_bottom_panel();
+}
+
void EditorPlugin::inspect_object(Object *p_obj,const String& p_for_property) {
EditorNode::get_singleton()->push_item(p_obj,p_for_property);
@@ -333,6 +348,7 @@ void EditorPlugin::_bind_methods() {
ObjectTypeDB::bind_method(_MD("remove_control_from_bottom_panel","control:Control"),&EditorPlugin::remove_control_from_bottom_panel);
ObjectTypeDB::bind_method(_MD("add_custom_type","type","base","script:Script","icon:Texture"),&EditorPlugin::add_custom_type);
ObjectTypeDB::bind_method(_MD("remove_custom_type","type"),&EditorPlugin::remove_custom_type);
+ ObjectTypeDB::bind_method(_MD("get_editor_viewport:Control"), &EditorPlugin::get_editor_viewport);
ObjectTypeDB::bind_method(_MD("add_import_plugin","plugin:EditorImportPlugin"),&EditorPlugin::add_import_plugin);
ObjectTypeDB::bind_method(_MD("remove_import_plugin","plugin:EditorImportPlugin"),&EditorPlugin::remove_import_plugin);
@@ -346,6 +362,9 @@ void EditorPlugin::_bind_methods() {
ObjectTypeDB::bind_method(_MD("inspect_object","object","for_property"),&EditorPlugin::inspect_object,DEFVAL(String()));
ObjectTypeDB::bind_method(_MD("update_canvas"),&EditorPlugin::update_canvas);
+ ObjectTypeDB::bind_method(_MD("make_bottom_panel_item_visible","item:Control"), &EditorPlugin::make_bottom_panel_item_visible);
+ ObjectTypeDB::bind_method(_MD("hide_bottom_panel"), &EditorPlugin::hide_bottom_panel);
+
ObjectTypeDB::bind_method(_MD("get_base_control:Control"),&EditorPlugin::get_base_control);
ObjectTypeDB::bind_method(_MD("get_undo_redo:UndoRedo"),&EditorPlugin::_get_undo_redo);
ObjectTypeDB::bind_method(_MD("get_selection:EditorSelection"),&EditorPlugin::get_selection);
diff --git a/tools/editor/editor_plugin.h b/tools/editor/editor_plugin.h
index 5b944cc27a..2700c49a6c 100644
--- a/tools/editor/editor_plugin.h
+++ b/tools/editor/editor_plugin.h
@@ -100,6 +100,7 @@ public:
void add_control_to_dock(DockSlot p_slot,Control *p_control);
void remove_control_from_docks(Control *p_control);
void remove_control_from_bottom_panel(Control *p_control);
+ Control* get_editor_viewport();
virtual Ref<SpatialEditorGizmo> create_spatial_gizmo(Spatial* p_spatial);
virtual bool forward_canvas_input_event(const Matrix32& p_canvas_xform, const InputEvent& p_event);
@@ -130,6 +131,9 @@ public:
Control *get_base_control();
+ void make_bottom_panel_item_visible(Control *p_item);
+ void hide_bottom_panel();
+
void add_import_plugin(const Ref<EditorImportPlugin>& p_editor_import);
void remove_import_plugin(const Ref<EditorImportPlugin>& p_editor_import);
diff --git a/tools/editor/plugins/script_editor_plugin.cpp b/tools/editor/plugins/script_editor_plugin.cpp
index 522ceba1dc..fd25843de9 100644
--- a/tools/editor/plugins/script_editor_plugin.cpp
+++ b/tools/editor/plugins/script_editor_plugin.cpp
@@ -1362,10 +1362,8 @@ struct _ScriptEditorItemData {
void ScriptEditor::_update_script_colors() {
- bool enabled = EditorSettings::get_singleton()->get("text_editor/script_temperature_enabled");
+ bool script_temperature_enabled = EditorSettings::get_singleton()->get("text_editor/script_temperature_enabled");
bool highlight_current = EditorSettings::get_singleton()->get("text_editor/highlight_current_script");
- if (!enabled)
- return;
int hist_size = EditorSettings::get_singleton()->get("text_editor/script_temperature_history_size");
Color hot_color=EditorSettings::get_singleton()->get("text_editor/script_temperature_hot_color");
@@ -1379,22 +1377,25 @@ void ScriptEditor::_update_script_colors() {
continue;
script_list->set_item_custom_bg_color(i,Color(0,0,0,0));
- if (!n->has_meta("__editor_pass")) {
- continue;
- }
-
- int pass=n->get_meta("__editor_pass");
- int h = edit_pass - pass;
- if (h>hist_size) {
- continue;
- }
- int non_zero_hist_size = ( hist_size == 0 ) ? 1 : hist_size;
- float v = Math::ease((edit_pass-pass)/float(non_zero_hist_size),0.4);
bool current = tab_container->get_current_tab() == c;
if (current && highlight_current) {
script_list->set_item_custom_bg_color(i, EditorSettings::get_singleton()->get("text_editor/current_script_background_color"));
- } else {
+
+ } else if (script_temperature_enabled) {
+
+ if (!n->has_meta("__editor_pass")) {
+ continue;
+ }
+
+ int pass=n->get_meta("__editor_pass");
+ int h = edit_pass - pass;
+ if (h>hist_size) {
+ continue;
+ }
+ int non_zero_hist_size = ( hist_size == 0 ) ? 1 : hist_size;
+ float v = Math::ease((edit_pass-pass)/float(non_zero_hist_size),0.4);
+
script_list->set_item_custom_bg_color(i,hot_color.linear_interpolate(cold_color,v));
}
}
diff --git a/tools/editor/plugins/shader_graph_editor_plugin.cpp b/tools/editor/plugins/shader_graph_editor_plugin.cpp
index aa66a2e0d9..3ab906f84e 100644
--- a/tools/editor/plugins/shader_graph_editor_plugin.cpp
+++ b/tools/editor/plugins/shader_graph_editor_plugin.cpp
@@ -2422,6 +2422,7 @@ void ShaderGraphView::_create_node(int p_id) {
colors.push_back("Color");
colors.push_back("LightColor");
colors.push_back("Light");
+ colors.push_back("ShadowColor");
colors.push_back("Diffuse");
colors.push_back("Specular");
colors.push_back("Emmision");
@@ -2434,6 +2435,7 @@ void ShaderGraphView::_create_node(int p_id) {
reals.push_back("ShadeParam");
reals.push_back("SpecularExp");
reals.push_back("LightAlpha");
+ reals.push_back("ShadowAlpha");
reals.push_back("PointSize");
reals.push_back("Discard");