diff options
43 files changed, 632 insertions, 171 deletions
diff --git a/SConstruct b/SConstruct index fc9c7dca35..42e9085171 100644 --- a/SConstruct +++ b/SConstruct @@ -6,7 +6,6 @@ import os.path import glob import sys import methods -import multiprocessing methods.update_version() diff --git a/core/io/resource_format_xml.cpp b/core/io/resource_format_xml.cpp index 2a79e6647d..75384d4ab6 100644 --- a/core/io/resource_format_xml.cpp +++ b/core/io/resource_format_xml.cpp @@ -193,6 +193,7 @@ Error ResourceInteractiveLoaderXML::close_tag(const String& p_name) { void ResourceInteractiveLoaderXML::unquote(String& p_str) { + p_str=p_str.strip_edges().replace("\"","").xml_unescape(); /*p_str=p_str.strip_edges(); @@ -1851,7 +1852,10 @@ void ResourceFormatSaverXMLInstance::escape(String& p_str) { for (int i=1;i<32;i++) { char chr[2]={i,0}; - p_str=p_str.replace(chr,"&#"+String::num(i)+";"); + const char hexn[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; + const char hex[8]={'&','#','0','0',hexn[i>>4],hexn[i&0xf],';',0}; + + p_str=p_str.replace(chr,hex); } diff --git a/demos/3d/truck_town/crane.scn b/demos/3d/truck_town/crane.scn Binary files differindex 080bd8ea17..2c4645af69 100644 --- a/demos/3d/truck_town/crane.scn +++ b/demos/3d/truck_town/crane.scn diff --git a/demos/misc/tween/icon.png b/demos/misc/tween/icon.png Binary files differnew file mode 100644 index 0000000000..3e991fcc29 --- /dev/null +++ b/demos/misc/tween/icon.png diff --git a/doc/base/classes.xml b/doc/base/classes.xml index 2c49926d66..35de0106b5 100644 --- a/doc/base/classes.xml +++ b/doc/base/classes.xml @@ -3281,6 +3281,12 @@ <description> </description> </method> + <method name="get_overlapping_bodies" qualifiers="const" > + <return type="Array"> + </return> + <description> + </description> + </method> </methods> <signals> <signal name="body_enter"> @@ -3418,6 +3424,12 @@ <description> </description> </method> + <method name="get_overlapping_bodies" qualifiers="const" > + <return type="Array"> + </return> + <description> + </description> + </method> </methods> <signals> <signal name="body_enter"> @@ -4828,6 +4840,10 @@ </method> </methods> <signals> + <signal name="released"> + <description> + </description> + </signal> <signal name="toggled"> <argument index="0" name="pressed" type="bool"> </argument> @@ -11647,6 +11663,14 @@ <description> </description> </method> + <method name="save_png" > + <return type="int"> + </return> + <argument index="0" name="path" type="String" default="0"> + </argument> + <description> + </description> + </method> </methods> <constants> <constant name="COMPRESS_BC" value="0"> @@ -15474,14 +15498,12 @@ Finally, when a node is freed, it will free all its children nodes too. </description> <methods> - <method name="_enter_scene" qualifiers="virtual" > + <method name="_enter_tree" qualifiers="virtual" > <description> - Called when entered the scene. </description> </method> - <method name="_exit_scene" qualifiers="virtual" > + <method name="_exit_tree" qualifiers="virtual" > <description> - Called when being removed from the scene. </description> </method> <method name="_fixed_process" qualifiers="virtual" > @@ -15634,11 +15656,10 @@ <description> </description> </method> - <method name="is_inside_scene" qualifiers="const" > + <method name="is_inside_tree" qualifiers="const" > <return type="bool"> </return> <description> - Return wether the node is inside a scene tree (a tree where the topmost node is a [RootNode]) </description> </method> <method name="is_a_parent_of" qualifiers="const" > @@ -15882,11 +15903,10 @@ <description> </description> </method> - <method name="get_scene" qualifiers="const" > - <return type="SceneMainLoop"> + <method name="get_tree" qualifiers="const" > + <return type="SceneTree"> </return> <description> - Get the current SceneMainLoop. Only returned if the node is inside the scene, else returns null. </description> </method> <method name="duplicate" qualifiers="const" > @@ -15917,28 +15937,24 @@ </method> </methods> <signals> - <signal name="enter_scene"> + <signal name="renamed"> <description> - Emitted when the node enters the scene. + Emitted when the node is renamed. </description> </signal> - <signal name="renamed"> + <signal name="enter_tree"> <description> - Emitted when the node is renamed. </description> </signal> - <signal name="exit_scene"> + <signal name="exit_tree"> <description> - Emitted when the node exits the scene. </description> </signal> </signals> <constants> - <constant name="NOTIFICATION_ENTER_SCENE" value="10"> - Notification received when the node enters the Scene Tree and gains access to the [RootNode]. Note that children nodes will not have received the notification at that time yet. + <constant name="NOTIFICATION_ENTER_TREE" value="10"> </constant> - <constant name="NOTIFICATION_EXIT_SCENE" value="11"> - Notification received when the node exits the Scene Tree and loses access to the [RootNode]. Note that parent nodes will not have received the notification at that time yet. + <constant name="NOTIFICATION_EXIT_TREE" value="11"> </constant> <constant name="NOTIFICATION_MOVED_IN_PARENT" value="12"> </constant> @@ -16554,6 +16570,10 @@ </argument> <argument index="1" name="arg1" type="float"> </argument> + <argument index="2" name="arg2" type="int"> + </argument> + <argument index="3" name="arg3" type="int"> + </argument> <description> </description> </method> @@ -17334,7 +17354,7 @@ <method name="put_var" > <return type="int"> </return> - <argument index="0" name="var" type="Variant"> + <argument index="0" name="var" type="var"> </argument> <description> </description> @@ -17368,6 +17388,70 @@ <constants> </constants> </class> +<class name="PacketPeerUDP" inherits="PacketPeer" category="Core"> + <brief_description> + </brief_description> + <description> + </description> + <methods> + <method name="listen" > + <return type="int"> + </return> + <argument index="0" name="port" type="int"> + </argument> + <argument index="1" name="recv_buf_size" type="int" default="65536"> + </argument> + <description> + </description> + </method> + <method name="close" > + <description> + </description> + </method> + <method name="wait" > + <return type="int"> + </return> + <description> + </description> + </method> + <method name="is_listening" qualifiers="const" > + <return type="bool"> + </return> + <description> + </description> + </method> + <method name="get_packet_ip" qualifiers="const" > + <return type="String"> + </return> + <description> + </description> + </method> + <method name="get_packet_address" qualifiers="const" > + <return type="int"> + </return> + <description> + </description> + </method> + <method name="get_packet_port" qualifiers="const" > + <return type="int"> + </return> + <description> + </description> + </method> + <method name="set_send_address" > + <return type="int"> + </return> + <argument index="0" name="host" type="String"> + </argument> + <argument index="1" name="port" type="int"> + </argument> + <description> + </description> + </method> + </methods> + <constants> + </constants> +</class> <class name="Panel" inherits="Control" category="Core"> <brief_description> Provides an opaque background for [Control] children. @@ -18039,6 +18123,30 @@ <description> </description> </method> + <method name="set_h_frames" > + <argument index="0" name="enable" type="int"> + </argument> + <description> + </description> + </method> + <method name="get_h_frames" qualifiers="const" > + <return type="int"> + </return> + <description> + </description> + </method> + <method name="set_v_frames" > + <argument index="0" name="enable" type="int"> + </argument> + <description> + </description> + </method> + <method name="get_v_frames" qualifiers="const" > + <return type="int"> + </return> + <description> + </description> + </method> <method name="set_emission_half_extents" > <argument index="0" name="extents" type="Vector2"> </argument> @@ -18173,7 +18281,7 @@ </constant> <constant name="PARAM_HUE_VARIATION" value="13"> </constant> - <constant name="PARAM_MAX" value="14"> + <constant name="PARAM_MAX" value="16"> </constant> <constant name="MAX_COLOR_PHASES" value="4"> </constant> @@ -19534,7 +19642,7 @@ <description> </description> </method> - <method name="free" > + <method name="free_rid" > <argument index="0" name="rid" type="RID"> </argument> <description> @@ -20994,7 +21102,7 @@ <description> </description> </method> - <method name="free" > + <method name="free_rid" > <argument index="0" name="rid" type="RID"> </argument> <description> @@ -24091,6 +24199,12 @@ <description> </description> </method> + <method name="get_colliding_bodies" qualifiers="const" > + <return type="Array"> + </return> + <description> + </description> + </method> </methods> <signals> <signal name="body_enter"> @@ -24364,6 +24478,12 @@ Return true if the body has the ability to fall asleep when not moving. See [set_can_sleep]. </description> </method> + <method name="get_colliding_bodies" qualifiers="const" > + <return type="Array"> + </return> + <description> + </description> + </method> </methods> <signals> <signal name="body_enter"> @@ -25275,13 +25395,10 @@ </constant> </constants> </class> -<class name="SceneMainLoop" inherits="MainLoop" category="Core"> +<class name="SceneTree" inherits="MainLoop" category="Core"> <brief_description> - Scene-Based implementation of the MainLoop. </brief_description> <description> - Scene implementation of the MainLoop. All scenes edited using the editor are loaded with this main loop, which provides the base for the scene system.[br] - All group operations (get nodes, call, etc) is performed here. All nodes in a group can be called a specific functions, set a property or notified. This happens in scene-order. </description> <methods> <method name="notify_group" > @@ -25292,7 +25409,6 @@ <argument index="2" name="notification" type="int"> </argument> <description> - Call a notification in all the nodes belonging to a given group. See GROUP_CALL_* enum for options. </description> </method> <method name="set_group" > @@ -25305,7 +25421,6 @@ <argument index="3" name="value" type="var"> </argument> <description> - Set a property in all the nodes belonging to a given group. See GROUP_CALL_* enum for options. </description> </method> <method name="get_nodes_in_group" > @@ -25314,7 +25429,6 @@ <argument index="0" name="arg0" type="String"> </argument> <description> - Get all the nods belonging to a given group. </description> </method> <method name="get_root" qualifiers="const" > @@ -25327,21 +25441,18 @@ <argument index="0" name="enabled" type="bool"> </argument> <description> - Set to true if the application will quit automatically when quit is requested (Alt-f4 or ctrl-c). </description> </method> <method name="set_editor_hint" > <argument index="0" name="enable" type="bool"> </argument> <description> - Set to true to tell nodes and the scene that it is being edited. This is used by editors, not release. </description> </method> <method name="is_editor_hint" qualifiers="const" > <return type="bool"> </return> <description> - Return true if the scene is being run inside an editor. </description> </method> <method name="set_edited_scene_root" > @@ -25360,19 +25471,16 @@ <argument index="0" name="enable" type="bool"> </argument> <description> - Set pause. The built-in pause system is very basic and only meant to avoid processing nodes not allowed to work in pause mode. </description> </method> <method name="is_paused" qualifiers="const" > <return type="bool"> </return> <description> - Return true if the scene is paused. </description> </method> <method name="set_input_as_handled" > <description> - Handle a current input event (avoid further processing of it). </description> </method> <method name="get_node_count" qualifiers="const" > @@ -25385,12 +25493,10 @@ <return type="int"> </return> <description> - Return the frame index (how many frames were drawn). </description> </method> <method name="quit" > <description> - Quit the application. </description> </method> <method name="set_screen_stretch" > @@ -25407,7 +25513,6 @@ <argument index="0" name="obj" type="Object"> </argument> <description> - Queue an object for deletion next time the loop goes idle. </description> </method> <method name="call_group" > @@ -25428,41 +25533,33 @@ <argument index="7" name="arg4" type="var" default="NULL"> </argument> <description> - Call a function for all the nodes in a given group. </description> </method> </methods> <signals> <signal name="screen_resized"> <description> - Emitted when the screen changes size. </description> </signal> <signal name="node_removed"> <argument index="0" name="node" type="Object"> </argument> <description> - Emitted when a node is removed from the scene. </description> </signal> <signal name="tree_changed"> <description> - Emitted when the scene tree changed (nodes added/removed/moved/etc) </description> </signal> </signals> <constants> <constant name="GROUP_CALL_DEFAULT" value="0"> - Regular group call flag (no flags). </constant> <constant name="GROUP_CALL_REVERSE" value="1"> - Call a group in inverse-scene order. </constant> <constant name="GROUP_CALL_REALTIME" value="2"> - Call a group immediately (usually calls are delivered on idle). </constant> <constant name="GROUP_CALL_UNIQUE" value="4"> - Call a group only once, even if call is performed many times. </constant> <constant name="STRETCH_MODE_DISABLED" value="0"> </constant> @@ -32543,7 +32640,7 @@ <description> </description> </method> - <method name="get_pos" qualifiers="const" > + <method name="get_stream_pos" qualifiers="const" > <return type="float"> </return> <description> @@ -32601,6 +32698,12 @@ <description> </description> </method> + <method name="set_audio_track" > + <argument index="0" name="idx" type="int"> + </argument> + <description> + </description> + </method> </methods> <constants> </constants> diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index 057de329df..9f2fd032fa 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -4648,7 +4648,8 @@ void RasterizerGLES2::_add_geometry( const Geometry* p_geometry, const InstanceD if (m->flags[VS::MATERIAL_FLAG_INVERT_FACES]) e->mirror=!e->mirror; - e->light_type=0xFF; // no lights! + //e->light_type=0xFF; // no lights! + e->light_type=3; //light type 3 is no light? e->light=0xFFFF; if (!shadow && !has_blend_alpha && has_alpha && m->depth_draw_mode==VS::MATERIAL_DEPTH_DRAW_OPAQUE_PRE_PASS_ALPHA) { @@ -9122,6 +9123,7 @@ void RasterizerGLES2::init() { use_anisotropic_filter=true; float_linear_supported=true; float_supported=true; + use_rgba_shadowmaps=false; glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT,&anisotropic_level); anisotropic_level=MIN(anisotropic_level,float(GLOBAL_DEF("rasterizer/anisotropic_filter_level",4.0))); diff --git a/drivers/gles2/shaders/material.glsl b/drivers/gles2/shaders/material.glsl index 7d9aca4b4d..f2d9eaf1e5 100644 --- a/drivers/gles2/shaders/material.glsl +++ b/drivers/gles2/shaders/material.glsl @@ -1214,7 +1214,7 @@ LIGHT_SHADER_CODE # if !defined(LIGHT_TYPE_DIRECTIONAL) && !defined(LIGHT_TYPE_OMNI) && !defined (LIGHT_TYPE_SPOT) //none #ifndef SHADELESS - diffuse.rgb=vec3(0.0,0.0,0.0); + diffuse.rgb=ambient_light *diffuse.rgb; #endif # endif diff --git a/modules/gdscript/gd_editor.cpp b/modules/gdscript/gd_editor.cpp index b1db087fb3..95bae2d32a 100644 --- a/modules/gdscript/gd_editor.cpp +++ b/modules/gdscript/gd_editor.cpp @@ -66,7 +66,7 @@ bool GDScriptLanguage::validate(const String& p_script, int &r_line_error,int &r GDParser parser; - Error err = parser.parse(p_script,p_path.get_base_dir(),true); + Error err = parser.parse(p_script,p_path.get_base_dir(),true,p_path); if (err) { r_line_error=parser.get_error_line(); r_col_error=parser.get_error_column(); diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp index de2b5219a9..904b6ba52f 100644 --- a/modules/gdscript/gd_parser.cpp +++ b/modules/gdscript/gd_parser.cpp @@ -225,7 +225,14 @@ GDParser::Node* GDParser::_parse_expression(Node *p_parent,bool p_static,bool p_ String path = tokenizer->get_token_constant(); if (!path.is_abs_path() && base_path!="") path=base_path+"/"+path; - path = path.replace("///","//"); + path = path.replace("///","//").simplify_path(); + if (path==self_path) { + + _set_error("Can't preload itself (use 'get_script()')."); + return NULL; + + } + Ref<Resource> res; if (!validating) { @@ -2616,8 +2623,9 @@ Error GDParser::_parse(const String& p_base_path) { return OK; } -Error GDParser::parse_bytecode(const Vector<uint8_t> &p_bytecode,const String& p_base_path) { +Error GDParser::parse_bytecode(const Vector<uint8_t> &p_bytecode,const String& p_base_path, const String &p_self_path) { + self_path=p_self_path; GDTokenizerBuffer *tb = memnew( GDTokenizerBuffer ); tb->set_code_buffer(p_bytecode); tokenizer=tb; @@ -2628,9 +2636,9 @@ Error GDParser::parse_bytecode(const Vector<uint8_t> &p_bytecode,const String& p } -Error GDParser::parse(const String& p_code,const String& p_base_path,bool p_just_validate) { - +Error GDParser::parse(const String& p_code, const String& p_base_path, bool p_just_validate, const String &p_self_path) { + self_path=p_self_path; GDTokenizerText *tt = memnew( GDTokenizerText ); tt->set_code(p_code); diff --git a/modules/gdscript/gd_parser.h b/modules/gdscript/gd_parser.h index 5fac34396c..3f82cafc61 100644 --- a/modules/gdscript/gd_parser.h +++ b/modules/gdscript/gd_parser.h @@ -373,6 +373,7 @@ private: List<int> tab_level; String base_path; + String self_path; PropertyInfo current_export; @@ -398,8 +399,8 @@ public: String get_error() const; int get_error_line() const; int get_error_column() const; - Error parse(const String& p_code, const String& p_base_path="", bool p_just_validate=false); - Error parse_bytecode(const Vector<uint8_t> &p_bytecode,const String& p_base_path=""); + Error parse(const String& p_code, const String& p_base_path="", bool p_just_validate=false,const String& p_self_path=""); + Error parse_bytecode(const Vector<uint8_t> &p_bytecode,const String& p_base_path="",const String& p_self_path=""); const Node *get_parse_tree() const; diff --git a/modules/gdscript/gd_script.cpp b/modules/gdscript/gd_script.cpp index 7085ae6a56..982584c75c 100644 --- a/modules/gdscript/gd_script.cpp +++ b/modules/gdscript/gd_script.cpp @@ -1523,6 +1523,7 @@ void GDScript::_placeholder_erased(PlaceHolderScriptInstance *p_placeholder) { placeholders.erase(p_placeholder); } +/* void GDScript::_update_placeholder(PlaceHolderScriptInstance *p_placeholder) { @@ -1563,7 +1564,7 @@ void GDScript::_update_placeholder(PlaceHolderScriptInstance *p_placeholder) { p_placeholder->update(plist,default_values); -} +}*/ #endif ScriptInstance* GDScript::instance_create(Object *p_this) { @@ -1582,7 +1583,8 @@ ScriptInstance* GDScript::instance_create(Object *p_this) { }*/ PlaceHolderScriptInstance *si = memnew( PlaceHolderScriptInstance(GDScriptLanguage::get_singleton(),Ref<Script>(this),p_this) ); placeholders.insert(si); - _update_placeholder(si); + //_update_placeholder(si); + _update_exports(); return si; #else return NULL; @@ -1623,61 +1625,136 @@ String GDScript::get_source_code() const { } void GDScript::set_source_code(const String& p_code) { + if (source==p_code) + return; source=p_code; +#ifdef TOOLS_ENABLED + source_changed_cache=true; + //print_line("SC CHANGED "+get_path()); +#endif + } +#ifdef TOOLS_ENABLED +void GDScript::_update_exports_values(Map<StringName,Variant>& values, List<PropertyInfo> &propnames) { + + if (base_cache.is_valid()) { + base_cache->_update_exports_values(values,propnames); + } + + for(Map<StringName,Variant>::Element *E=member_default_values_cache.front();E;E=E->next()) { + values[E->key()]=E->get(); + } + + for (List<PropertyInfo>::Element *E=members_cache.front();E;E=E->next()) { + propnames.push_back(E->get()); + } + +} +#endif -void GDScript::_update_exports(Set<PlaceHolderScriptInstance*> *p_instances) { +bool GDScript::_update_exports() { #ifdef TOOLS_ENABLED - String basedir=path; + bool changed=false; - if (basedir=="") - basedir=get_path(); + if (source_changed_cache) { + //print_line("updating source for "+get_path()); + source_changed_cache=false; + changed=true; - if (basedir!="") - basedir=basedir.get_base_dir(); + String basedir=path; - GDParser parser; - Error err = parser.parse(source,basedir,true); - if (err) - return; //do none + if (basedir=="") + basedir=get_path(); - const GDParser::Node* root = parser.get_parse_tree(); - ERR_FAIL_COND(root->type!=GDParser::Node::TYPE_CLASS); + if (basedir!="") + basedir=basedir.get_base_dir(); + GDParser parser; + Error err = parser.parse(source,basedir,true,path); + if (err==OK) { - const GDParser::ClassNode *c = static_cast<const GDParser::ClassNode*>(root); + const GDParser::Node* root = parser.get_parse_tree(); + ERR_FAIL_COND_V(root->type!=GDParser::Node::TYPE_CLASS,false); - if (c->extends_used && String(c->extends_file)!="") { + const GDParser::ClassNode *c = static_cast<const GDParser::ClassNode*>(root); - Ref<GDScript> bf = ResourceLoader::load(c->extends_file); - if (bf.is_valid()) { + if (base_cache.is_valid()) { + base_cache->inheriters_cache.erase(get_instance_ID()); + base_cache=Ref<GDScript>(); + } - bf->_update_exports(p_instances); - } - } + if (c->extends_used && String(c->extends_file)!="") { - List<PropertyInfo> plist; + String path = c->extends_file; + if (path.is_rel_path()) { - Map<StringName,Variant> default_values; + String base = get_path(); + if (base=="" || base.is_rel_path()) { - for(int i=0;i<c->variables.size();i++) { - if (c->variables[i]._export.type==Variant::NIL) - continue; + ERR_PRINT(("Could not resolve relative path for parent class: "+path).utf8().get_data()); + } else { + path=base.get_base_dir().plus_file(path); + } + } + + Ref<GDScript> bf = ResourceLoader::load(path); + + if (bf.is_valid()) { + + //print_line("parent is: "+bf->get_path()); + base_cache=bf; + bf->inheriters_cache.insert(get_instance_ID()); + + //bf->_update_exports(p_instances,true,false); + + } + } + + members_cache.clear();; + member_default_values_cache.clear(); + + for(int i=0;i<c->variables.size();i++) { + if (c->variables[i]._export.type==Variant::NIL) + continue; + + members_cache.push_back(c->variables[i]._export); + //print_line("found "+c->variables[i]._export.name); + member_default_values_cache[c->variables[i].identifier]=c->variables[i].default_value; + } + } + } else { + //print_line("unchaged is "+get_path()); - plist.push_back(c->variables[i]._export); - default_values[c->variables[i].identifier]=c->variables[i].default_value; } + if (base_cache.is_valid()) { + if (base_cache->_update_exports()) { + changed = true; + } + } - for (Set<PlaceHolderScriptInstance*>::Element *E=p_instances->front();E;E=E->next()) { + if (/*changed &&*/ placeholders.size()) { //hm :( - E->get()->update(plist,default_values); + //print_line("updating placeholders for "+get_path()); + + //update placeholders if any + Map<StringName,Variant> values; + List<PropertyInfo> propnames; + _update_exports_values(values,propnames); + + for (Set<PlaceHolderScriptInstance*>::Element *E=placeholders.front();E;E=E->next()) { + + E->get()->update(propnames,values); + } } + + return changed; + #endif } @@ -1685,8 +1762,20 @@ void GDScript::update_exports() { #ifdef TOOLS_ENABLED - _update_exports(&placeholders); + _update_exports(); + Set<ObjectID> copy=inheriters_cache; //might get modified + + //print_line("update exports for "+get_path()+" ic: "+itos(copy.size())); + for(Set<ObjectID>::Element *E=copy.front();E;E=E->next()) { + Object *id=ObjectDB::get_instance(E->get()); + if (!id) + continue; + GDScript *s=id->cast_to<GDScript>(); + if (!s) + continue; + s->update_exports(); + } #endif } @@ -1718,7 +1807,7 @@ Error GDScript::reload() { valid=false; GDParser parser; - Error err = parser.parse(source,basedir); + Error err = parser.parse(source,basedir,false,path); if (err) { if (ScriptDebugger::get_singleton()) { GDScriptLanguage::get_singleton()->debug_break_parse(get_path(),parser.get_error_line(),"Parser Error: "+parser.get_error()); @@ -1746,10 +1835,10 @@ Error GDScript::reload() { } #ifdef TOOLS_ENABLED - for (Set<PlaceHolderScriptInstance*>::Element *E=placeholders.front();E;E=E->next()) { + /*for (Set<PlaceHolderScriptInstance*>::Element *E=placeholders.front();E;E=E->next()) { _update_placeholder(E->get()); - } + }*/ #endif return OK; } @@ -1892,7 +1981,7 @@ Error GDScript::load_byte_code(const String& p_path) { valid=false; GDParser parser; - Error err = parser.parse_bytecode(bytecode,basedir); + Error err = parser.parse_bytecode(bytecode,basedir,get_path()); if (err) { _err_print_error("GDScript::load_byte_code",path.empty()?"built-in":(const char*)path.utf8().get_data(),parser.get_error_line(),("Parse Error: "+parser.get_error()).utf8().get_data()); ERR_FAIL_V(ERR_PARSE_ERROR); @@ -1945,6 +2034,10 @@ Error GDScript::load_source_code(const String& p_path) { } source=s; +#ifdef TOOLS_ENABLED + source_changed_cache=true; +#endif + //print_line("LSC :"+get_path()); path=p_path; return OK; @@ -1986,6 +2079,9 @@ GDScript::GDScript() { _base=NULL; _owner=NULL; tool=false; +#ifdef TOOLS_ENABLED + source_changed_cache=false; +#endif } diff --git a/modules/gdscript/gd_script.h b/modules/gdscript/gd_script.h index 3b183a41b6..f4e4dffaa5 100644 --- a/modules/gdscript/gd_script.h +++ b/modules/gdscript/gd_script.h @@ -245,7 +245,16 @@ friend class GDScriptLanguage; Map<StringName,Ref<GDScript> > subclasses; #ifdef TOOLS_ENABLED + Map<StringName,Variant> member_default_values; + + List<PropertyInfo> members_cache; + Map<StringName,Variant> member_default_values_cache; + Ref<GDScript> base_cache; + Set<ObjectID> inheriters_cache; + bool source_changed_cache; + void _update_exports_values(Map<StringName,Variant>& values, List<PropertyInfo> &propnames); + #endif Map<StringName,PropertyInfo> member_info; @@ -265,13 +274,13 @@ friend class GDScriptLanguage; #ifdef TOOLS_ENABLED Set<PlaceHolderScriptInstance*> placeholders; - void _update_placeholder(PlaceHolderScriptInstance *p_placeholder); + //void _update_placeholder(PlaceHolderScriptInstance *p_placeholder); virtual void _placeholder_erased(PlaceHolderScriptInstance *p_placeholder); #endif - void _update_exports(Set<PlaceHolderScriptInstance *> *p_instances); + bool _update_exports(); protected: bool _get(const StringName& p_name,Variant &r_ret) const; diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index 89f121c3f6..3e4ea8a4e0 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -1229,7 +1229,7 @@ Error EditorExportPlatformAndroid::export_project(const String& p_path, bool p_d } if (!FileAccess::exists(keystore)) { - EditorNode::add_io_error("Could not find keytore, unable to export."); + EditorNode::add_io_error("Could not find keystore, unable to export."); return ERR_FILE_CANT_OPEN; } diff --git a/platform/isim/detect.py b/platform/isim/detect.py index f4a17838f9..8d60e30d25 100644 --- a/platform/isim/detect.py +++ b/platform/isim/detect.py @@ -60,14 +60,18 @@ def configure(env): '-Xlinker', '-objc_abi_version', '-Xlinker', '2', + '-framework', 'AudioToolbox', + '-framework', 'AVFoundation', + '-framework', 'CoreAudio', + '-framework', 'CoreGraphics', + '-framework', 'CoreMedia', '-framework', 'Foundation', + '-framework', 'Security', '-framework', 'UIKit', - '-framework', 'IOKit', - '-framework', 'CoreGraphics', + '-framework', 'MediaPlayer', '-framework', 'OpenGLES', '-framework', 'QuartzCore', - '-framework', 'AudioToolbox', - '-framework', 'MediaPlayer', + '-framework', 'SystemConfiguration', '-F$ISIMSDK', ]) diff --git a/scene/2d/animated_sprite.cpp b/scene/2d/animated_sprite.cpp index 316dffb3f9..2fcfc18429 100644 --- a/scene/2d/animated_sprite.cpp +++ b/scene/2d/animated_sprite.cpp @@ -27,7 +27,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "animated_sprite.h" - +#include "scene/scene_string_names.h" void AnimatedSprite::edit_set_pivot(const Point2& p_pivot) { set_offset(p_pivot); @@ -207,7 +207,7 @@ void AnimatedSprite::set_frame(int p_frame) { frame=p_frame; update(); _change_notify("frame"); - + emit_signal(SceneStringNames::get_singleton()->frame_changed); } int AnimatedSprite::get_frame() const { @@ -233,6 +233,7 @@ void AnimatedSprite::set_offset(const Point2& p_offset) { offset=p_offset; update(); item_rect_changed(); + _change_notify("offset"); } Point2 AnimatedSprite::get_offset() const { @@ -325,6 +326,8 @@ void AnimatedSprite::_bind_methods() { ObjectTypeDB::bind_method(_MD("_res_changed"),&AnimatedSprite::_res_changed); + ADD_SIGNAL(MethodInfo("frame_changed")); + ADD_PROPERTYNZ( PropertyInfo( Variant::OBJECT, "frames",PROPERTY_HINT_RESOURCE_TYPE,"SpriteFrames"), _SCS("set_sprite_frames"),_SCS("get_sprite_frames")); ADD_PROPERTYNZ( PropertyInfo( Variant::INT, "frame"), _SCS("set_frame"),_SCS("get_frame")); ADD_PROPERTY( PropertyInfo( Variant::BOOL, "centered"), _SCS("set_centered"),_SCS("is_centered")); diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index 3114106235..ca2a42026d 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -142,6 +142,8 @@ void Area2D::_body_inout(int p_status,const RID& p_body, int p_instance, int p_b ERR_FAIL_COND(!body_in && !E); + locked=true; + if (body_in) { if (!E) { @@ -197,11 +199,18 @@ void Area2D::_body_inout(int p_status,const RID& p_body, int p_instance, int p_b } + locked=false; + + } void Area2D::_clear_monitoring() { + if (locked) { + ERR_EXPLAIN("This function can't be used during the in/out signal."); + } + ERR_FAIL_COND(locked); Map<ObjectID,BodyState> bmcopy = body_map; body_map.clear(); @@ -243,6 +252,11 @@ void Area2D::_notification(int p_what) { void Area2D::set_enable_monitoring(bool p_enable) { + if (locked) { + ERR_EXPLAIN("This function can't be used during the in/out signal."); + } + ERR_FAIL_COND(locked); + if (p_enable==monitoring) return; @@ -336,6 +350,7 @@ Area2D::Area2D() : CollisionObject2D(Physics2DServer::get_singleton()->area_crea set_gravity_vector(Vector2(0,1)); gravity_is_point=false; density=0.1; + locked=false; priority=0; monitoring=false; set_enable_monitoring(true); diff --git a/scene/2d/area_2d.h b/scene/2d/area_2d.h index c6210e7c9a..2044cc7db0 100644 --- a/scene/2d/area_2d.h +++ b/scene/2d/area_2d.h @@ -52,6 +52,7 @@ private: real_t density; int priority; bool monitoring; + bool locked; void _body_inout(int p_status,const RID& p_body, int p_instance, int p_body_shape,int p_area_shape); diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp index 2b4be734af..217a98aaea 100644 --- a/scene/2d/polygon_2d.cpp +++ b/scene/2d/polygon_2d.cpp @@ -359,5 +359,6 @@ Polygon2D::Polygon2D() { tex_rot=0; tex_tile=true; tex_scale=Vector2(1,1); + color=Color(1,1,1); rect_cache_dirty=true; } diff --git a/scene/2d/sprite.cpp b/scene/2d/sprite.cpp index 9f789a7a1f..82f5a6972a 100644 --- a/scene/2d/sprite.cpp +++ b/scene/2d/sprite.cpp @@ -34,6 +34,7 @@ void Sprite::edit_set_pivot(const Point2& p_pivot) { set_offset(p_pivot); + } Point2 Sprite::edit_get_pivot() const { @@ -136,6 +137,7 @@ void Sprite::set_offset(const Point2& p_offset) { offset=p_offset; update(); item_rect_changed(); + _change_notify("offset"); } Point2 Sprite::get_offset() const { @@ -199,6 +201,8 @@ void Sprite::set_frame(int p_frame) { item_rect_changed(); frame=p_frame; + + emit_signal(SceneStringNames::get_singleton()->frame_changed); } int Sprite::get_frame() const { @@ -307,6 +311,8 @@ void Sprite::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_modulate","modulate"),&Sprite::set_modulate); ObjectTypeDB::bind_method(_MD("get_modulate"),&Sprite::get_modulate); + ADD_SIGNAL(MethodInfo("frame_changed")); + ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE,"Texture"), _SCS("set_texture"),_SCS("get_texture")); ADD_PROPERTY( PropertyInfo( Variant::BOOL, "centered"), _SCS("set_centered"),_SCS("is_centered")); ADD_PROPERTY( PropertyInfo( Variant::VECTOR2, "offset"), _SCS("set_offset"),_SCS("get_offset")); diff --git a/scene/3d/area.cpp b/scene/3d/area.cpp index cb1df78fda..9cdd24d102 100644 --- a/scene/3d/area.cpp +++ b/scene/3d/area.cpp @@ -115,6 +115,7 @@ void Area::_body_enter_tree(ObjectID p_id) { void Area::_body_exit_tree(ObjectID p_id) { + Object *obj = ObjectDB::get_instance(p_id); Node *node = obj ? obj->cast_to<Node>() : NULL; ERR_FAIL_COND(!node); @@ -132,6 +133,7 @@ void Area::_body_exit_tree(ObjectID p_id) { void Area::_body_inout(int p_status,const RID& p_body, int p_instance, int p_body_shape,int p_area_shape) { + bool body_in = p_status==PhysicsServer::AREA_BODY_ADDED; ObjectID objid=p_instance; @@ -142,6 +144,8 @@ void Area::_body_inout(int p_status,const RID& p_body, int p_instance, int p_bod ERR_FAIL_COND(!body_in && !E); + locked=true; + if (body_in) { if (!E) { @@ -197,11 +201,19 @@ void Area::_body_inout(int p_status,const RID& p_body, int p_instance, int p_bod } + locked=false; + + } void Area::_clear_monitoring() { + if (locked) { + ERR_EXPLAIN("This function can't be used during the in/out signal."); + } + ERR_FAIL_COND(locked); + Map<ObjectID,BodyState> bmcopy = body_map; body_map.clear(); //disconnect all monitored stuff @@ -235,6 +247,11 @@ void Area::_notification(int p_what) { void Area::set_enable_monitoring(bool p_enable) { + if (locked) { + ERR_EXPLAIN("This function can't be used during the in/out signal."); + } + ERR_FAIL_COND(locked); + if (p_enable==monitoring) return; @@ -325,6 +342,7 @@ Area::Area() : CollisionObject(PhysicsServer::get_singleton()->area_create(),tru space_override=SPACE_OVERRIDE_DISABLED; set_gravity(9.8);; + locked=false; set_gravity_vector(Vector3(0,-1,0)); gravity_is_point=false; density=0.1; diff --git a/scene/3d/area.h b/scene/3d/area.h index 4707b73e1c..40c6d24b5c 100644 --- a/scene/3d/area.h +++ b/scene/3d/area.h @@ -52,6 +52,7 @@ private: real_t density; int priority; bool monitoring; + bool locked; void _body_inout(int p_status,const RID& p_body, int p_instance, int p_body_shape,int p_area_shape); diff --git a/scene/3d/light.cpp b/scene/3d/light.cpp index 9d959cb0d6..15e77e5378 100644 --- a/scene/3d/light.cpp +++ b/scene/3d/light.cpp @@ -415,11 +415,11 @@ void Light::approximate_opengl_attenuation(float p_constant, float p_linear, flo float energy=1.0; - if (p_constant>0) + /*if (p_constant>0) energy=1.0/p_constant; //energy is this else energy=8.0; // some high number.. - +*/ if (radius==10000) radius=100; //bug? diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index a6a8919d13..77f2cf5cc1 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -275,6 +275,9 @@ void SpriteBase3D::_bind_methods() { BIND_CONSTANT( ALPHA_CUT_DISABLED ); BIND_CONSTANT( ALPHA_CUT_DISCARD ); BIND_CONSTANT( ALPHA_CUT_OPAQUE_PREPASS ); + + + } @@ -494,6 +497,8 @@ void Sprite3D::set_frame(int p_frame) { frame=p_frame; _queue_update(); + ADD_SIGNAL(MethodInfo("frame_changed")); + } int Sprite3D::get_frame() const { @@ -579,6 +584,8 @@ void Sprite3D::_bind_methods() { ADD_PROPERTY( PropertyInfo( Variant::BOOL, "region"), _SCS("set_region"),_SCS("is_region")); ADD_PROPERTY( PropertyInfo( Variant::RECT2, "region_rect"), _SCS("set_region_rect"),_SCS("get_region_rect")); + ADD_SIGNAL(MethodInfo("frame_changed")); + } Sprite3D::Sprite3D() { @@ -722,6 +729,8 @@ void AnimatedSprite3D::_bind_methods(){ ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "frames", PROPERTY_HINT_RESOURCE_TYPE,"SpriteFrames"), _SCS("set_sprite_frames"),_SCS("get_sprite_frames")); ADD_PROPERTY( PropertyInfo( Variant::INT, "frame"), _SCS("set_frame"),_SCS("get_frame")); + ADD_SIGNAL(MethodInfo("frame_changed")); + } @@ -764,6 +773,7 @@ void AnimatedSprite3D::set_frame(int p_frame){ frame=p_frame; _queue_update(); + emit_signal(SceneStringNames::get_singleton()->frame_changed); } int AnimatedSprite3D::get_frame() const{ diff --git a/scene/3d/visual_instance.cpp b/scene/3d/visual_instance.cpp index 5b40a4d7e5..a82c69e67f 100644 --- a/scene/3d/visual_instance.cpp +++ b/scene/3d/visual_instance.cpp @@ -359,13 +359,13 @@ void GeometryInstance::_bind_methods() { GeometryInstance::GeometryInstance() { draw_begin=0; draw_end=0; + for(int i=0;i<FLAG_MAX;i++) { + flags[i]=false; + } + flags[FLAG_VISIBLE]=true; flags[FLAG_CAST_SHADOW]=true; flags[FLAG_RECEIVE_SHADOWS]=true; - flags[FLAG_BILLBOARD]=false; - flags[FLAG_BILLBOARD_FIX_Y]=false; - flags[FLAG_DEPH_SCALE]=false; - flags[FLAG_VISIBLE_IN_ALL_ROOMS]=false; baked_light_instance=NULL; baked_light_texture_id=0; VS::get_singleton()->instance_geometry_set_baked_light_texture_index(get_instance(),0); diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index b95d271394..ba68948e6b 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -1747,16 +1747,16 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { } break;} - default: { + default: { - scancode_handled=false; - } break; + scancode_handled=false; + } break; } if (scancode_handled) accept_event(); - +/* if (!scancode_handled && !k.mod.command && !k.mod.alt) { if (k.unicode>=32) { @@ -1770,8 +1770,8 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { break; } } - - if (!scancode_handled && !k.mod.command && !k.mod.alt) { +*/ + if (!scancode_handled && !k.mod.command && !k.mod.alt) { //for german kbds if (k.unicode>=32) { @@ -3150,12 +3150,15 @@ void TextEdit::set_line(int line, String new_text) { if (line < 0 || line > text.size()) return; - text.set(line, new_text); + _remove_text(line, 0, line, text[line].length()); + _insert_text(line, 0, new_text); } void TextEdit::insert_at(const String &p_text, int at) { - text.insert(at, p_text); + cursor_set_column(0); + cursor_set_line(at); + _insert_text(at, 0, p_text+"\n"); } void TextEdit::set_show_line_numbers(bool p_show) { diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index db9142cb99..b7b52a39dc 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -1693,6 +1693,13 @@ void Tree::text_editor_enter(String p_text) { case TreeItem::CELL_MODE_RANGE: { c.val=p_text.to_double(); + if (c.step>0) + c.val=Math::stepify(c.val,c.step); + if (c.val<c.min) + c.val=c.min; + else if (c.val>c.max) + c.val=c.max; + //popup_edited_item->edited_signal.call( popup_edited_item_col ); } break; default: { ERR_FAIL(); } diff --git a/scene/main/scene_main_loop.cpp b/scene/main/scene_main_loop.cpp index 47089638bb..ed3e419359 100644 --- a/scene/main/scene_main_loop.cpp +++ b/scene/main/scene_main_loop.cpp @@ -333,6 +333,9 @@ void SceneTree::input_text( const String& p_text ) { void SceneTree::input_event( const InputEvent& p_event ) { + if (is_editor_hint() && (p_event.type==InputEvent::JOYSTICK_MOTION || p_event.type==InputEvent::JOYSTICK_BUTTON)) + return; //avoid joy input on editor + root_lock++; //last_id=p_event.ID; diff --git a/scene/main/timer.cpp b/scene/main/timer.cpp index 2ae918f3f3..f718a09577 100644 --- a/scene/main/timer.cpp +++ b/scene/main/timer.cpp @@ -40,7 +40,8 @@ void Timer::_notification(int p_what) { #ifdef TOOLS_ENABLED if (get_tree()->is_editor_hint() && get_tree()->get_edited_scene_root() && (get_tree()->get_edited_scene_root()==this || get_tree()->get_edited_scene_root()->is_a_parent_of(this))) break; -#endif start(); +#endif + start(); } } break; case NOTIFICATION_PROCESS: { diff --git a/scene/scene_string_names.cpp b/scene/scene_string_names.cpp index 8ad7e06c0f..0d66257eda 100644 --- a/scene/scene_string_names.cpp +++ b/scene/scene_string_names.cpp @@ -150,4 +150,6 @@ SceneStringNames::SceneStringNames() { _pressed=StaticCString::create("_pressed"); _toggled=StaticCString::create("_toggled"); + frame_changed=StaticCString::create("frame_changed"); + } diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h index 512674f648..b0628c86b6 100644 --- a/scene/scene_string_names.h +++ b/scene/scene_string_names.h @@ -158,6 +158,7 @@ public: StringName _mouse_enter; StringName _mouse_exit; + StringName frame_changed; }; diff --git a/servers/physics/body_pair_sw.cpp b/servers/physics/body_pair_sw.cpp index bca6a9fa72..2e66c9e27b 100644 --- a/servers/physics/body_pair_sw.cpp +++ b/servers/physics/body_pair_sw.cpp @@ -175,7 +175,7 @@ void BodyPairSW::validate_contacts() { bool BodyPairSW::setup(float p_step) { //cannot collide - if (A->has_exception(B->get_self()) || B->has_exception(A->get_self()) || (A->get_mode()<=PhysicsServer::BODY_MODE_KINEMATIC && B->get_mode()<=PhysicsServer::BODY_MODE_KINEMATIC && A->get_max_contacts_reported()==0 && B->get_max_contacts_reported()==0)) { + if ((A->get_layer_mask()&B->get_layer_mask())==0 || A->has_exception(B->get_self()) || B->has_exception(A->get_self()) || (A->get_mode()<=PhysicsServer::BODY_MODE_KINEMATIC && B->get_mode()<=PhysicsServer::BODY_MODE_KINEMATIC && A->get_max_contacts_reported()==0 && B->get_max_contacts_reported()==0)) { collided=false; return false; } diff --git a/servers/physics/collision_solver_sw.cpp b/servers/physics/collision_solver_sw.cpp index 56f2784145..86e3b679f2 100644 --- a/servers/physics/collision_solver_sw.cpp +++ b/servers/physics/collision_solver_sw.cpp @@ -275,6 +275,44 @@ void CollisionSolverSW::concave_distance_callback(void *p_userdata, ShapeSW *p_c } + +bool CollisionSolverSW::solve_distance_plane(const ShapeSW *p_shape_A,const Transform& p_transform_A,const ShapeSW *p_shape_B,const Transform& p_transform_B,Vector3& r_point_A,Vector3& r_point_B) { + + const PlaneShapeSW *plane = static_cast<const PlaneShapeSW*>(p_shape_A); + if (p_shape_B->get_type()==PhysicsServer::SHAPE_PLANE) + return false; + Plane p = p_transform_A.xform(plane->get_plane()); + + static const int max_supports = 16; + Vector3 supports[max_supports]; + int support_count; + + p_shape_B->get_supports(p_transform_B.basis.xform_inv(-p.normal).normalized(),max_supports,supports,support_count); + + bool collided=false; + Vector3 closest; + float closest_d; + + + for(int i=0;i<support_count;i++) { + + supports[i] = p_transform_B.xform( supports[i] ); + real_t d = p.distance_to(supports[i]); + if (i==0 || d<closest_d) { + closest=supports[i]; + closest_d=d; + if (d<=0) + collided=true; + } + + } + + r_point_A=p.project(closest); + r_point_B=closest; + + return collided; +} + bool CollisionSolverSW::solve_distance(const ShapeSW *p_shape_A,const Transform& p_transform_A,const ShapeSW *p_shape_B,const Transform& p_transform_B,Vector3& r_point_A,Vector3& r_point_B,const AABB& p_concave_hint,Vector3 *r_sep_axis) { if (p_shape_A->is_concave()) @@ -282,7 +320,11 @@ bool CollisionSolverSW::solve_distance(const ShapeSW *p_shape_A,const Transform& if (p_shape_B->get_type()==PhysicsServer::SHAPE_PLANE) { - return false; //unsupported + Vector3 a,b; + bool col = solve_distance_plane(p_shape_B,p_transform_B,p_shape_A,p_transform_A,a,b); + r_point_A=b; + r_point_B=a; + return !col; } else if (p_shape_B->is_concave()) { diff --git a/servers/physics/collision_solver_sw.h b/servers/physics/collision_solver_sw.h index 430f057c7c..764c32926c 100644 --- a/servers/physics/collision_solver_sw.h +++ b/servers/physics/collision_solver_sw.h @@ -42,6 +42,7 @@ private: static bool solve_ray(const ShapeSW *p_shape_A,const Transform& p_transform_A,const ShapeSW *p_shape_B,const Transform& p_transform_B,CallbackResult p_result_callback,void *p_userdata,bool p_swap_result); static bool solve_concave(const ShapeSW *p_shape_A,const Transform& p_transform_A,const ShapeSW *p_shape_B,const Transform& p_transform_B,CallbackResult p_result_callback,void *p_userdata,bool p_swap_result,float p_margin_A=0,float p_margin_B=0); static void concave_distance_callback(void *p_userdata, ShapeSW *p_convex); + static bool solve_distance_plane(const ShapeSW *p_shape_A,const Transform& p_transform_A,const ShapeSW *p_shape_B,const Transform& p_transform_B,Vector3& r_point_A,Vector3& r_point_B); public: diff --git a/servers/visual/rasterizer.cpp b/servers/visual/rasterizer.cpp index 5e81bc960a..b5e74e0f2e 100644 --- a/servers/visual/rasterizer.cpp +++ b/servers/visual/rasterizer.cpp @@ -79,7 +79,7 @@ RID Rasterizer::_create_shader(const FixedMaterialShaderKey& p_key) { if (texcoords_used&(1<<VS::FIXED_MATERIAL_TEXCOORD_UV_TRANSFORM)) { code+="uniform mat4 fmp_uv_xform;\n"; - code+="vec2 uv_xform = fmp_uv_xform * UV;\n"; + code+="vec2 uv_xform = (fmp_uv_xform * vec4(UV,0,1)).xy;\n"; } /* HANDLE NORMAL MAPPING */ diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp index ca219b13a4..40e36d2a89 100644 --- a/servers/visual/shader_language.cpp +++ b/servers/visual/shader_language.cpp @@ -436,7 +436,10 @@ ShaderLanguage::Token ShaderLanguage::read_token(const CharType* p_text,int p_le return Token(TK_INDENTIFIER,str); } - return Token(TK_ERROR,"Unknown character"); + if (GETCHAR(0)>32) + return Token(TK_ERROR,"Tokenizer: Unknown character #"+itos(GETCHAR(0))+": '"+String::chr(GETCHAR(0))+"'"); + else + return Token(TK_ERROR,"Tokenizer: Unknown character #"+itos(GETCHAR(0))); } break; } @@ -463,9 +466,9 @@ Error ShaderLanguage::tokenize(const String& p_text,Vector<Token> *p_tokens,Stri if (t.type==TK_ERROR) { if (r_error) { - return ERR_COMPILATION_FAILED; *r_error=t.text; *r_err_line=line; + return ERR_COMPILATION_FAILED; } } @@ -952,10 +955,16 @@ const ShaderLanguage::OperatorDef ShaderLanguage::operator_defs[]={ {OP_ASSIGN_ADD,TYPE_VOID,{TYPE_VEC2,TYPE_VEC2}}, {OP_ASSIGN_ADD,TYPE_VOID,{TYPE_VEC3,TYPE_VEC3}}, {OP_ASSIGN_ADD,TYPE_VOID,{TYPE_VEC4,TYPE_VEC4}}, + {OP_ASSIGN_ADD,TYPE_VOID,{TYPE_VEC2,TYPE_FLOAT}}, + {OP_ASSIGN_ADD,TYPE_VOID,{TYPE_VEC3,TYPE_FLOAT}}, + {OP_ASSIGN_ADD,TYPE_VOID,{TYPE_VEC4,TYPE_FLOAT}}, {OP_ASSIGN_SUB,TYPE_VOID,{TYPE_FLOAT,TYPE_FLOAT}}, {OP_ASSIGN_SUB,TYPE_VOID,{TYPE_VEC2,TYPE_VEC2}}, {OP_ASSIGN_SUB,TYPE_VOID,{TYPE_VEC3,TYPE_VEC3}}, {OP_ASSIGN_SUB,TYPE_VOID,{TYPE_VEC4,TYPE_VEC4}}, + {OP_ASSIGN_SUB,TYPE_VOID,{TYPE_VEC2,TYPE_FLOAT}}, + {OP_ASSIGN_SUB,TYPE_VOID,{TYPE_VEC3,TYPE_FLOAT}}, + {OP_ASSIGN_SUB,TYPE_VOID,{TYPE_VEC4,TYPE_FLOAT}}, {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_FLOAT,TYPE_FLOAT}}, {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC2,TYPE_VEC2}}, {OP_ASSIGN_MUL,TYPE_VOID,{TYPE_VEC2,TYPE_FLOAT}}, @@ -2485,6 +2494,9 @@ Error ShaderLanguage::compile(const String& p_code,ShaderType p_type,CompileFunc uint64_t t = OS::get_singleton()->get_ticks_usec(); Error err = tokenize(p_code,&tokens,r_error,r_err_line,r_err_column); + if (err!=OK) { + print_line("tokenizer error!"); + } double tf = (OS::get_singleton()->get_ticks_usec()-t)/1000.0; //print_line("tokenize time: "+rtos(tf)); diff --git a/tools/editor/animation_editor.cpp b/tools/editor/animation_editor.cpp index 0d4f5a7b74..95f9ee6509 100644 --- a/tools/editor/animation_editor.cpp +++ b/tools/editor/animation_editor.cpp @@ -2513,6 +2513,7 @@ void AnimationKeyEditor::_query_insert(const InsertData& p_id) { if (insert_frame!=OS::get_singleton()->get_frames_drawn()) { + //clear insert list for the frame if frame changed if (insert_confirm->is_visible()) return; //do nothing insert_data.clear(); @@ -2520,19 +2521,29 @@ void AnimationKeyEditor::_query_insert(const InsertData& p_id) { } insert_frame=OS::get_singleton()->get_frames_drawn(); + for (List<InsertData>::Element *E=insert_data.front();E;E=E->next()) { + //prevent insertion of multiple tracks + if (E->get().path==p_id.path) + return; //already inserted a track for this on this frame + } + insert_data.push_back(p_id); if (p_id.track_idx==-1) { - //potential new key, does not exist - if (insert_data.size()==1) - insert_confirm->set_text("Create NEW track for "+p_id.query+" and insert key?"); - else - insert_confirm->set_text("Create "+itos(insert_data.size())+" NEW tracks and insert keys?"); - - insert_confirm->get_ok()->set_text("Create"); - insert_confirm->popup_centered(Size2(300,100)); - insert_query=true; - + if (bool(EDITOR_DEF("animation/confirm_insert_track",true))) { + //potential new key, does not exist + if (insert_data.size()==1) + insert_confirm->set_text("Create NEW track for "+p_id.query+" and insert key?"); + else + insert_confirm->set_text("Create "+itos(insert_data.size())+" NEW tracks and insert keys?"); + + insert_confirm->get_ok()->set_text("Create"); + insert_confirm->popup_centered(Size2(300,100)); + insert_query=true; + } else { + call_deferred("_insert_delay"); + insert_queue=true; + } } else { if (!insert_query && !insert_queue) { @@ -3143,7 +3154,7 @@ AnimationKeyEditor::AnimationKeyEditor(UndoRedo *p_undo_redo, EditorHistory *p_h //add_child(menu); menu_track = memnew( MenuButton ); - menu_track->set_text("Tracks.."); + menu_track->set_text("Tracks"); hb->add_child(menu_track); menu_track->get_popup()->connect("item_pressed",this,"_menu_track"); @@ -3341,8 +3352,6 @@ AnimationKeyEditor::AnimationKeyEditor(UndoRedo *p_undo_redo, EditorHistory *p_h add_child(insert_confirm); insert_confirm->connect("confirmed",this,"_confirm_insert_list"); - EDITOR_DEF("animation_editor/confirm_insert_key",true); - click.click=ClickOver::CLICK_NONE; diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index 5e9cdf78a2..2927e7c870 100644 --- a/tools/editor/editor_node.cpp +++ b/tools/editor/editor_node.cpp @@ -2819,6 +2819,8 @@ void EditorNode::animation_editor_make_visible(bool p_visible) { //pd_anim->hide(); animation_editor->hide(); // scene_root_parent->set_margin(MARGIN_TOP,0); + if (!animation_vb->get_parent_control()) + return; animation_vb->get_parent_control()->minimum_size_changed(); top_split->set_collapsed(true); } diff --git a/tools/editor/editor_settings.cpp b/tools/editor/editor_settings.cpp index 8852293fe4..8b4d899437 100644 --- a/tools/editor/editor_settings.cpp +++ b/tools/editor/editor_settings.cpp @@ -440,6 +440,7 @@ void EditorSettings::_load_defaults() { set("animation/autorename_animation_tracks",true); + set("animation/confirm_insert_track",true); set("property_editor/texture_preview_width",48); set("help/doc_path",""); diff --git a/tools/editor/plugins/polygon_2d_editor_plugin.cpp b/tools/editor/plugins/polygon_2d_editor_plugin.cpp index 7dd8dd3035..27e539d50b 100644 --- a/tools/editor/plugins/polygon_2d_editor_plugin.cpp +++ b/tools/editor/plugins/polygon_2d_editor_plugin.cpp @@ -187,6 +187,8 @@ void Polygon2DEditor::_wip_close() { bool Polygon2DEditor::forward_input_event(const InputEvent& p_event) { + if (node==NULL) + return false; switch(p_event.type) { @@ -701,11 +703,16 @@ void Polygon2DEditor::edit(Node *p_collision_polygon) { node=p_collision_polygon->cast_to<Polygon2D>(); if (!canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw")) canvas_item_editor->get_viewport_control()->connect("draw",this,"_canvas_draw"); + node->connect("exit_tree",this,"_node_removed",varray(),CONNECT_ONESHOT); wip.clear(); wip_active=false; edited_point=-1; } else { + + if (node) + node->disconnect("exit_tree",this,"_node_removed"); + node=NULL; if (canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw")) @@ -723,12 +730,14 @@ void Polygon2DEditor::_bind_methods() { ObjectTypeDB::bind_method(_MD("_uv_draw"),&Polygon2DEditor::_uv_draw); ObjectTypeDB::bind_method(_MD("_uv_input"),&Polygon2DEditor::_uv_input); ObjectTypeDB::bind_method(_MD("_uv_scroll_changed"),&Polygon2DEditor::_uv_scroll_changed); + ObjectTypeDB::bind_method(_MD("_node_removed"),&Polygon2DEditor::_node_removed); } Polygon2DEditor::Polygon2DEditor(EditorNode *p_editor) { + node=NULL; canvas_item_editor=NULL; editor=p_editor; undo_redo = editor->get_undo_redo(); diff --git a/tools/editor/plugins/script_editor_plugin.cpp b/tools/editor/plugins/script_editor_plugin.cpp index c0d773309c..c5fb574c71 100644 --- a/tools/editor/plugins/script_editor_plugin.cpp +++ b/tools/editor/plugins/script_editor_plugin.cpp @@ -608,6 +608,16 @@ bool ScriptEditor::_test_script_times_on_disk() { return all_ok; } +void ScriptEditor::swap_lines(TextEdit *tx, int line1, int line2) +{ + String tmp = tx->get_line(line1); + String tmp2 = tx->get_line(line2); + tx->set_line(line2, tmp); + tx->set_line(line1, tmp2); + + tx->cursor_set_line(line2); +} + void ScriptEditor::_menu_option(int p_option) { @@ -690,18 +700,38 @@ void ScriptEditor::_menu_option(int p_option) { if (scr.is_null()) return; - int line_id = tx->cursor_get_line(); - int next_id = line_id - 1; + if (tx->is_selection_active()) + { + int from_line = tx->get_selection_from_line(); + int from_col = tx->get_selection_from_column(); + int to_line = tx->get_selection_to_line(); + int to_column = tx->get_selection_to_column(); + + for (int i = from_line; i <= to_line; i++) + { + int line_id = i; + int next_id = i - 1; - if (line_id == 0 || next_id < 0) - return; + if (line_id == 0 || next_id < 0) + return; - String tmp = tx->get_line(line_id); - String tmp2 = tx->get_line(next_id); - tx->set_line(next_id, tmp); - tx->set_line(line_id, tmp2); + swap_lines(tx, line_id, next_id); + } + int from_line_up = from_line > 0 ? from_line-1 : from_line; + int to_line_up = to_line > 0 ? to_line-1 : to_line; + tx->select(from_line_up, from_col, to_line_up, to_column); + } + else + { + int line_id = tx->cursor_get_line(); + int next_id = line_id - 1; + + if (line_id == 0 || next_id < 0) + return; + + swap_lines(tx, line_id, next_id); + } tx->update(); - tx->cursor_set_line(next_id); } break; case EDIT_MOVE_LINE_DOWN: { @@ -711,18 +741,38 @@ void ScriptEditor::_menu_option(int p_option) { if (scr.is_null()) return; - int line_id = tx->cursor_get_line(); - int next_id = line_id + 1; + if (tx->is_selection_active()) + { + int from_line = tx->get_selection_from_line(); + int from_col = tx->get_selection_from_column(); + int to_line = tx->get_selection_to_line(); + int to_column = tx->get_selection_to_column(); - if (line_id == tx->get_line_count() || next_id > tx->get_line_count()) - return; + for (int i = to_line; i >= from_line; i--) + { + int line_id = i; + int next_id = i + 1; + + if (line_id == tx->get_line_count()-1 || next_id > tx->get_line_count()) + return; - String tmp = tx->get_line(line_id); - String tmp2 = tx->get_line(next_id); - tx->set_line(next_id, tmp); - tx->set_line(line_id, tmp2); + swap_lines(tx, line_id, next_id); + } + int from_line_down = from_line < tx->get_line_count() ? from_line+1 : from_line; + int to_line_down = to_line < tx->get_line_count() ? to_line+1 : to_line; + tx->select(from_line_down, from_col, to_line_down, to_column); + } + else + { + int line_id = tx->cursor_get_line(); + int next_id = line_id + 1; + + if (line_id == tx->get_line_count()-1 || next_id > tx->get_line_count()) + return; + + swap_lines(tx, line_id, next_id); + } tx->update(); - tx->cursor_set_line(next_id); } break; case EDIT_INDENT_LEFT: { @@ -740,19 +790,39 @@ void ScriptEditor::_menu_option(int p_option) { for (int i = begin; i <= end; i++) { String line_text = tx->get_line(i); - line_text = line_text.substr(1, line_text.length()); - tx->set_line(i, line_text); + // begins with tab + if (line_text.begins_with("\t")) + { + line_text = line_text.substr(1, line_text.length()); + tx->set_line(i, line_text); + } + // begins with 4 spaces + else if (line_text.begins_with(" ")) + { + line_text = line_text.substr(4, line_text.length()); + tx->set_line(i, line_text); + } } } else { begin = tx->cursor_get_line(); String line_text = tx->get_line(begin); - line_text = line_text.substr(1, line_text.length()); - tx->set_line(begin, line_text); + // begins with tab + if (line_text.begins_with("\t")) + { + line_text = line_text.substr(1, line_text.length()); + tx->set_line(begin, line_text); + } + // begins with 4 spaces + else if (line_text.begins_with(" ")) + { + line_text = line_text.substr(4, line_text.length()); + tx->set_line(begin, line_text); + } } tx->update(); - tx->deselect(); + //tx->deselect(); } break; case EDIT_INDENT_RIGHT: { @@ -782,7 +852,7 @@ void ScriptEditor::_menu_option(int p_option) { tx->set_line(begin, line_text); } tx->update(); - tx->deselect(); + //tx->deselect(); } break; case EDIT_CLONE_DOWN: { @@ -837,7 +907,7 @@ void ScriptEditor::_menu_option(int p_option) { tx->set_line(begin, line_text); } tx->update(); - tx->deselect(); + //tx->deselect(); } break; case EDIT_COMPLETE: { @@ -1443,7 +1513,7 @@ void ScriptEditor::_add_callback(Object *p_obj, const String& p_function, const int pos = script->get_language()->find_function(p_function,code); if (pos==-1) { //does not exist - + ste->get_text_edit()->deselect(); pos=ste->get_text_edit()->get_line_count()+2; String func = script->get_language()->make_function("",p_function,p_args); //code=code+func; @@ -1498,8 +1568,8 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { edit_menu->get_popup()->add_separator(); edit_menu->get_popup()->add_item("Select All",EDIT_SELECT_ALL,KEY_MASK_CMD|KEY_A); edit_menu->get_popup()->add_separator(); - edit_menu->get_popup()->add_item("Move Line Up",EDIT_MOVE_LINE_UP,KEY_MASK_ALT|KEY_UP); - edit_menu->get_popup()->add_item("Move Line Down",EDIT_MOVE_LINE_DOWN,KEY_MASK_ALT|KEY_DOWN); + edit_menu->get_popup()->add_item("Move Up",EDIT_MOVE_LINE_UP,KEY_MASK_ALT|KEY_UP); + edit_menu->get_popup()->add_item("Move Down",EDIT_MOVE_LINE_DOWN,KEY_MASK_ALT|KEY_DOWN); edit_menu->get_popup()->add_item("Indent Left",EDIT_INDENT_LEFT,KEY_MASK_ALT|KEY_LEFT); edit_menu->get_popup()->add_item("Indent Right",EDIT_INDENT_RIGHT,KEY_MASK_ALT|KEY_RIGHT); edit_menu->get_popup()->add_item("Toggle Comment",EDIT_TOGGLE_COMMENT,KEY_MASK_CMD|KEY_SLASH); diff --git a/tools/editor/plugins/script_editor_plugin.h b/tools/editor/plugins/script_editor_plugin.h index 62508253e3..01942fab2a 100644 --- a/tools/editor/plugins/script_editor_plugin.h +++ b/tools/editor/plugins/script_editor_plugin.h @@ -218,7 +218,7 @@ public: void get_breakpoints(List<String> *p_breakpoints); - + void swap_lines(TextEdit *tx, int line1, int line2); void save_external_data(); diff --git a/tools/editor/plugins/shader_editor_plugin.cpp b/tools/editor/plugins/shader_editor_plugin.cpp index d9bf4b6fa5..a6172ee098 100644 --- a/tools/editor/plugins/shader_editor_plugin.cpp +++ b/tools/editor/plugins/shader_editor_plugin.cpp @@ -144,10 +144,13 @@ void ShaderTextEditor::_validate_script() { Error err = ShaderLanguage::compile(code,type,NULL,NULL,&errortxt,&line,&col); if (err!=OK) { - String error_text="error("+itos(line)+","+itos(col)+"): "+errortxt; + String error_text="error("+itos(line+1)+","+itos(col)+"): "+errortxt; set_error(error_text); + get_text_edit()->set_line_as_marked(line,true); } else { + for(int i=0;i<get_text_edit()->get_line_count();i++) + get_text_edit()->set_line_as_marked(i,false); set_error(""); } diff --git a/tools/export/blender25/io_scene_dae/export_dae.py b/tools/export/blender25/io_scene_dae/export_dae.py index 8b1d2e296a..c41b60f2e6 100644 --- a/tools/export/blender25/io_scene_dae/export_dae.py +++ b/tools/export/blender25/io_scene_dae/export_dae.py @@ -1438,11 +1438,16 @@ class DaeExporter: return tcn def export_animations(self): - + tmp_mat = [] # workaround by ndee + for s in self.skeletons: # workaround by ndee + tmp_bone_mat = [] # workaround by ndee + for bone in s.pose.bones: # workaround by ndee + tmp_bone_mat.append(Matrix(bone.matrix_basis)) # workaround by ndee + tmp_mat.append([Matrix(s.matrix_local),tmp_bone_mat]) # workaround by ndee -> stores skeleton and bone transformations + self.writel(S_ANIM,0,'<library_animations>') - if (self.config["use_anim_action_all"] and len(self.skeletons)): cached_actions = {} @@ -1473,13 +1478,18 @@ class DaeExporter: bones.append(dp) allowed_skeletons=[] - for y in self.skeletons: + for i,y in enumerate(self.skeletons): # workaround by ndee if (y.animation_data): for z in y.pose.bones: if (z.bone.name in bones): if (not y in allowed_skeletons): allowed_skeletons.append(y) y.animation_data.action=x; + + y.matrix_local = tmp_mat[i][0] # workaround by ndee -> resets the skeleton transformation. + for j,bone in enumerate(s.pose.bones): # workaround by ndee + bone.matrix_basis = Matrix() # workaround by ndee -> resets the bone transformations. Important if bones in follwing actions miss keyframes + print("allowed skeletons "+str(allowed_skeletons)) @@ -1498,16 +1508,20 @@ class DaeExporter: self.writel(S_ANIM_CLIPS,0,'</library_animation_clips>') - for s in self.skeletons: + for i,s in enumerate(self.skeletons): # workaround by ndee if (s.animation_data==None): continue if s in cached_actions: s.animation_data.action = bpy.data.actions[cached_actions[s]] else: s.animation_data.action = None + for j,bone in enumerate(s.pose.bones): # workaround by ndee + bone.matrix_basis = tmp_mat[i][1][j] # workaround by ndee -> resets the bone transformation to what they were before exporting. else: self.export_animation(self.scene.frame_start,self.scene.frame_end) - + + + self.writel(S_ANIM,0,'</library_animations>') def export(self): |