diff options
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");  |