summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--SConstruct1
-rw-r--r--core/io/resource_format_xml.cpp6
-rw-r--r--demos/3d/truck_town/crane.scnbin23916 -> 24164 bytes
-rw-r--r--demos/misc/tween/icon.pngbin0 -> 3621 bytes
-rw-r--r--doc/base/classes.xml199
-rw-r--r--drivers/gles2/rasterizer_gles2.cpp4
-rw-r--r--drivers/gles2/shaders/material.glsl2
-rw-r--r--modules/gdscript/gd_editor.cpp2
-rw-r--r--modules/gdscript/gd_parser.cpp16
-rw-r--r--modules/gdscript/gd_parser.h5
-rw-r--r--modules/gdscript/gd_script.cpp166
-rw-r--r--modules/gdscript/gd_script.h13
-rw-r--r--platform/android/export/export.cpp2
-rw-r--r--platform/isim/detect.py12
-rw-r--r--scene/2d/animated_sprite.cpp7
-rw-r--r--scene/2d/area_2d.cpp15
-rw-r--r--scene/2d/area_2d.h1
-rw-r--r--scene/2d/polygon_2d.cpp1
-rw-r--r--scene/2d/sprite.cpp6
-rw-r--r--scene/3d/area.cpp18
-rw-r--r--scene/3d/area.h1
-rw-r--r--scene/3d/light.cpp4
-rw-r--r--scene/3d/sprite_3d.cpp10
-rw-r--r--scene/3d/visual_instance.cpp8
-rw-r--r--scene/gui/text_edit.cpp19
-rw-r--r--scene/gui/tree.cpp7
-rw-r--r--scene/main/scene_main_loop.cpp3
-rw-r--r--scene/main/timer.cpp3
-rw-r--r--scene/scene_string_names.cpp2
-rw-r--r--scene/scene_string_names.h1
-rw-r--r--servers/physics/body_pair_sw.cpp2
-rw-r--r--servers/physics/collision_solver_sw.cpp44
-rw-r--r--servers/physics/collision_solver_sw.h1
-rw-r--r--servers/visual/rasterizer.cpp2
-rw-r--r--servers/visual/shader_language.cpp16
-rw-r--r--tools/editor/animation_editor.cpp35
-rw-r--r--tools/editor/editor_node.cpp2
-rw-r--r--tools/editor/editor_settings.cpp1
-rw-r--r--tools/editor/plugins/polygon_2d_editor_plugin.cpp9
-rw-r--r--tools/editor/plugins/script_editor_plugin.cpp126
-rw-r--r--tools/editor/plugins/script_editor_plugin.h2
-rw-r--r--tools/editor/plugins/shader_editor_plugin.cpp5
-rw-r--r--tools/export/blender25/io_scene_dae/export_dae.py24
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
index 080bd8ea17..2c4645af69 100644
--- a/demos/3d/truck_town/crane.scn
+++ b/demos/3d/truck_town/crane.scn
Binary files differ
diff --git a/demos/misc/tween/icon.png b/demos/misc/tween/icon.png
new file mode 100644
index 0000000000..3e991fcc29
--- /dev/null
+++ b/demos/misc/tween/icon.png
Binary files differ
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):