summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/array.cpp47
-rw-r--r--core/array.h3
-rw-r--r--core/os/rw_lock.h6
-rw-r--r--core/variant_call.cpp4
-rw-r--r--drivers/gles2/rasterizer_canvas_gles2.cpp14
-rw-r--r--drivers/gles2/rasterizer_gles2.cpp4
-rw-r--r--drivers/gles2/rasterizer_scene_gles2.cpp43
-rw-r--r--drivers/gles2/rasterizer_scene_gles2.h2
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.cpp16
-rw-r--r--drivers/gles2/shader_gles2.cpp14
-rw-r--r--drivers/gles2/shaders/canvas.glsl6
-rw-r--r--drivers/gles2/shaders/scene.glsl4
-rw-r--r--drivers/gles2/shaders/stdlib.glsl3
-rw-r--r--editor/editor_properties.cpp29
-rw-r--r--editor/editor_properties.h5
-rw-r--r--editor/plugins/animation_blend_tree_editor_plugin.cpp27
-rw-r--r--editor/scene_tree_editor.cpp5
-rw-r--r--misc/dist/html/fixed-size.html (renamed from misc/dist/html/default.html)0
-rw-r--r--misc/dist/html/full-size.html260
-rw-r--r--modules/mono/glue/cs_files/AABB.cs200
-rw-r--r--modules/mono/glue/cs_files/Rect2.cs1
-rw-r--r--platform/android/export/export.cpp10
-rw-r--r--platform/iphone/export/export.cpp22
-rw-r--r--platform/javascript/SCsub2
-rw-r--r--platform/javascript/export/export.cpp6
-rw-r--r--platform/javascript/os_javascript.cpp115
-rw-r--r--platform/javascript/os_javascript.h5
-rw-r--r--platform/osx/export/export.cpp6
-rw-r--r--platform/uwp/export/export.cpp4
-rw-r--r--scene/2d/canvas_item.h2
-rw-r--r--scene/2d/collision_object_2d.cpp4
-rw-r--r--scene/2d/physics_body_2d.cpp41
-rw-r--r--scene/2d/physics_body_2d.h1
-rw-r--r--scene/2d/remote_transform_2d.cpp7
-rw-r--r--scene/2d/sprite.cpp38
-rw-r--r--scene/2d/sprite.h2
-rw-r--r--scene/3d/camera.cpp3
-rw-r--r--scene/3d/remote_transform.cpp4
-rw-r--r--scene/animation/animation_blend_tree.cpp11
-rw-r--r--scene/animation/animation_blend_tree.h1
-rw-r--r--scene/animation/animation_node_state_machine.cpp1
-rw-r--r--scene/animation/animation_tree.cpp45
-rw-r--r--scene/animation/animation_tree.h11
-rw-r--r--scene/main/canvas_layer.cpp19
-rw-r--r--scene/main/canvas_layer.h1
-rw-r--r--scene/resources/texture.cpp145
-rw-r--r--scene/resources/texture.h19
47 files changed, 881 insertions, 337 deletions
diff --git a/core/array.cpp b/core/array.cpp
index 44c553e4eb..ebad0df126 100644
--- a/core/array.cpp
+++ b/core/array.cpp
@@ -355,11 +355,58 @@ Variant Array::pop_front() {
return Variant();
}
+Variant Array::min() const {
+
+ Variant minval;
+ for (int i = 0; i < size(); i++) {
+ if (i == 0) {
+ minval = get(i);
+ } else {
+ bool valid;
+ Variant ret;
+ Variant test = get(i);
+ Variant::evaluate(Variant::OP_LESS, test, minval, ret, valid);
+ if (!valid) {
+ return Variant(); //not a valid comparison
+ }
+ if (bool(ret)) {
+ //is less
+ minval = test;
+ }
+ }
+ }
+ return minval;
+}
+
+Variant Array::max() const {
+
+ Variant maxval;
+ for (int i = 0; i < size(); i++) {
+ if (i == 0) {
+ maxval = get(i);
+ } else {
+ bool valid;
+ Variant ret;
+ Variant test = get(i);
+ Variant::evaluate(Variant::OP_GREATER, test, maxval, ret, valid);
+ if (!valid) {
+ return Variant(); //not a valid comparison
+ }
+ if (bool(ret)) {
+ //is less
+ maxval = test;
+ }
+ }
+ }
+ return maxval;
+}
+
Array::Array(const Array &p_from) {
_p = NULL;
_ref(p_from);
}
+
Array::Array() {
_p = memnew(ArrayPrivate);
diff --git a/core/array.h b/core/array.h
index e549a886e6..c824c9b4f7 100644
--- a/core/array.h
+++ b/core/array.h
@@ -90,6 +90,9 @@ public:
Array duplicate(bool p_deep = false) const;
+ Variant min() const;
+ Variant max() const;
+
Array(const Array &p_from);
Array();
~Array();
diff --git a/core/os/rw_lock.h b/core/os/rw_lock.h
index 9053794c83..3e53300c9f 100644
--- a/core/os/rw_lock.h
+++ b/core/os/rw_lock.h
@@ -56,8 +56,10 @@ class RWLockRead {
RWLock *lock;
public:
- RWLockRead(RWLock *p_lock) {
- lock = p_lock;
+ RWLockRead(const RWLock *p_lock) {
+ if (p_lock) {
+ lock = const_cast<RWLock *>(p_lock);
+ }
if (lock) lock->read_lock();
}
~RWLockRead() {
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index 1c50df75f5..8b18b274b6 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -516,6 +516,8 @@ struct _VariantCall {
VCALL_LOCALMEM4R(Array, bsearch_custom);
VCALL_LOCALMEM1R(Array, duplicate);
VCALL_LOCALMEM0(Array, invert);
+ VCALL_LOCALMEM0R(Array, max);
+ VCALL_LOCALMEM0R(Array, min);
static void _call_PoolByteArray_get_string_from_ascii(Variant &r_ret, Variant &p_self, const Variant **p_args) {
@@ -1705,6 +1707,8 @@ void register_variant_methods() {
ADDFUNC4R(ARRAY, INT, Array, bsearch_custom, NIL, "value", OBJECT, "obj", STRING, "func", BOOL, "before", varray(true));
ADDFUNC0NC(ARRAY, NIL, Array, invert, varray());
ADDFUNC1R(ARRAY, ARRAY, Array, duplicate, BOOL, "deep", varray(false));
+ ADDFUNC0R(ARRAY, NIL, Array, max, varray());
+ ADDFUNC0R(ARRAY, NIL, Array, min, varray());
ADDFUNC0R(POOL_BYTE_ARRAY, INT, PoolByteArray, size, varray());
ADDFUNC2(POOL_BYTE_ARRAY, NIL, PoolByteArray, set, INT, "idx", INT, "byte", varray());
diff --git a/drivers/gles2/rasterizer_canvas_gles2.cpp b/drivers/gles2/rasterizer_canvas_gles2.cpp
index d6fbf04353..5b04517394 100644
--- a/drivers/gles2/rasterizer_canvas_gles2.cpp
+++ b/drivers/gles2/rasterizer_canvas_gles2.cpp
@@ -152,7 +152,7 @@ RasterizerStorageGLES2::Texture *RasterizerCanvasGLES2::_bind_canvas_texture(con
state.current_tex = RID();
state.current_tex_ptr = NULL;
- glActiveTexture(GL_TEXTURE0);
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 1);
glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex);
} else {
@@ -167,7 +167,7 @@ RasterizerStorageGLES2::Texture *RasterizerCanvasGLES2::_bind_canvas_texture(con
texture->render_target->used_in_frame = true;
}
- glActiveTexture(GL_TEXTURE0);
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 1);
glBindTexture(GL_TEXTURE_2D, texture->tex_id);
state.current_tex = p_texture;
@@ -179,7 +179,7 @@ RasterizerStorageGLES2::Texture *RasterizerCanvasGLES2::_bind_canvas_texture(con
state.current_tex = RID();
state.current_tex_ptr = NULL;
- glActiveTexture(GL_TEXTURE0);
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 1);
glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex);
}
@@ -889,7 +889,7 @@ void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, cons
for (int i = 0; i < tc; i++) {
- glActiveTexture(GL_TEXTURE2 + i);
+ glActiveTexture(GL_TEXTURE0 + i);
RasterizerStorageGLES2::Texture *t = storage->texture_owner.getornull(textures[i].second);
@@ -937,7 +937,7 @@ void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, cons
}
int blend_mode = shader_cache ? shader_cache->canvas_item.blend_mode : RasterizerStorageGLES2::Shader::CanvasItem::BLEND_MODE_MIX;
- bool unshaded = true || (shader_cache && blend_mode != RasterizerStorageGLES2::Shader::CanvasItem::BLEND_MODE_MIX);
+ bool unshaded = (shader_cache && blend_mode != RasterizerStorageGLES2::Shader::CanvasItem::BLEND_MODE_MIX);
bool reclip = false;
if (last_blend_mode != blend_mode) {
@@ -1027,8 +1027,8 @@ void RasterizerCanvasGLES2::reset_canvas() {
// keeping this for now as there's nothing else that uses texture unit 2
// TODO ^
if (storage->frame.current_rt) {
- glActiveTexture(GL_TEXTURE0 + 2);
- glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->copy_screen_effect.color);
+ // glActiveTexture(GL_TEXTURE0 + 2);
+ // glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->copy_screen_effect.color);
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp
index a1a0b9e2c6..8815205054 100644
--- a/drivers/gles2/rasterizer_gles2.cpp
+++ b/drivers/gles2/rasterizer_gles2.cpp
@@ -327,7 +327,7 @@ void RasterizerGLES2::set_boot_image(const Ref<Image> &p_image, const Color &p_c
screenrect.position += ((Size2(window_w, window_h) - screenrect.size) / 2.0).floor();
RasterizerStorageGLES2::Texture *t = storage->texture_owner.get(texture);
- glActiveTexture(GL_TEXTURE0);
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 1);
glBindTexture(GL_TEXTURE_2D, t->tex_id);
canvas->draw_generic_textured_rect(screenrect, Rect2(0, 0, 1, 1));
glBindTexture(GL_TEXTURE_2D, 0);
@@ -354,7 +354,7 @@ void RasterizerGLES2::blit_render_target_to_screen(RID p_render_target, const Re
canvas->canvas_begin();
glDisable(GL_BLEND);
glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES2::system_fbo);
- glActiveTexture(GL_TEXTURE0);
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 1);
glBindTexture(GL_TEXTURE_2D, rt->color);
// TODO normals
diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp
index 5d20868294..e21998d55e 100644
--- a/drivers/gles2/rasterizer_scene_gles2.cpp
+++ b/drivers/gles2/rasterizer_scene_gles2.cpp
@@ -837,7 +837,7 @@ static const GLenum gl_primitive[] = {
GL_TRIANGLE_FAN
};
-void RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_material, bool p_reverse_cull, Size2i p_skeleton_tex_size) {
+void RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_material, bool p_reverse_cull, bool p_alpha_pass, Size2i p_skeleton_tex_size) {
// material parameters
@@ -851,6 +851,20 @@ void RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_m
glEnable(GL_DEPTH_TEST);
}
+ switch (p_material->shader->spatial.depth_draw_mode) {
+ case RasterizerStorageGLES2::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS:
+ case RasterizerStorageGLES2::Shader::Spatial::DEPTH_DRAW_OPAQUE: {
+
+ glDepthMask(!p_alpha_pass);
+ } break;
+ case RasterizerStorageGLES2::Shader::Spatial::DEPTH_DRAW_ALWAYS: {
+ glDepthMask(GL_TRUE);
+ } break;
+ case RasterizerStorageGLES2::Shader::Spatial::DEPTH_DRAW_NEVER: {
+ glDepthMask(GL_FALSE);
+ } break;
+ }
+
// TODO whyyyyy????
p_reverse_cull = true;
@@ -913,8 +927,8 @@ void RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_m
void RasterizerSceneGLES2::_setup_geometry(RenderList::Element *p_element, RasterizerStorageGLES2::Skeleton *p_skeleton) {
state.scene_shader.set_conditional(SceneShaderGLES2::USE_SKELETON, p_skeleton != NULL);
- // state.scene_shader.set_conditional(SceneShaderGLES2::USE_SKELETON_SOFTWARE, !storage->config.float_texture_supported);
- state.scene_shader.set_conditional(SceneShaderGLES2::USE_SKELETON_SOFTWARE, true);
+ state.scene_shader.set_conditional(SceneShaderGLES2::USE_SKELETON_SOFTWARE, !storage->config.float_texture_supported);
+ // state.scene_shader.set_conditional(SceneShaderGLES2::USE_SKELETON_SOFTWARE, true);
switch (p_element->instance->base_type) {
@@ -951,9 +965,9 @@ void RasterizerSceneGLES2::_setup_geometry(RenderList::Element *p_element, Raste
} break;
}
- if (false && storage->config.float_texture_supported) {
+ if (storage->config.float_texture_supported) {
if (p_skeleton) {
- glActiveTexture(GL_TEXTURE4);
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 1);
glBindTexture(GL_TEXTURE_2D, p_skeleton->tex_id);
}
@@ -1202,6 +1216,12 @@ void RasterizerSceneGLES2::_render_geometry(RenderList::Element *p_element) {
glDisableVertexAttribArray(15); // color
glDisableVertexAttribArray(8); // custom data
+ if (!s->attribs[VS::ARRAY_COLOR].enabled) {
+ glDisableVertexAttribArray(VS::ARRAY_COLOR);
+
+ glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1);
+ }
+
glVertexAttrib4f(15, 1, 1, 1, 1);
glVertexAttrib4f(8, 0, 0, 0, 0);
@@ -1245,7 +1265,12 @@ void RasterizerSceneGLES2::_render_geometry(RenderList::Element *p_element) {
}
if (multi_mesh->color_floats) {
- glVertexAttrib4fv(15, buffer + color_ofs);
+ if (multi_mesh->color_format == VS::MULTIMESH_COLOR_8BIT) {
+ uint8_t *color_data = (uint8_t *)(buffer + color_ofs);
+ glVertexAttrib4f(15, color_data[0] / 255.0, color_data[1] / 255.0, color_data[2] / 255.0, color_data[3] / 255.0);
+ } else {
+ glVertexAttrib4fv(15, buffer + color_ofs);
+ }
}
if (multi_mesh->custom_data_floats) {
@@ -1432,7 +1457,7 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
_setup_geometry(e, skeleton);
- _setup_material(material, p_reverse_cull, Size2i(skeleton ? skeleton->size * 3 : 0, 0));
+ _setup_material(material, p_reverse_cull, p_alpha_pass, Size2i(skeleton ? skeleton->size * 3 : 0, 0));
if (use_radiance_map) {
state.scene_shader.set_uniform(SceneShaderGLES2::RADIANCE_INVERSE_XFORM, p_view_transform);
@@ -1568,7 +1593,7 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
{
_setup_geometry(e, skeleton);
- _setup_material(material, p_reverse_cull, Size2i(skeleton ? skeleton->size * 3 : 0, 0));
+ _setup_material(material, p_reverse_cull, p_alpha_pass, Size2i(skeleton ? skeleton->size * 3 : 0, 0));
if (shadow_atlas != NULL) {
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 4);
glBindTexture(GL_TEXTURE_2D, shadow_atlas->depth);
@@ -1757,7 +1782,7 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
RasterizerStorageGLES2::Skeleton *skeleton = storage->skeleton_owner.getornull(e->instance->skeleton);
{
- _setup_material(material, p_reverse_cull, Size2i(skeleton ? skeleton->size * 3 : 0, 0));
+ _setup_material(material, p_reverse_cull, false, Size2i(skeleton ? skeleton->size * 3 : 0, 0));
if (directional_shadow.depth) {
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 4); // TODO move into base pass
diff --git a/drivers/gles2/rasterizer_scene_gles2.h b/drivers/gles2/rasterizer_scene_gles2.h
index e153080e15..72dbe14387 100644
--- a/drivers/gles2/rasterizer_scene_gles2.h
+++ b/drivers/gles2/rasterizer_scene_gles2.h
@@ -563,7 +563,7 @@ public:
void _draw_sky(RasterizerStorageGLES2::Sky *p_sky, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_custom_fov, float p_energy);
- void _setup_material(RasterizerStorageGLES2::Material *p_material, bool p_reverse_cull, Size2i p_skeleton_tex_size = Size2i(0, 0));
+ void _setup_material(RasterizerStorageGLES2::Material *p_material, bool p_reverse_cull, bool p_alpha_pass, Size2i p_skeleton_tex_size = Size2i(0, 0));
void _setup_geometry(RenderList::Element *p_element, RasterizerStorageGLES2::Skeleton *p_skeleton);
void _render_geometry(RenderList::Element *p_element);
diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp
index e2d8ec1178..262add1cc3 100644
--- a/drivers/gles2/rasterizer_storage_gles2.cpp
+++ b/drivers/gles2/rasterizer_storage_gles2.cpp
@@ -384,6 +384,10 @@ void RasterizerStorageGLES2::texture_allocate(RID p_texture, int p_width, int p_
case VS::TEXTURE_TYPE_3D: {
texture->images.resize(p_depth_3d);
} break;
+ default: {
+ ERR_PRINT("Unknown texture type!");
+ return;
+ }
}
Image::Format real_format;
@@ -636,6 +640,8 @@ void RasterizerStorageGLES2::texture_set_flags(RID p_texture, uint32_t p_flags)
bool had_mipmaps = texture->flags & VS::TEXTURE_FLAG_MIPMAPS;
+ texture->flags = p_flags;
+
glActiveTexture(GL_TEXTURE0);
glBindTexture(texture->target, texture->tex_id);
@@ -1303,6 +1309,10 @@ void RasterizerStorageGLES2::shader_get_param_list(RID p_shader, List<PropertyIn
pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
pi.hint_string = "CubeMap";
} break;
+
+ default: {
+
+ } break;
}
p_param_list->push_back(pi);
@@ -2848,7 +2858,11 @@ void RasterizerStorageGLES2::skeleton_allocate(RID p_skeleton, int p_bones, bool
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, skeleton->tex_id);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, p_bones * 3, 1, 0, GL_RGB, GL_FLOAT, NULL);
+#ifdef GLES_OVER_GL
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, p_bones * 3, 1, 0, GL_RGBA, GL_FLOAT, NULL);
+#else
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, p_bones * 3, 1, 0, GL_RGBA, GL_FLOAT, NULL);
+#endif
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
diff --git a/drivers/gles2/shader_gles2.cpp b/drivers/gles2/shader_gles2.cpp
index e9b58cb272..5cdbdf84e0 100644
--- a/drivers/gles2/shader_gles2.cpp
+++ b/drivers/gles2/shader_gles2.cpp
@@ -967,19 +967,7 @@ void ShaderGLES2::use_material(void *p_material) {
value.second.write[15].real = 1;
} break;
- case ShaderLanguage::TYPE_SAMPLER2D: {
-
- } break;
-
- case ShaderLanguage::TYPE_ISAMPLER2D: {
-
- } break;
-
- case ShaderLanguage::TYPE_USAMPLER2D: {
-
- } break;
-
- case ShaderLanguage::TYPE_SAMPLERCUBE: {
+ default: {
} break;
}
diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl
index 29d81bb2c4..e97822f9bf 100644
--- a/drivers/gles2/shaders/canvas.glsl
+++ b/drivers/gles2/shaders/canvas.glsl
@@ -96,9 +96,9 @@ precision mediump float;
precision mediump int;
#endif
-uniform sampler2D color_texture; // texunit:0
+uniform sampler2D color_texture; // texunit:-1
uniform highp vec2 color_texpixel_size;
-uniform mediump sampler2D normal_texture; // texunit:1
+uniform mediump sampler2D normal_texture; // texunit:-2
varying mediump vec2 uv_interp;
varying mediump vec4 color_interp;
@@ -109,7 +109,7 @@ uniform vec4 final_modulate;
#ifdef SCREEN_TEXTURE_USED
-uniform sampler2D screen_texture; // texunit:2
+uniform sampler2D screen_texture; // texunit:-3
#endif
diff --git a/drivers/gles2/shaders/scene.glsl b/drivers/gles2/shaders/scene.glsl
index 204f22c046..2c9d4f01a3 100644
--- a/drivers/gles2/shaders/scene.glsl
+++ b/drivers/gles2/shaders/scene.glsl
@@ -168,7 +168,7 @@ void main() {
#ifdef USE_SKELETON
- highp mat4 bone_transform = mat4(1.0);
+ highp mat4 bone_transform = mat4(0.0);
#ifdef USE_SKELETON_SOFTWARE
// passing the transform as attributes
@@ -189,7 +189,7 @@ void main() {
texel2DFetch(bone_transforms, skeleton_texture_size, tex_ofs + ivec2(1, 0)),
texel2DFetch(bone_transforms, skeleton_texture_size, tex_ofs + ivec2(2, 0)),
vec4(0.0, 0.0, 0.0, 1.0));
-
+
bone_transform += transpose(b) * bone_weights[i];
}
}
diff --git a/drivers/gles2/shaders/stdlib.glsl b/drivers/gles2/shaders/stdlib.glsl
index ebbdb96311..8b30e097e6 100644
--- a/drivers/gles2/shaders/stdlib.glsl
+++ b/drivers/gles2/shaders/stdlib.glsl
@@ -38,8 +38,5 @@ highp vec4 texel2DFetch(highp sampler2D tex, ivec2 size, ivec2 coord)
float x_coord = float(2 * coord.x + 1) / float(size.x * 2);
float y_coord = float(2 * coord.y + 1) / float(size.y * 2);
- x_coord = float(coord.x) / float(size.x);
- y_coord = float(coord.y) / float(size.y);
-
return texture2DLod(tex, vec2(x_coord, y_coord), 0.0);
}
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index 5f1e7273e5..3c3df6b8ef 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -258,19 +258,40 @@ void EditorPropertyPath::setup(const Vector<String> &p_extensions, bool p_folder
global = p_global;
}
+void EditorPropertyPath::_notification(int p_what) {
+
+ if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
+ path_edit->set_icon(get_icon("Folder", "EditorIcons"));
+ }
+}
+
+void EditorPropertyPath::_path_focus_exited() {
+
+ _path_selected(path->get_text());
+}
+
void EditorPropertyPath::_bind_methods() {
ClassDB::bind_method(D_METHOD("_path_pressed"), &EditorPropertyPath::_path_pressed);
ClassDB::bind_method(D_METHOD("_path_selected"), &EditorPropertyPath::_path_selected);
+ ClassDB::bind_method(D_METHOD("_path_focus_exited"), &EditorPropertyPath::_path_focus_exited);
}
EditorPropertyPath::EditorPropertyPath() {
- path = memnew(Button);
- path->set_clip_text(true);
- add_child(path);
+ HBoxContainer *path_hb = memnew(HBoxContainer);
+ add_child(path_hb);
+ path = memnew(LineEdit);
+ path_hb->add_child(path);
+ path->connect("text_entered", this, "_path_selected");
+ path->connect("focus_exited", this, "_path_focus_exited");
+ path->set_h_size_flags(SIZE_EXPAND_FILL);
+
+ path_edit = memnew(Button);
+ path_edit->set_clip_text(true);
+ path_hb->add_child(path_edit);
add_focusable(path);
dialog = NULL;
- path->connect("pressed", this, "_path_pressed");
+ path_edit->connect("pressed", this, "_path_pressed");
folder = false;
global = false;
}
diff --git a/editor/editor_properties.h b/editor/editor_properties.h
index 5726ccfa41..cfc433b880 100644
--- a/editor/editor_properties.h
+++ b/editor/editor_properties.h
@@ -107,13 +107,16 @@ class EditorPropertyPath : public EditorProperty {
bool folder;
bool global;
EditorFileDialog *dialog;
- Button *path;
+ LineEdit *path;
+ Button *path_edit;
void _path_selected(const String &p_path);
void _path_pressed();
+ void _path_focus_exited();
protected:
static void _bind_methods();
+ void _notification(int p_what);
public:
void setup(const Vector<String> &p_extensions, bool p_folder, bool p_global);
diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp
index 42e32b9788..9530fae8e4 100644
--- a/editor/plugins/animation_blend_tree_editor_plugin.cpp
+++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp
@@ -650,8 +650,9 @@ void AnimationNodeBlendTreeEditor::_notification(int p_what) {
blend_tree->get_node_connections(&conns);
for (List<AnimationNodeBlendTree::NodeConnection>::Element *E = conns.front(); E; E = E->next()) {
float activity = 0;
+ StringName path = AnimationTreeEditor::get_singleton()->get_base_path() + E->get().input_node;
if (AnimationTreeEditor::get_singleton()->get_tree() && !AnimationTreeEditor::get_singleton()->get_tree()->is_state_invalid()) {
- activity = blend_tree->get_connection_activity(E->get().input_node, E->get().input_index);
+ activity = AnimationTreeEditor::get_singleton()->get_tree()->get_connection_activity(path, E->get().input_index);
}
graph->set_connection_activity(E->get().output_node, 0, E->get().input_node, E->get().input_index, activity);
}
@@ -777,6 +778,30 @@ void AnimationNodeBlendTreeEditor::_node_renamed(const String &p_text, Ref<Anima
visible_properties[i]->set_object_and_property(visible_properties[i]->get_edited_object(), new_name);
}
}
+
+ //recreate connections
+ graph->clear_connections();
+
+ List<AnimationNodeBlendTree::NodeConnection> connections;
+ blend_tree->get_node_connections(&connections);
+
+ for (List<AnimationNodeBlendTree::NodeConnection>::Element *E = connections.front(); E; E = E->next()) {
+
+ StringName from = E->get().output_node;
+ StringName to = E->get().input_node;
+ int to_idx = E->get().input_index;
+
+ graph->connect_node(from, 0, to, to_idx);
+ }
+
+ //update animations
+ for (Map<StringName, ProgressBar *>::Element *E = animations.front(); E; E = E->next()) {
+ if (E->key() == prev_name) {
+ animations[new_name] = animations[prev_name];
+ animations.erase(prev_name);
+ break;
+ }
+ }
}
void AnimationNodeBlendTreeEditor::_node_renamed_focus_out(Node *le, Ref<AnimationNode> p_node) {
diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp
index 88d614ab89..47db656017 100644
--- a/editor/scene_tree_editor.cpp
+++ b/editor/scene_tree_editor.cpp
@@ -521,8 +521,10 @@ void SceneTreeEditor::_selected_changed() {
void SceneTreeEditor::_deselect_items() {
// Clear currently elected items in scene tree dock.
- if (editor_selection)
+ if (editor_selection) {
editor_selection->clear();
+ emit_signal("node_changed");
+ }
}
void SceneTreeEditor::_cell_multi_selected(Object *p_object, int p_cell, bool p_selected) {
@@ -546,6 +548,7 @@ void SceneTreeEditor::_cell_multi_selected(Object *p_object, int p_cell, bool p_
} else {
editor_selection->remove_node(n);
}
+ emit_signal("node_changed");
}
void SceneTreeEditor::_notification(int p_what) {
diff --git a/misc/dist/html/default.html b/misc/dist/html/fixed-size.html
index 14766e8239..14766e8239 100644
--- a/misc/dist/html/default.html
+++ b/misc/dist/html/fixed-size.html
diff --git a/misc/dist/html/full-size.html b/misc/dist/html/full-size.html
new file mode 100644
index 0000000000..44b009524c
--- /dev/null
+++ b/misc/dist/html/full-size.html
@@ -0,0 +1,260 @@
+<!DOCTYPE html>
+<html xmlns='http://www.w3.org/1999/xhtml' lang='' xml:lang=''>
+<head>
+ <meta charset='utf-8' />
+ <meta name='viewport' content='width=device-width, user-scalable=no' />
+ <title></title>
+ <style type='text/css'>
+
+ body {
+ touch-action: none;
+ margin: 0;
+ border: 0 none;
+ padding: 0;
+ text-align: center;
+ background-color: black;
+ }
+
+ #canvas {
+ display: block;
+ margin: 0;
+ color: white;
+ }
+
+ #canvas:focus {
+ outline: none;
+ }
+
+ .godot {
+ font-family: 'Noto Sans', 'Droid Sans', Arial, sans-serif;
+ color: #e0e0e0;
+ background-color: #3b3943;
+ background-image: linear-gradient(to bottom, #403e48, #35333c);
+ border: 1px solid #45434e;
+ box-shadow: 0 0 1px 1px #2f2d35;
+ }
+
+
+ /* Status display
+ * ============== */
+
+ #status {
+ position: absolute;
+ left: 0;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ /* don't consume click events - make children visible explicitly */
+ visibility: hidden;
+ }
+
+ #status-progress {
+ width: 366px;
+ height: 7px;
+ background-color: #38363A;
+ border: 1px solid #444246;
+ padding: 1px;
+ box-shadow: 0 0 2px 1px #1B1C22;
+ border-radius: 2px;
+ visibility: visible;
+ }
+
+ @media only screen and (orientation:portrait) {
+ #status-progress {
+ width: 61.8%;
+ }
+ }
+
+ #status-progress-inner {
+ height: 100%;
+ width: 0;
+ box-sizing: border-box;
+ transition: width 0.5s linear;
+ background-color: #202020;
+ border: 1px solid #222223;
+ box-shadow: 0 0 1px 1px #27282E;
+ border-radius: 3px;
+ }
+
+ #status-indeterminate {
+ visibility: visible;
+ position: relative;
+ }
+
+ #status-indeterminate > div {
+ width: 4.5px;
+ height: 0;
+ border-style: solid;
+ border-width: 9px 3px 0 3px;
+ border-color: #2b2b2b transparent transparent transparent;
+ transform-origin: center 21px;
+ position: absolute;
+ }
+
+ #status-indeterminate > div:nth-child(1) { transform: rotate( 22.5deg); }
+ #status-indeterminate > div:nth-child(2) { transform: rotate( 67.5deg); }
+ #status-indeterminate > div:nth-child(3) { transform: rotate(112.5deg); }
+ #status-indeterminate > div:nth-child(4) { transform: rotate(157.5deg); }
+ #status-indeterminate > div:nth-child(5) { transform: rotate(202.5deg); }
+ #status-indeterminate > div:nth-child(6) { transform: rotate(247.5deg); }
+ #status-indeterminate > div:nth-child(7) { transform: rotate(292.5deg); }
+ #status-indeterminate > div:nth-child(8) { transform: rotate(337.5deg); }
+
+ #status-notice {
+ margin: 0 100px;
+ line-height: 1.3;
+ visibility: visible;
+ padding: 4px 6px;
+ visibility: visible;
+ }
+ </style>
+$GODOT_HEAD_INCLUDE
+</head>
+<body>
+ <canvas id='canvas'>
+ HTML5 canvas appears to be unsupported in the current browser.<br />
+ Please try updating or use a different browser.
+ </canvas>
+ <div id='status'>
+ <div id='status-progress' style='display: none;' oncontextmenu='event.preventDefault();'><div id ='status-progress-inner'></div></div>
+ <div id='status-indeterminate' style='display: none;' oncontextmenu='event.preventDefault();'>
+ <div></div>
+ <div></div>
+ <div></div>
+ <div></div>
+ <div></div>
+ <div></div>
+ <div></div>
+ <div></div>
+ </div>
+ <div id='status-notice' class='godot' style='display: none;'></div>
+ </div>
+
+ <script type='text/javascript' src='$GODOT_BASENAME.js'></script>
+ <script type='text/javascript'>//<![CDATA[
+
+ var engine = new Engine;
+ var setStatusMode;
+ var setStatusNotice;
+
+ (function() {
+
+ const MAIN_PACK = '$GODOT_BASENAME.pck';
+ const INDETERMINATE_STATUS_STEP_MS = 100;
+
+ var canvas = document.getElementById('canvas');
+ var statusProgress = document.getElementById('status-progress');
+ var statusProgressInner = document.getElementById('status-progress-inner');
+ var statusIndeterminate = document.getElementById('status-indeterminate');
+ var statusNotice = document.getElementById('status-notice');
+
+ var initializing = true;
+ var statusMode = 'hidden';
+
+ var animationCallbacks = [];
+ function animate(time) {
+ animationCallbacks.forEach(callback => callback(time));
+ requestAnimationFrame(animate);
+ }
+ requestAnimationFrame(animate);
+
+ function adjustCanvasDimensions() {
+ canvas.width = innerWidth;
+ canvas.height = innerHeight;
+ }
+ animationCallbacks.push(adjustCanvasDimensions);
+ adjustCanvasDimensions();
+
+ setStatusMode = function setStatusMode(mode) {
+
+ if (statusMode === mode || !initializing)
+ return;
+ [statusProgress, statusIndeterminate, statusNotice].forEach(elem => {
+ elem.style.display = 'none';
+ });
+ if (animateStatusIndeterminate in animationCallbacks) {
+ animationCallbacks.erase(animateStatusIndeterminate);
+ }
+ switch (mode) {
+ case 'progress':
+ statusProgress.style.display = 'block';
+ break;
+ case 'indeterminate':
+ statusIndeterminate.style.display = 'block';
+ animationCallbacks.push(animateStatusIndeterminate);
+ break;
+ case 'notice':
+ statusNotice.style.display = 'block';
+ break;
+ case 'hidden':
+ break;
+ default:
+ throw new Error('Invalid status mode');
+ }
+ statusMode = mode;
+ }
+
+ function animateStatusIndeterminate(ms) {
+
+ var i = Math.floor(ms / INDETERMINATE_STATUS_STEP_MS % 8);
+ if (statusIndeterminate.children[i].style.borderTopColor == '') {
+ Array.prototype.slice.call(statusIndeterminate.children).forEach(child => {
+ child.style.borderTopColor = '';
+ });
+ statusIndeterminate.children[i].style.borderTopColor = '#dfdfdf';
+ }
+ }
+
+ setStatusNotice = function setStatusNotice(text) {
+
+ while (statusNotice.lastChild) {
+ statusNotice.removeChild(statusNotice.lastChild);
+ }
+ var lines = text.split('\n');
+ lines.forEach((line) => {
+ statusNotice.appendChild(document.createTextNode(line));
+ statusNotice.appendChild(document.createElement('br'));
+ });
+ };
+
+ engine.setProgressFunc((current, total) => {
+
+ if (total > 0) {
+ statusProgressInner.style.width = current/total * 100 + '%';
+ setStatusMode('progress');
+ if (current === total) {
+ // wait for progress bar animation
+ setTimeout(() => {
+ setStatusMode('indeterminate');
+ }, 500);
+ }
+ } else {
+ setStatusMode('indeterminate');
+ }
+ });
+
+ function displayFailureNotice(err) {
+ var msg = err.message || err;
+ console.error(msg);
+ setStatusNotice(msg);
+ setStatusMode('notice');
+ initializing = false;
+ };
+
+ if (!Engine.isWebGLAvailable()) {
+ displayFailureNotice('WebGL not available');
+ } else {
+ setStatusMode('indeterminate');
+ engine.setCanvas(canvas);
+ engine.startGame(MAIN_PACK).then(() => {
+ setStatusMode('hidden');
+ initializing = false;
+ }, displayFailureNotice);
+ }
+ })();
+ //]]></script>
+</body>
+</html>
diff --git a/modules/mono/glue/cs_files/AABB.cs b/modules/mono/glue/cs_files/AABB.cs
index 39f2d2ed51..0df2e615f1 100644
--- a/modules/mono/glue/cs_files/AABB.cs
+++ b/modules/mono/glue/cs_files/AABB.cs
@@ -15,39 +15,33 @@ namespace Godot
{
public struct AABB : IEquatable<AABB>
{
- private Vector3 position;
- private Vector3 size;
+ private Vector3 _position;
+ private Vector3 _size;
public Vector3 Position
{
- get
- {
- return position;
- }
+ get { return _position; }
+ set { _position = value; }
}
public Vector3 Size
{
- get
- {
- return size;
- }
+ get { return _size; }
+ set { _size = value; }
}
public Vector3 End
{
- get
- {
- return position + size;
- }
+ get { return _position + _size; }
+ set { _size = value - _position; }
}
public bool Encloses(AABB with)
{
- Vector3 src_min = position;
- Vector3 src_max = position + size;
- Vector3 dst_min = with.position;
- Vector3 dst_max = with.position + with.size;
+ Vector3 src_min = _position;
+ Vector3 src_max = _position + _size;
+ Vector3 dst_min = with._position;
+ Vector3 dst_max = with._position + with._size;
return src_min.x <= dst_min.x &&
src_max.x > dst_max.x &&
@@ -59,8 +53,8 @@ namespace Godot
public AABB Expand(Vector3 to_point)
{
- Vector3 begin = position;
- Vector3 end = position + size;
+ Vector3 begin = _position;
+ Vector3 end = _position + _size;
if (to_point.x < begin.x)
begin.x = to_point.x;
@@ -81,7 +75,7 @@ namespace Godot
public real_t GetArea()
{
- return size.x * size.y * size.z;
+ return _size.x * _size.y * _size.z;
}
public Vector3 GetEndpoint(int idx)
@@ -89,21 +83,21 @@ namespace Godot
switch (idx)
{
case 0:
- return new Vector3(position.x, position.y, position.z);
+ return new Vector3(_position.x, _position.y, _position.z);
case 1:
- return new Vector3(position.x, position.y, position.z + size.z);
+ return new Vector3(_position.x, _position.y, _position.z + _size.z);
case 2:
- return new Vector3(position.x, position.y + size.y, position.z);
+ return new Vector3(_position.x, _position.y + _size.y, _position.z);
case 3:
- return new Vector3(position.x, position.y + size.y, position.z + size.z);
+ return new Vector3(_position.x, _position.y + _size.y, _position.z + _size.z);
case 4:
- return new Vector3(position.x + size.x, position.y, position.z);
+ return new Vector3(_position.x + _size.x, _position.y, _position.z);
case 5:
- return new Vector3(position.x + size.x, position.y, position.z + size.z);
+ return new Vector3(_position.x + _size.x, _position.y, _position.z + _size.z);
case 6:
- return new Vector3(position.x + size.x, position.y + size.y, position.z);
+ return new Vector3(_position.x + _size.x, _position.y + _size.y, _position.z);
case 7:
- return new Vector3(position.x + size.x, position.y + size.y, position.z + size.z);
+ return new Vector3(_position.x + _size.x, _position.y + _size.y, _position.z + _size.z);
default:
throw new ArgumentOutOfRangeException(nameof(idx), String.Format("Index is {0}, but a value from 0 to 7 is expected.", idx));
}
@@ -112,15 +106,15 @@ namespace Godot
public Vector3 GetLongestAxis()
{
var axis = new Vector3(1f, 0f, 0f);
- real_t max_size = size.x;
+ real_t max_size = _size.x;
- if (size.y > max_size)
+ if (_size.y > max_size)
{
axis = new Vector3(0f, 1f, 0f);
- max_size = size.y;
+ max_size = _size.y;
}
- if (size.z > max_size)
+ if (_size.z > max_size)
{
axis = new Vector3(0f, 0f, 1f);
}
@@ -131,15 +125,15 @@ namespace Godot
public Vector3.Axis GetLongestAxisIndex()
{
var axis = Vector3.Axis.X;
- real_t max_size = size.x;
+ real_t max_size = _size.x;
- if (size.y > max_size)
+ if (_size.y > max_size)
{
axis = Vector3.Axis.Y;
- max_size = size.y;
+ max_size = _size.y;
}
- if (size.z > max_size)
+ if (_size.z > max_size)
{
axis = Vector3.Axis.Z;
}
@@ -149,13 +143,13 @@ namespace Godot
public real_t GetLongestAxisSize()
{
- real_t max_size = size.x;
+ real_t max_size = _size.x;
- if (size.y > max_size)
- max_size = size.y;
+ if (_size.y > max_size)
+ max_size = _size.y;
- if (size.z > max_size)
- max_size = size.z;
+ if (_size.z > max_size)
+ max_size = _size.z;
return max_size;
}
@@ -163,15 +157,15 @@ namespace Godot
public Vector3 GetShortestAxis()
{
var axis = new Vector3(1f, 0f, 0f);
- real_t max_size = size.x;
+ real_t max_size = _size.x;
- if (size.y < max_size)
+ if (_size.y < max_size)
{
axis = new Vector3(0f, 1f, 0f);
- max_size = size.y;
+ max_size = _size.y;
}
- if (size.z < max_size)
+ if (_size.z < max_size)
{
axis = new Vector3(0f, 0f, 1f);
}
@@ -182,15 +176,15 @@ namespace Godot
public Vector3.Axis GetShortestAxisIndex()
{
var axis = Vector3.Axis.X;
- real_t max_size = size.x;
+ real_t max_size = _size.x;
- if (size.y < max_size)
+ if (_size.y < max_size)
{
axis = Vector3.Axis.Y;
- max_size = size.y;
+ max_size = _size.y;
}
- if (size.z < max_size)
+ if (_size.z < max_size)
{
axis = Vector3.Axis.Z;
}
@@ -200,21 +194,21 @@ namespace Godot
public real_t GetShortestAxisSize()
{
- real_t max_size = size.x;
+ real_t max_size = _size.x;
- if (size.y < max_size)
- max_size = size.y;
+ if (_size.y < max_size)
+ max_size = _size.y;
- if (size.z < max_size)
- max_size = size.z;
+ if (_size.z < max_size)
+ max_size = _size.z;
return max_size;
}
public Vector3 GetSupport(Vector3 dir)
{
- Vector3 half_extents = size * 0.5f;
- Vector3 ofs = position + half_extents;
+ Vector3 half_extents = _size * 0.5f;
+ Vector3 ofs = _position + half_extents;
return ofs + new Vector3(
dir.x > 0f ? -half_extents.x : half_extents.x,
@@ -226,39 +220,39 @@ namespace Godot
{
var res = this;
- res.position.x -= by;
- res.position.y -= by;
- res.position.z -= by;
- res.size.x += 2.0f * by;
- res.size.y += 2.0f * by;
- res.size.z += 2.0f * by;
+ res._position.x -= by;
+ res._position.y -= by;
+ res._position.z -= by;
+ res._size.x += 2.0f * by;
+ res._size.y += 2.0f * by;
+ res._size.z += 2.0f * by;
return res;
}
public bool HasNoArea()
{
- return size.x <= 0f || size.y <= 0f || size.z <= 0f;
+ return _size.x <= 0f || _size.y <= 0f || _size.z <= 0f;
}
public bool HasNoSurface()
{
- return size.x <= 0f && size.y <= 0f && size.z <= 0f;
+ return _size.x <= 0f && _size.y <= 0f && _size.z <= 0f;
}
public bool HasPoint(Vector3 point)
{
- if (point.x < position.x)
+ if (point.x < _position.x)
return false;
- if (point.y < position.y)
+ if (point.y < _position.y)
return false;
- if (point.z < position.z)
+ if (point.z < _position.z)
return false;
- if (point.x > position.x + size.x)
+ if (point.x > _position.x + _size.x)
return false;
- if (point.y > position.y + size.y)
+ if (point.y > _position.y + _size.y)
return false;
- if (point.z > position.z + size.z)
+ if (point.z > _position.z + _size.z)
return false;
return true;
@@ -266,10 +260,10 @@ namespace Godot
public AABB Intersection(AABB with)
{
- Vector3 src_min = position;
- Vector3 src_max = position + size;
- Vector3 dst_min = with.position;
- Vector3 dst_max = with.position + with.size;
+ Vector3 src_min = _position;
+ Vector3 src_max = _position + _size;
+ Vector3 dst_min = with._position;
+ Vector3 dst_max = with._position + with._size;
Vector3 min, max;
@@ -302,17 +296,17 @@ namespace Godot
public bool Intersects(AABB with)
{
- if (position.x >= with.position.x + with.size.x)
+ if (_position.x >= with._position.x + with._size.x)
return false;
- if (position.x + size.x <= with.position.x)
+ if (_position.x + _size.x <= with._position.x)
return false;
- if (position.y >= with.position.y + with.size.y)
+ if (_position.y >= with._position.y + with._size.y)
return false;
- if (position.y + size.y <= with.position.y)
+ if (_position.y + _size.y <= with._position.y)
return false;
- if (position.z >= with.position.z + with.size.z)
+ if (_position.z >= with._position.z + with._size.z)
return false;
- if (position.z + size.z <= with.position.z)
+ if (_position.z + _size.z <= with._position.z)
return false;
return true;
@@ -322,14 +316,14 @@ namespace Godot
{
Vector3[] points =
{
- new Vector3(position.x, position.y, position.z),
- new Vector3(position.x, position.y, position.z + size.z),
- new Vector3(position.x, position.y + size.y, position.z),
- new Vector3(position.x, position.y + size.y, position.z + size.z),
- new Vector3(position.x + size.x, position.y, position.z),
- new Vector3(position.x + size.x, position.y, position.z + size.z),
- new Vector3(position.x + size.x, position.y + size.y, position.z),
- new Vector3(position.x + size.x, position.y + size.y, position.z + size.z)
+ new Vector3(_position.x, _position.y, _position.z),
+ new Vector3(_position.x, _position.y, _position.z + _size.z),
+ new Vector3(_position.x, _position.y + _size.y, _position.z),
+ new Vector3(_position.x, _position.y + _size.y, _position.z + _size.z),
+ new Vector3(_position.x + _size.x, _position.y, _position.z),
+ new Vector3(_position.x + _size.x, _position.y, _position.z + _size.z),
+ new Vector3(_position.x + _size.x, _position.y + _size.y, _position.z),
+ new Vector3(_position.x + _size.x, _position.y + _size.y, _position.z + _size.z)
};
bool over = false;
@@ -355,8 +349,8 @@ namespace Godot
{
real_t seg_from = from[i];
real_t seg_to = to[i];
- real_t box_begin = position[i];
- real_t box_end = box_begin + size[i];
+ real_t box_begin = _position[i];
+ real_t box_end = box_begin + _size[i];
real_t cmin, cmax;
if (seg_from < seg_to)
@@ -394,10 +388,10 @@ namespace Godot
public AABB Merge(AABB with)
{
- Vector3 beg_1 = position;
- Vector3 beg_2 = with.position;
- var end_1 = new Vector3(size.x, size.y, size.z) + beg_1;
- var end_2 = new Vector3(with.size.x, with.size.y, with.size.z) + beg_2;
+ Vector3 beg_1 = _position;
+ Vector3 beg_2 = with._position;
+ var end_1 = new Vector3(_size.x, _size.y, _size.z) + beg_1;
+ var end_2 = new Vector3(with._size.x, with._size.y, with._size.z) + beg_2;
var min = new Vector3(
beg_1.x < beg_2.x ? beg_1.x : beg_2.x,
@@ -417,8 +411,8 @@ namespace Godot
// Constructors
public AABB(Vector3 position, Vector3 size)
{
- this.position = position;
- this.size = size;
+ _position = position;
+ _size = size;
}
public static bool operator ==(AABB left, AABB right)
@@ -443,20 +437,20 @@ namespace Godot
public bool Equals(AABB other)
{
- return position == other.position && size == other.size;
+ return _position == other._position && _size == other._size;
}
public override int GetHashCode()
{
- return position.GetHashCode() ^ size.GetHashCode();
+ return _position.GetHashCode() ^ _size.GetHashCode();
}
public override string ToString()
{
return String.Format("{0} - {1}", new object[]
{
- position.ToString(),
- size.ToString()
+ _position.ToString(),
+ _size.ToString()
});
}
@@ -464,8 +458,8 @@ namespace Godot
{
return String.Format("{0} - {1}", new object[]
{
- position.ToString(format),
- size.ToString(format)
+ _position.ToString(format),
+ _size.ToString(format)
});
}
}
diff --git a/modules/mono/glue/cs_files/Rect2.cs b/modules/mono/glue/cs_files/Rect2.cs
index e772665009..cb25c267bc 100644
--- a/modules/mono/glue/cs_files/Rect2.cs
+++ b/modules/mono/glue/cs_files/Rect2.cs
@@ -29,6 +29,7 @@ namespace Godot
public Vector2 End
{
get { return _position + _size; }
+ set { _size = value - _position; }
}
public real_t Area
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index e8ab1558cc..4f72b359e9 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -1088,8 +1088,8 @@ public:
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "graphics/32_bits_framebuffer"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "one_click_deploy/clear_previous_install"), true));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/debug", PROPERTY_HINT_GLOBAL_FILE, "apk"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/release", PROPERTY_HINT_GLOBAL_FILE, "apk"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/debug", PROPERTY_HINT_GLOBAL_FILE, "*.apk"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/release", PROPERTY_HINT_GLOBAL_FILE, "*.apk"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "command_line/extra_args"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/code", PROPERTY_HINT_RANGE, "1,4096,1,or_greater"), 1));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "version/name"), "1.0"));
@@ -1104,10 +1104,10 @@ public:
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_xlarge"), true));
for (int i = 0; i < sizeof(launcher_icons) / sizeof(launcher_icons[0]); ++i) {
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_icons[i].option_id, PROPERTY_HINT_FILE, "png"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_icons[i].option_id, PROPERTY_HINT_FILE, "*.png"), ""));
}
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release", PROPERTY_HINT_GLOBAL_FILE, "keystore"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release", PROPERTY_HINT_GLOBAL_FILE, "*.keystore"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release_user"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release_password"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "apk_expansion/enable"), false));
@@ -1899,7 +1899,7 @@ void register_android_exporter() {
EDITOR_DEF("export/android/jarsigner", "");
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/android/jarsigner", PROPERTY_HINT_GLOBAL_FILE, exe_ext));
EDITOR_DEF("export/android/debug_keystore", "");
- EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/android/debug_keystore", PROPERTY_HINT_GLOBAL_FILE, "keystore"));
+ EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/android/debug_keystore", PROPERTY_HINT_GLOBAL_FILE, "*.keystore"));
EDITOR_DEF("export/android/debug_keystore_user", "androiddebugkey");
EDITOR_DEF("export/android/debug_keystore_pass", "android");
EDITOR_DEF("export/android/force_system_user", false);
diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp
index ab8d9909a0..9754807f38 100644
--- a/platform/iphone/export/export.cpp
+++ b/platform/iphone/export/export.cpp
@@ -172,8 +172,8 @@ static const LoadingScreenInfo loading_screen_infos[] = {
void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options) {
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/debug", PROPERTY_HINT_GLOBAL_FILE, "zip"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/release", PROPERTY_HINT_GLOBAL_FILE, "zip"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/debug", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/release", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/app_store_team_id"), ""));
@@ -193,18 +193,18 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options)
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/version"), "1.0"));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/copyright"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "required_icons/iphone_120x120", PROPERTY_HINT_FILE, "png"), "")); // Home screen on iPhone/iPod Touch with retina display
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "required_icons/ipad_76x76", PROPERTY_HINT_FILE, "png"), "")); // Home screen on iPad
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "required_icons/app_store_1024x1024", PROPERTY_HINT_FILE, "png"), "")); // App Store
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "required_icons/iphone_120x120", PROPERTY_HINT_FILE, "*.png"), "")); // Home screen on iPhone/iPod Touch with retina display
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "required_icons/ipad_76x76", PROPERTY_HINT_FILE, "*.png"), "")); // Home screen on iPad
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "required_icons/app_store_1024x1024", PROPERTY_HINT_FILE, "*.png"), "")); // App Store
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "optional_icons/iphone_180x180", PROPERTY_HINT_FILE, "png"), "")); // Home screen on iPhone with retina HD display
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "optional_icons/ipad_152x152", PROPERTY_HINT_FILE, "png"), "")); // Home screen on iPad with retina display
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "optional_icons/ipad_167x167", PROPERTY_HINT_FILE, "png"), "")); // Home screen on iPad Pro
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "optional_icons/spotlight_40x40", PROPERTY_HINT_FILE, "png"), "")); // Spotlight
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "optional_icons/spotlight_80x80", PROPERTY_HINT_FILE, "png"), "")); // Spotlight on devices with retina display
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "optional_icons/iphone_180x180", PROPERTY_HINT_FILE, "*.png"), "")); // Home screen on iPhone with retina HD display
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "optional_icons/ipad_152x152", PROPERTY_HINT_FILE, "*.png"), "")); // Home screen on iPad with retina display
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "optional_icons/ipad_167x167", PROPERTY_HINT_FILE, "*.png"), "")); // Home screen on iPad Pro
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "optional_icons/spotlight_40x40", PROPERTY_HINT_FILE, "*.png"), "")); // Spotlight
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "optional_icons/spotlight_80x80", PROPERTY_HINT_FILE, "*.png"), "")); // Spotlight on devices with retina display
for (int i = 0; i < sizeof(loading_screen_infos) / sizeof(loading_screen_infos[0]); ++i) {
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, loading_screen_infos[i].preset_key, PROPERTY_HINT_FILE, "png"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, loading_screen_infos[i].preset_key, PROPERTY_HINT_FILE, "*.png"), ""));
}
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/s3tc"), false));
diff --git a/platform/javascript/SCsub b/platform/javascript/SCsub
index 98988d97fd..a93c98a89f 100644
--- a/platform/javascript/SCsub
+++ b/platform/javascript/SCsub
@@ -32,6 +32,6 @@ zip_files = env.InstallAs([
], [
js_wrapped,
wasm,
- '#misc/dist/html/default.html'
+ '#misc/dist/html/full-size.html'
])
env.Zip('#bin/godot', zip_files, ZIPROOT=zip_dir, ZIPSUFFIX='${PROGSUFFIX}${ZIPSUFFIX}', ZIPCOMSTR='Archving $SOURCES as $TARGET')
diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp
index 78e60af3e0..a7f0084562 100644
--- a/platform/javascript/export/export.cpp
+++ b/platform/javascript/export/export.cpp
@@ -120,10 +120,10 @@ void EditorExportPlatformJavaScript::get_export_options(List<ExportOption> *r_op
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/s3tc"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/etc"), false));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/etc2"), true));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "html/custom_html_shell", PROPERTY_HINT_FILE, "html"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "html/custom_html_shell", PROPERTY_HINT_FILE, "*.html"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "html/head_include", PROPERTY_HINT_MULTILINE_TEXT), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "zip"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "zip"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
}
String EditorExportPlatformJavaScript::get_name() const {
diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp
index a2c6bdd629..5a8a05d4df 100644
--- a/platform/javascript/os_javascript.cpp
+++ b/platform/javascript/os_javascript.cpp
@@ -71,14 +71,6 @@ static bool is_canvas_focused() {
static bool cursor_inside_canvas = true;
-EM_BOOL OS_JavaScript::browser_resize_callback(int p_event_type, const EmscriptenUiEvent *p_event, void *p_user_data) {
-
- // The order of the fullscreen change event and the window size change
- // event varies, even within just one browser, so defer handling.
- get_singleton()->canvas_size_adjustment_requested = true;
- return false;
-}
-
EM_BOOL OS_JavaScript::fullscreen_change_callback(int p_event_type, const EmscriptenFullscreenChangeEvent *p_event, void *p_user_data) {
OS_JavaScript *os = get_singleton();
@@ -88,7 +80,13 @@ EM_BOOL OS_JavaScript::fullscreen_change_callback(int p_event_type, const Emscri
// This event property is the only reliable data on
// browser fullscreen state.
os->video_mode.fullscreen = p_event->isFullscreen;
- os->canvas_size_adjustment_requested = true;
+ if (os->video_mode.fullscreen) {
+ os->entering_fullscreen = false;
+ } else {
+ // Restoring maximized window now will cause issues,
+ // so delay until main_loop_iterate.
+ os->just_exited_fullscreen = true;
+ }
}
return false;
}
@@ -114,14 +112,14 @@ Size2 OS_JavaScript::get_screen_size(int p_screen) const {
void OS_JavaScript::set_window_size(const Size2 p_size) {
windowed_size = p_size;
- if (is_window_fullscreen()) {
+ if (video_mode.fullscreen) {
window_maximized = false;
set_window_fullscreen(false);
- } else if (is_window_maximized()) {
- set_window_maximized(false);
} else {
- video_mode.width = p_size.x;
- video_mode.height = p_size.y;
+ if (window_maximized) {
+ emscripten_exit_soft_fullscreen();
+ window_maximized = false;
+ }
emscripten_set_canvas_size(p_size.x, p_size.y);
}
}
@@ -135,31 +133,22 @@ Size2 OS_JavaScript::get_window_size() const {
void OS_JavaScript::set_window_maximized(bool p_enabled) {
- window_maximized = p_enabled;
- if (is_window_fullscreen()) {
+ if (video_mode.fullscreen) {
+ window_maximized = p_enabled;
set_window_fullscreen(false);
- return;
- }
- // Calling emscripten_enter_soft_fullscreen mutltiple times hides all
- // page elements except the canvas permanently, so track state.
- if (p_enabled && !soft_fullscreen_enabled) {
-
+ } else if (!p_enabled) {
+ emscripten_exit_soft_fullscreen();
+ window_maximized = false;
+ } else if (!window_maximized) {
+ // Prevent calling emscripten_enter_soft_fullscreen mutltiple times,
+ // this would hide page elements permanently.
EmscriptenFullscreenStrategy strategy;
strategy.scaleMode = EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH;
strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF;
strategy.filteringMode = EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT;
strategy.canvasResizedCallback = NULL;
emscripten_enter_soft_fullscreen(NULL, &strategy);
- soft_fullscreen_enabled = true;
- video_mode.width = get_window_size().width;
- video_mode.height = get_window_size().height;
- } else if (!p_enabled) {
-
- emscripten_exit_soft_fullscreen();
- soft_fullscreen_enabled = false;
- video_mode.width = windowed_size.width;
- video_mode.height = windowed_size.height;
- emscripten_set_canvas_size(video_mode.width, video_mode.height);
+ window_maximized = p_enabled;
}
}
@@ -170,30 +159,33 @@ bool OS_JavaScript::is_window_maximized() const {
void OS_JavaScript::set_window_fullscreen(bool p_enabled) {
- if (p_enabled == is_window_fullscreen()) {
+ if (p_enabled == video_mode.fullscreen) {
return;
}
- // Just request changes here, if successful, canvas is resized in
- // _browser_resize_callback or _fullscreen_change_callback.
- EMSCRIPTEN_RESULT result;
+ // Just request changes here, if successful, logic continues in
+ // fullscreen_change_callback.
if (p_enabled) {
if (window_maximized) {
- // Soft fullsreen during real fulllscreen can cause issues.
- set_window_maximized(false);
- window_maximized = true;
+ // Soft fullsreen during real fullscreen can cause issues, so exit.
+ // This must be called before requesting full screen.
+ emscripten_exit_soft_fullscreen();
}
EmscriptenFullscreenStrategy strategy;
strategy.scaleMode = EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH;
strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF;
strategy.filteringMode = EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT;
strategy.canvasResizedCallback = NULL;
- emscripten_request_fullscreen_strategy(NULL, false, &strategy);
+ EMSCRIPTEN_RESULT result = emscripten_request_fullscreen_strategy(NULL, false, &strategy);
+ ERR_EXPLAIN("Enabling fullscreen is only possible from an input callback for the HTML5 platform");
+ ERR_FAIL_COND(result == EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED);
+ ERR_FAIL_COND(result != EMSCRIPTEN_RESULT_SUCCESS);
+ // Not fullscreen yet, so prevent "windowed" canvas dimensions from
+ // being overwritten.
+ entering_fullscreen = true;
} else {
- result = emscripten_exit_fullscreen();
- if (result != EMSCRIPTEN_RESULT_SUCCESS) {
- ERR_PRINTS("Failed to exit fullscreen: Code " + itos(result));
- }
+ // No logic allowed here, since exiting w/ ESC key won't use this function.
+ ERR_FAIL_COND(emscripten_exit_fullscreen() != EMSCRIPTEN_RESULT_SUCCESS);
}
}
@@ -725,7 +717,6 @@ Error OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver,
SET_EM_CALLBACK("#canvas", keydown, keydown_callback)
SET_EM_CALLBACK("#canvas", keypress, keypress_callback)
SET_EM_CALLBACK("#canvas", keyup, keyup_callback)
- SET_EM_CALLBACK(NULL, resize, browser_resize_callback)
SET_EM_CALLBACK(NULL, fullscreenchange, fullscreen_change_callback)
SET_EM_CALLBACK_NOTARGET(gamepadconnected, gamepad_change_callback)
SET_EM_CALLBACK_NOTARGET(gamepaddisconnected, gamepad_change_callback)
@@ -794,18 +785,32 @@ bool OS_JavaScript::main_loop_iterate() {
/* clang-format on */
}
}
+
process_joypads();
- if (canvas_size_adjustment_requested) {
- if (video_mode.fullscreen || window_maximized) {
- video_mode.width = get_window_size().width;
- video_mode.height = get_window_size().height;
- }
- if (!video_mode.fullscreen) {
- set_window_maximized(window_maximized);
+ if (just_exited_fullscreen) {
+ if (window_maximized) {
+ EmscriptenFullscreenStrategy strategy;
+ strategy.scaleMode = EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH;
+ strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF;
+ strategy.filteringMode = EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT;
+ strategy.canvasResizedCallback = NULL;
+ emscripten_enter_soft_fullscreen(NULL, &strategy);
+ } else {
+ emscripten_set_canvas_size(windowed_size.width, windowed_size.height);
}
- canvas_size_adjustment_requested = false;
+ just_exited_fullscreen = false;
}
+
+ int canvas[3];
+ emscripten_get_canvas_size(canvas, canvas + 1, canvas + 2);
+ video_mode.width = canvas[0];
+ video_mode.height = canvas[1];
+ if (!window_maximized && !video_mode.fullscreen && !just_exited_fullscreen && !entering_fullscreen) {
+ windowed_size.width = canvas[0];
+ windowed_size.height = canvas[1];
+ }
+
return Main::iteration();
}
@@ -958,8 +963,8 @@ OS_JavaScript::OS_JavaScript(int p_argc, char *p_argv[]) {
set_cmdline(p_argv[0], arguments);
window_maximized = false;
- soft_fullscreen_enabled = false;
- canvas_size_adjustment_requested = false;
+ entering_fullscreen = false;
+ just_exited_fullscreen = false;
main_loop = NULL;
diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h
index 915320fe39..f40fb8fc7e 100644
--- a/platform/javascript/os_javascript.h
+++ b/platform/javascript/os_javascript.h
@@ -44,8 +44,8 @@ class OS_JavaScript : public OS_Unix {
VideoMode video_mode;
Vector2 windowed_size;
bool window_maximized;
- bool soft_fullscreen_enabled;
- bool canvas_size_adjustment_requested;
+ bool entering_fullscreen;
+ bool just_exited_fullscreen;
InputDefault *input;
Ref<InputEventKey> deferred_key_event;
@@ -59,7 +59,6 @@ class OS_JavaScript : public OS_Unix {
int64_t sync_wait_time;
int64_t last_sync_check_time;
- static EM_BOOL browser_resize_callback(int p_event_type, const EmscriptenUiEvent *p_event, void *p_user_data);
static EM_BOOL fullscreen_change_callback(int p_event_type, const EmscriptenFullscreenChangeEvent *p_event, void *p_user_data);
static EM_BOOL keydown_callback(int p_event_type, const EmscriptenKeyboardEvent *p_event, void *p_user_data);
diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp
index f0945e2e1e..57ca29bdd5 100644
--- a/platform/osx/export/export.cpp
+++ b/platform/osx/export/export.cpp
@@ -109,12 +109,12 @@ void EditorExportPlatformOSX::get_preset_features(const Ref<EditorExportPreset>
void EditorExportPlatformOSX::get_export_options(List<ExportOption> *r_options) {
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/debug", PROPERTY_HINT_GLOBAL_FILE, "zip"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/release", PROPERTY_HINT_GLOBAL_FILE, "zip"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/debug", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/release", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game Name"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/info"), "Made with Godot Engine"));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/icon", PROPERTY_HINT_FILE, "png"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/icon", PROPERTY_HINT_FILE, "*.png"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/identifier", PROPERTY_HINT_PLACEHOLDER_TEXT, "com.example.game"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/signature"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/short_version"), "1.0"));
diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp
index cb6633434b..1ad5293b44 100644
--- a/platform/uwp/export/export.cpp
+++ b/platform/uwp/export/export.cpp
@@ -1087,8 +1087,8 @@ public:
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "tiles/show_name_on_wide310x150"), false));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "tiles/show_name_on_square310x310"), false));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "zip"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "zip"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
// Capabilities
const char **basic = uwp_capabilities;
diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h
index 85f8564ac2..1e6a251c9c 100644
--- a/scene/2d/canvas_item.h
+++ b/scene/2d/canvas_item.h
@@ -139,8 +139,6 @@ class CanvasItem : public Node {
GDCLASS(CanvasItem, Node);
- friend class CanvasLayer;
-
public:
enum BlendMode {
diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp
index 52d04ac10a..1e2184bd41 100644
--- a/scene/2d/collision_object_2d.cpp
+++ b/scene/2d/collision_object_2d.cpp
@@ -38,7 +38,7 @@ void CollisionObject2D::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE: {
- Transform2D global_transform = get_global_transform_with_canvas();
+ Transform2D global_transform = get_global_transform();
if (area)
Physics2DServer::get_singleton()->area_set_transform(rid, global_transform);
@@ -64,7 +64,7 @@ void CollisionObject2D::_notification(int p_what) {
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
- Transform2D global_transform = get_global_transform_with_canvas();
+ Transform2D global_transform = get_global_transform();
if (only_update_transform_changes && global_transform == last_transform) {
return;
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index 66686f10a8..02213e07d0 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -35,6 +35,19 @@
#include "engine.h"
#include "math_funcs.h"
#include "scene/scene_string_names.h"
+void PhysicsBody2D::_notification(int p_what) {
+
+ /*
+ switch(p_what) {
+
+ case NOTIFICATION_TRANSFORM_CHANGED: {
+
+ Physics2DServer::get_singleton()->body_set_state(get_rid(),Physics2DServer::BODY_STATE_TRANSFORM,get_global_transform());
+
+ } break;
+ }
+ */
+}
void PhysicsBody2D::_set_layers(uint32_t p_mask) {
@@ -423,7 +436,7 @@ bool RigidBody2D::_test_motion(const Vector2 &p_motion, bool p_infinite_inertia,
Physics2DServer::MotionResult *r = NULL;
if (p_result.is_valid())
r = p_result->get_result_ptr();
- return Physics2DServer::get_singleton()->body_test_motion(get_rid(), get_global_transform_with_canvas(), p_motion, p_infinite_inertia, p_margin, r);
+ return Physics2DServer::get_singleton()->body_test_motion(get_rid(), get_global_transform(), p_motion, p_infinite_inertia, p_margin, r);
}
void RigidBody2D::_direct_state_changed(Object *p_state) {
@@ -436,7 +449,7 @@ void RigidBody2D::_direct_state_changed(Object *p_state) {
set_block_transform_notify(true); // don't want notify (would feedback loop)
if (mode != MODE_KINEMATIC)
- set_global_transform(get_canvas_transform().affine_inverse() * state->get_transform());
+ set_global_transform(state->get_transform());
linear_velocity = state->get_linear_velocity();
angular_velocity = state->get_angular_velocity();
if (sleeping != state->is_sleeping()) {
@@ -1131,7 +1144,7 @@ bool KinematicBody2D::separate_raycast_shapes(bool p_infinite_inertia, Collision
Physics2DServer::SeparationResult sep_res[8]; //max 8 rays
- Transform2D gt = get_global_transform_with_canvas();
+ Transform2D gt = get_global_transform();
Vector2 recover;
int hits = Physics2DServer::get_singleton()->body_test_ray_separation(get_rid(), gt, p_infinite_inertia, recover, sep_res, 8, margin);
@@ -1145,7 +1158,7 @@ bool KinematicBody2D::separate_raycast_shapes(bool p_infinite_inertia, Collision
}
gt.elements[2] += recover;
- set_global_transform(get_canvas_transform().affine_inverse() * gt);
+ set_global_transform(gt);
if (deepest != -1) {
r_collision.collider = sep_res[deepest].collider_id;
@@ -1166,7 +1179,7 @@ bool KinematicBody2D::separate_raycast_shapes(bool p_infinite_inertia, Collision
bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes, bool p_test_only) {
- Transform2D gt = get_global_transform_with_canvas();
+ Transform2D gt = get_global_transform();
Physics2DServer::MotionResult result;
bool colliding = Physics2DServer::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, margin, &result, p_exclude_raycast_shapes);
@@ -1185,7 +1198,7 @@ bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_
if (!p_test_only) {
gt.elements[2] += result.motion;
- set_global_transform(get_canvas_transform().affine_inverse() * gt);
+ set_global_transform(gt);
}
return colliding;
@@ -1259,9 +1272,9 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const
if (p_stop_on_slope) {
if (Vector2() == lv_n + p_floor_direction) {
- Transform2D gt = get_global_transform_with_canvas();
+ Transform2D gt = get_global_transform();
gt.elements[2] -= collision.travel;
- set_global_transform(get_canvas_transform().affine_inverse() * gt);
+ set_global_transform(gt);
return Vector2();
}
}
@@ -1310,7 +1323,7 @@ Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_veloci
}
Collision col;
- Transform2D gt = get_global_transform_with_canvas();
+ Transform2D gt = get_global_transform();
if (move_and_collide(p_snap, p_infinite_inertia, col, false, true)) {
gt.elements[2] += col.travel;
@@ -1319,7 +1332,7 @@ Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_veloci
on_floor_body = col.collider_rid;
floor_velocity = col.collider_vel;
}
- set_global_transform(get_canvas_transform().affine_inverse() * gt);
+ set_global_transform(gt);
}
return ret;
@@ -1416,22 +1429,22 @@ void KinematicBody2D::_direct_state_changed(Object *p_state) {
last_valid_transform = state->get_transform();
set_notify_local_transform(false);
- set_global_transform(get_canvas_transform().affine_inverse() * last_valid_transform);
+ set_global_transform(last_valid_transform);
set_notify_local_transform(true);
}
void KinematicBody2D::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
- last_valid_transform = get_global_transform_with_canvas();
+ last_valid_transform = get_global_transform();
}
if (p_what == NOTIFICATION_LOCAL_TRANSFORM_CHANGED) {
//used by sync to physics, send the new transform to the physics
- Transform2D new_transform = get_global_transform_with_canvas();
+ Transform2D new_transform = get_global_transform();
Physics2DServer::get_singleton()->body_set_state(get_rid(), Physics2DServer::BODY_STATE_TRANSFORM, new_transform);
//but then revert changes
set_notify_local_transform(false);
- set_global_transform(get_canvas_transform().affine_inverse() * last_valid_transform);
+ set_global_transform(last_valid_transform);
set_notify_local_transform(true);
}
}
diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h
index 0900438e3c..852963a721 100644
--- a/scene/2d/physics_body_2d.h
+++ b/scene/2d/physics_body_2d.h
@@ -49,6 +49,7 @@ class PhysicsBody2D : public CollisionObject2D {
uint32_t _get_layers() const;
protected:
+ void _notification(int p_what);
PhysicsBody2D(Physics2DServer::BodyMode p_mode);
static void _bind_methods();
diff --git a/scene/2d/remote_transform_2d.cpp b/scene/2d/remote_transform_2d.cpp
index 63c3d78dfd..f0274e5206 100644
--- a/scene/2d/remote_transform_2d.cpp
+++ b/scene/2d/remote_transform_2d.cpp
@@ -67,7 +67,7 @@ void RemoteTransform2D::_update_remote() {
} else {
Transform2D n_trans = n->get_global_transform();
Transform2D our_trans = get_global_transform();
- Vector2 n_scale = n->get_global_scale();
+ Vector2 n_scale = n->get_scale();
if (!update_remote_position)
our_trans.set_origin(n_trans.get_origin());
@@ -131,8 +131,10 @@ void RemoteTransform2D::_notification(int p_what) {
void RemoteTransform2D::set_remote_node(const NodePath &p_remote_node) {
remote_node = p_remote_node;
- if (is_inside_tree())
+ if (is_inside_tree()) {
_update_cache();
+ _update_remote();
+ }
update_configuration_warning();
}
@@ -144,6 +146,7 @@ NodePath RemoteTransform2D::get_remote_node() const {
void RemoteTransform2D::set_use_global_coordinates(const bool p_enable) {
use_global_coordinates = p_enable;
+ _update_remote();
}
bool RemoteTransform2D::get_use_global_coordinates() const {
diff --git a/scene/2d/sprite.cpp b/scene/2d/sprite.cpp
index ebe0e81f6e..bb5990fa79 100644
--- a/scene/2d/sprite.cpp
+++ b/scene/2d/sprite.cpp
@@ -298,6 +298,11 @@ int Sprite::get_hframes() const {
bool Sprite::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
+ return is_pixel_opaque(p_point);
+}
+
+bool Sprite::is_pixel_opaque(const Point2 &p_point) const {
+
if (texture.is_null())
return false;
@@ -316,32 +321,6 @@ bool Sprite::_edit_is_selected_on_click(const Point2 &p_point, double p_toleranc
q.y = 1.0f - q.y;
q = q * src_rect.size + src_rect.position;
- Ref<Image> image;
- Ref<AtlasTexture> atlasTexture = texture;
- if (atlasTexture.is_null()) {
- image = texture->get_data();
- } else {
- ERR_FAIL_COND_V(atlasTexture->get_atlas().is_null(), false);
-
- image = atlasTexture->get_atlas()->get_data();
-
- Rect2 region = atlasTexture->get_region();
- Rect2 margin = atlasTexture->get_margin();
-
- q -= margin.position;
-
- if ((q.x > region.size.width) || (q.y > region.size.height)) {
- return false;
- }
-
- q += region.position;
- }
-
- ERR_FAIL_COND_V(image.is_null(), false);
- if (image->is_compressed()) {
- return dst_rect.has_point(p_point);
- }
-
bool is_repeat = texture->get_flags() & Texture::FLAG_REPEAT;
bool is_mirrored_repeat = texture->get_flags() & Texture::FLAG_MIRRORED_REPEAT;
if (is_repeat) {
@@ -363,11 +342,8 @@ bool Sprite::_edit_is_selected_on_click(const Point2 &p_point, double p_toleranc
q.x = MIN(q.x, texture->get_size().width - 1);
q.y = MIN(q.y, texture->get_size().height - 1);
}
- image->lock();
- const Color c = image->get_pixel((int)q.x, (int)q.y);
- image->unlock();
- return c.a > 0.01;
+ return texture->is_pixel_opaque((int)q.x, (int)q.y);
}
Rect2 Sprite::get_rect() const {
@@ -437,6 +413,8 @@ void Sprite::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_region", "enabled"), &Sprite::set_region);
ClassDB::bind_method(D_METHOD("is_region"), &Sprite::is_region);
+ ClassDB::bind_method(D_METHOD("is_pixel_opaque", "pos"), &Sprite::is_pixel_opaque);
+
ClassDB::bind_method(D_METHOD("set_region_rect", "rect"), &Sprite::set_region_rect);
ClassDB::bind_method(D_METHOD("get_region_rect"), &Sprite::get_region_rect);
diff --git a/scene/2d/sprite.h b/scene/2d/sprite.h
index 0a5ff002cd..ab444f89fc 100644
--- a/scene/2d/sprite.h
+++ b/scene/2d/sprite.h
@@ -75,6 +75,8 @@ public:
virtual bool _edit_use_pivot() const;
virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
+ bool is_pixel_opaque(const Point2 &p_point) const;
+
virtual Rect2 _edit_get_rect() const;
virtual bool _edit_use_rect() const;
diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp
index bcd015875b..a4582b7d7d 100644
--- a/scene/3d/camera.cpp
+++ b/scene/3d/camera.cpp
@@ -867,6 +867,9 @@ void ClippedCamera::_bind_methods() {
ADD_GROUP("Clip To", "clip_to");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_to_areas", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_clip_to_areas", "is_clip_to_areas_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_to_bodies", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_clip_to_bodies", "is_clip_to_bodies_enabled");
+
+ BIND_ENUM_CONSTANT(CLIP_PROCESS_PHYSICS);
+ BIND_ENUM_CONSTANT(CLIP_PROCESS_IDLE);
}
ClippedCamera::ClippedCamera() {
margin = 0;
diff --git a/scene/3d/remote_transform.cpp b/scene/3d/remote_transform.cpp
index 2156e24cd0..c12e49fb47 100644
--- a/scene/3d/remote_transform.cpp
+++ b/scene/3d/remote_transform.cpp
@@ -124,8 +124,10 @@ void RemoteTransform::_notification(int p_what) {
void RemoteTransform::set_remote_node(const NodePath &p_remote_node) {
remote_node = p_remote_node;
- if (is_inside_tree())
+ if (is_inside_tree()) {
_update_cache();
+ _update_remote();
+ }
update_configuration_warning();
}
diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp
index 66a9c5babd..10bab3ce38 100644
--- a/scene/animation/animation_blend_tree.cpp
+++ b/scene/animation/animation_blend_tree.cpp
@@ -987,17 +987,6 @@ void AnimationNodeBlendTree::disconnect_node(const StringName &p_node, int p_inp
nodes[p_node].connections.write[p_input_index] = StringName();
}
-float AnimationNodeBlendTree::get_connection_activity(const StringName &p_input_node, int p_input_index) const {
-
- ERR_FAIL_COND_V(!nodes.has(p_input_node), 0);
-
- Ref<AnimationNode> input = nodes[p_input_node].node;
- ERR_FAIL_INDEX_V(p_input_index, nodes[p_input_node].connections.size(), 0);
-
- //return input->get_input_activity(p_input_index);
- return 0;
-}
-
AnimationNodeBlendTree::ConnectionError AnimationNodeBlendTree::can_connect_node(const StringName &p_input_node, int p_input_index, const StringName &p_output_node) const {
if (!nodes.has(p_output_node) || p_output_node == SceneStringNames::get_singleton()->output) {
diff --git a/scene/animation/animation_blend_tree.h b/scene/animation/animation_blend_tree.h
index 37bd45c74a..7bf2917c1e 100644
--- a/scene/animation/animation_blend_tree.h
+++ b/scene/animation/animation_blend_tree.h
@@ -349,7 +349,6 @@ public:
void connect_node(const StringName &p_input_node, int p_input_index, const StringName &p_output_node);
void disconnect_node(const StringName &p_node, int p_input_index);
- float get_connection_activity(const StringName &p_input_node, int p_input_index) const;
struct NodeConnection {
StringName input_node;
diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp
index c28e918a16..09c36eb081 100644
--- a/scene/animation/animation_node_state_machine.cpp
+++ b/scene/animation/animation_node_state_machine.cpp
@@ -124,7 +124,6 @@ void AnimationNodeStateMachinePlayback::start(const StringName &p_state) {
start_request_travel = false;
start_request = p_state;
stop_request = false;
- print_line("wants start");
}
void AnimationNodeStateMachinePlayback::stop() {
diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp
index 1513010a8a..76f0ee9359 100644
--- a/scene/animation/animation_tree.cpp
+++ b/scene/animation/animation_tree.cpp
@@ -109,8 +109,16 @@ float AnimationNode::blend_input(int p_input, float p_time, bool p_seek, float p
Ref<AnimationNode> node = blend_tree->get_node(node_name);
//inputs.write[p_input].last_pass = state->last_pass;
- float activity;
- return _blend_node(node_name, blend_tree->get_node_connection_array(node_name), NULL, node, p_time, p_seek, p_blend, p_filter, p_optimize, &activity);
+ float activity=0;
+ float ret = _blend_node(node_name, blend_tree->get_node_connection_array(node_name), NULL, node, p_time, p_seek, p_blend, p_filter, p_optimize, &activity);
+
+ Vector<AnimationTree::Activity> *activity_ptr = state->tree->input_activity_map.getptr(base_path);
+
+ if (activity_ptr && p_input<activity_ptr->size()) {
+ activity_ptr->write[p_input].last_pass = state->last_pass;
+ activity_ptr->write[p_input].activity = activity;
+ }
+ return ret;
}
float AnimationNode::blend_node(const StringName &p_sub_path, Ref<AnimationNode> p_node, float p_time, bool p_seek, float p_blend, FilterAction p_filter, bool p_optimize) {
@@ -1285,6 +1293,18 @@ void AnimationTree::_update_properties_for_node(const String &p_base_path, Ref<A
property_parent_map[p_base_path] = HashMap<StringName, StringName>();
}
+ if (node->get_input_count() && !input_activity_map.has(p_base_path)) {
+
+ Vector<Activity> activity;
+ for(int i=0;i<node->get_input_count();i++) {
+ Activity a;
+ a.last_pass=0;
+ activity.push_back(a);
+ }
+ input_activity_map[p_base_path] = activity;
+ input_activity_map_get[String(p_base_path).substr(0,String(p_base_path).length()-1)]=&input_activity_map[p_base_path];
+ }
+
List<PropertyInfo> plist;
node->get_parameter_list(&plist);
for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
@@ -1317,6 +1337,8 @@ void AnimationTree::_update_properties() {
properties.clear();
property_parent_map.clear();
+ input_activity_map.clear();
+ input_activity_map_get.clear();
if (root.is_valid()) {
_update_properties_for_node(SceneStringNames::get_singleton()->parameters_base_path, root);
@@ -1380,6 +1402,25 @@ void AnimationTree::rename_parameter(const String &p_base, const String &p_new_b
_update_properties();
}
+float AnimationTree::get_connection_activity(const StringName& p_path,int p_connection) const {
+
+ if (!input_activity_map_get.has(p_path)) {
+ return 0;
+ }
+ const Vector<Activity> *activity = input_activity_map_get[p_path];
+
+ if (!activity || p_connection<0 || p_connection>=activity->size()) {
+ return 0;
+ }
+
+ if ((*activity)[p_connection].last_pass != process_pass) {
+ return 0;
+ }
+
+ return (*activity)[p_connection].activity;
+}
+
+
void AnimationTree::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_active", "active"), &AnimationTree::set_active);
ClassDB::bind_method(D_METHOD("is_active"), &AnimationTree::is_active);
diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h
index 3c615b2f92..70f3932f21 100644
--- a/scene/animation/animation_tree.h
+++ b/scene/animation/animation_tree.h
@@ -55,7 +55,7 @@ public:
Vector<float> blends;
State *state;
- String path;
+
float _pre_process(const StringName &p_base_path, AnimationNode *p_parent, State *p_state, float p_time, bool p_seek, const Vector<StringName> &p_connections);
void _pre_update_animations(HashMap<NodePath, int> *track_map);
@@ -256,6 +256,14 @@ private:
HashMap<StringName, HashMap<StringName, StringName> > property_parent_map;
HashMap<StringName, Variant> property_map;
+ struct Activity {
+ uint64_t last_pass;
+ float activity;
+ };
+
+ HashMap<StringName, Vector<Activity> > input_activity_map;
+ HashMap<StringName, Vector<Activity> *> input_activity_map_get;
+
void _update_properties_for_node(const String &p_base_path, Ref<AnimationNode> node);
protected:
@@ -289,6 +297,7 @@ public:
Transform get_root_motion_transform() const;
+ float get_connection_activity(const StringName &p_path, int p_connection) const;
void advance(float p_time);
void rename_parameter(const String &p_base, const String &p_new_base);
diff --git a/scene/main/canvas_layer.cpp b/scene/main/canvas_layer.cpp
index c044443b51..a2e890e7a7 100644
--- a/scene/main/canvas_layer.cpp
+++ b/scene/main/canvas_layer.cpp
@@ -29,7 +29,6 @@
/*************************************************************************/
#include "canvas_layer.h"
-#include "scene/2d/canvas_item.h"
#include "viewport.h"
void CanvasLayer::set_layer(int p_xform) {
@@ -63,24 +62,6 @@ void CanvasLayer::_update_xform() {
transform.set_origin(ofs);
if (viewport.is_valid())
VisualServer::get_singleton()->viewport_set_canvas_transform(viewport, canvas, transform);
-
- if (!is_inside_tree())
- return;
-
- _notify_xform(this);
-}
-
-void CanvasLayer::_notify_xform(Node *p_node) {
-
- for (int i = 0; i < p_node->get_child_count(); i++) {
-
- CanvasItem *ci = Object::cast_to<CanvasItem>(p_node->get_child(i));
- if (ci) {
- ci->_notify_transform(ci);
- } else {
- _notify_xform(p_node->get_child(i));
- }
- }
}
void CanvasLayer::_update_locrotscale() {
diff --git a/scene/main/canvas_layer.h b/scene/main/canvas_layer.h
index fd347c4739..aae23fbb12 100644
--- a/scene/main/canvas_layer.h
+++ b/scene/main/canvas_layer.h
@@ -56,7 +56,6 @@ class CanvasLayer : public Node {
int sort_index;
void _update_xform();
- void _notify_xform(Node *p_node);
void _update_locrotscale();
protected:
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index d8efbeba17..c763c9bc79 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "texture.h"
+#include "bit_mask.h"
#include "core/method_bind_ext.gen.inc"
#include "core/os/os.h"
#include "core_string_names.h"
@@ -39,6 +40,9 @@ Size2 Texture::get_size() const {
return Size2(get_width(), get_height());
}
+bool Texture::is_pixel_opaque(int p_x, int p_y) const {
+ return true;
+}
void Texture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
@@ -234,6 +238,7 @@ void ImageTexture::set_data(const Ref<Image> &p_image) {
VisualServer::get_singleton()->texture_set_data(texture, p_image);
_change_notify();
+ alpha_cache.unref();
}
void ImageTexture::_resource_path_changed() {
@@ -288,6 +293,41 @@ void ImageTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, cons
VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, texture, p_src_rect, p_modulate, p_transpose, normal_rid, p_clip_uv);
}
+bool ImageTexture::is_pixel_opaque(int p_x, int p_y) const {
+
+ if (!alpha_cache.is_valid()) {
+ Ref<Image> img = get_data();
+ if (img.is_valid()) {
+ if (img->is_compressed()) { //must decompress, if compressed
+ Ref<Image> decom = img->duplicate();
+ decom->decompress();
+ img = decom;
+ }
+ alpha_cache.instance();
+ alpha_cache->create_from_image_alpha(img);
+ }
+ }
+
+ if (alpha_cache.is_valid()) {
+
+ int aw = int(alpha_cache->get_size().width);
+ int ah = int(alpha_cache->get_size().height);
+ if (aw == 0 || ah == 0) {
+ return true;
+ }
+
+ int x = p_x * aw / w;
+ int y = p_y * ah / h;
+
+ x = CLAMP(x, 0, aw);
+ y = CLAMP(y, 0, aw);
+
+ return alpha_cache->get_bit(Point2(x, y));
+ }
+
+ return true;
+}
+
void ImageTexture::set_size_override(const Size2 &p_size) {
Size2 s = p_size;
@@ -421,6 +461,8 @@ Image::Format StreamTexture::get_format() const {
Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &flags, Ref<Image> &image, int p_size_limit) {
+ alpha_cache.unref();
+
ERR_FAIL_COND_V(image.is_null(), ERR_INVALID_PARAMETER);
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
@@ -709,6 +751,40 @@ Ref<Image> StreamTexture::get_data() const {
return VS::get_singleton()->texture_get_data(texture);
}
+bool StreamTexture::is_pixel_opaque(int p_x, int p_y) const {
+
+ if (!alpha_cache.is_valid()) {
+ Ref<Image> img = get_data();
+ if (img.is_valid()) {
+ if (img->is_compressed()) { //must decompress, if compressed
+ Ref<Image> decom = img->duplicate();
+ decom->decompress();
+ img = decom;
+ }
+ alpha_cache.instance();
+ alpha_cache->create_from_image_alpha(img);
+ }
+ }
+
+ if (alpha_cache.is_valid()) {
+
+ int aw = int(alpha_cache->get_size().width);
+ int ah = int(alpha_cache->get_size().height);
+ if (aw == 0 || ah == 0) {
+ return true;
+ }
+
+ int x = p_x * aw / w;
+ int y = p_y * ah / h;
+
+ x = CLAMP(x, 0, aw);
+ y = CLAMP(y, 0, aw);
+
+ return alpha_cache->get_bit(Point2(x, y));
+ }
+
+ return true;
+}
void StreamTexture::set_flags(uint32_t p_flags) {
flags = p_flags;
VS::get_singleton()->texture_set_flags(texture, flags);
@@ -1007,6 +1083,15 @@ bool AtlasTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect,
return true;
}
+bool AtlasTexture::is_pixel_opaque(int p_x, int p_y) const {
+
+ if (atlas.is_valid()) {
+ return atlas->is_pixel_opaque(p_x + region.position.x + margin.position.x, p_x + region.position.y + margin.position.y);
+ }
+
+ return true;
+}
+
AtlasTexture::AtlasTexture() {
filter_clip = false;
}
@@ -1184,6 +1269,23 @@ void LargeTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, cons
}
}
+bool LargeTexture::is_pixel_opaque(int p_x, int p_y) const {
+
+ for (int i = 0; i < pieces.size(); i++) {
+
+ // TODO
+ if (!pieces[i].texture.is_valid())
+ continue;
+
+ Rect2 rect(pieces[i].offset, pieces[i].texture->get_size());
+ if (rect.has_point(Point2(p_x, p_y))) {
+ return pieces[i].texture->is_pixel_opaque(p_x - rect.position.x, p_y - rect.position.y);
+ }
+ }
+
+ return true;
+}
+
LargeTexture::LargeTexture() {
}
@@ -1666,7 +1768,7 @@ ProxyTexture::~ProxyTexture() {
void AnimatedTexture::_update_proxy() {
- _THREAD_SAFE_METHOD_
+ RWLockRead r(rw_lock);
float delta;
if (prev_ticks == 0) {
@@ -1712,7 +1814,7 @@ void AnimatedTexture::_update_proxy() {
void AnimatedTexture::set_frames(int p_frames) {
ERR_FAIL_COND(p_frames < 1 || p_frames > MAX_FRAMES);
- _THREAD_SAFE_METHOD_
+ RWLockWrite r(rw_lock);
frame_count = p_frames;
}
@@ -1723,14 +1825,14 @@ int AnimatedTexture::get_frames() const {
void AnimatedTexture::set_frame_texture(int p_frame, const Ref<Texture> &p_texture) {
ERR_FAIL_INDEX(p_frame, MAX_FRAMES);
- _THREAD_SAFE_METHOD_
+ RWLockWrite w(rw_lock);
frames[p_frame].texture = p_texture;
}
Ref<Texture> AnimatedTexture::get_frame_texture(int p_frame) const {
ERR_FAIL_INDEX_V(p_frame, MAX_FRAMES, Ref<Texture>());
- _THREAD_SAFE_METHOD_
+ RWLockRead r(rw_lock);
return frames[p_frame].texture;
}
@@ -1738,14 +1840,14 @@ Ref<Texture> AnimatedTexture::get_frame_texture(int p_frame) const {
void AnimatedTexture::set_frame_delay(int p_frame, float p_delay_sec) {
ERR_FAIL_INDEX(p_frame, MAX_FRAMES);
- _THREAD_SAFE_METHOD_
+ RWLockRead r(rw_lock);
frames[p_frame].delay_sec = p_delay_sec;
}
float AnimatedTexture::get_frame_delay(int p_frame) const {
ERR_FAIL_INDEX_V(p_frame, MAX_FRAMES, 0);
- _THREAD_SAFE_METHOD_
+ RWLockRead r(rw_lock);
return frames[p_frame].delay_sec;
}
@@ -1760,8 +1862,7 @@ float AnimatedTexture::get_fps() const {
}
int AnimatedTexture::get_width() const {
-
- _THREAD_SAFE_METHOD_
+ RWLockRead r(rw_lock);
if (!frames[current_frame].texture.is_valid()) {
return 1;
@@ -1770,8 +1871,7 @@ int AnimatedTexture::get_width() const {
return frames[current_frame].texture->get_width();
}
int AnimatedTexture::get_height() const {
-
- _THREAD_SAFE_METHOD_
+ RWLockRead r(rw_lock);
if (!frames[current_frame].texture.is_valid()) {
return 1;
@@ -1785,7 +1885,7 @@ RID AnimatedTexture::get_rid() const {
bool AnimatedTexture::has_alpha() const {
- _THREAD_SAFE_METHOD_
+ RWLockRead r(rw_lock);
if (!frames[current_frame].texture.is_valid()) {
return false;
@@ -1796,7 +1896,7 @@ bool AnimatedTexture::has_alpha() const {
Ref<Image> AnimatedTexture::get_data() const {
- _THREAD_SAFE_METHOD_
+ RWLockRead r(rw_lock);
if (!frames[current_frame].texture.is_valid()) {
return Ref<Image>();
@@ -1805,11 +1905,21 @@ Ref<Image> AnimatedTexture::get_data() const {
return frames[current_frame].texture->get_data();
}
+bool AnimatedTexture::is_pixel_opaque(int p_x, int p_y) const {
+
+ RWLockRead r(rw_lock);
+
+ if (frames[current_frame].texture.is_valid()) {
+ return frames[current_frame].texture->is_pixel_opaque(p_x, p_y);
+ }
+ return true;
+}
+
void AnimatedTexture::set_flags(uint32_t p_flags) {
}
uint32_t AnimatedTexture::get_flags() const {
- _THREAD_SAFE_METHOD_
+ RWLockRead r(rw_lock);
if (!frames[current_frame].texture.is_valid()) {
return 0;
@@ -1862,10 +1972,19 @@ AnimatedTexture::AnimatedTexture() {
prev_ticks = 0;
current_frame = 0;
VisualServer::get_singleton()->connect("frame_pre_draw", this, "_update_proxy");
+
+#ifndef NO_THREADS
+ rw_lock = RWLock::create();
+#else
+ rw_lock = NULL;
+#endif
}
AnimatedTexture::~AnimatedTexture() {
VS::get_singleton()->free(proxy);
+ if (rw_lock) {
+ memdelete(rw_lock);
+ }
}
///////////////////////////////
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index c1331fb3fe..79e6d2cdf9 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -34,6 +34,7 @@
#include "curve.h"
#include "io/resource_loader.h"
#include "os/mutex.h"
+#include "os/rw_lock.h"
#include "os/thread_safe.h"
#include "rect2.h"
#include "resource.h"
@@ -67,6 +68,8 @@ public:
virtual Size2 get_size() const;
virtual RID get_rid() const = 0;
+ virtual bool is_pixel_opaque(int p_x, int p_y) const;
+
virtual bool has_alpha() const = 0;
virtual void set_flags(uint32_t p_flags) = 0;
@@ -84,6 +87,8 @@ public:
VARIANT_ENUM_CAST(Texture::Flags);
+class BitMap;
+
class ImageTexture : public Texture {
GDCLASS(ImageTexture, Texture);
@@ -104,6 +109,7 @@ private:
Storage storage;
Size2 size_override;
float lossy_storage_quality;
+ mutable Ref<BitMap> alpha_cache;
protected:
virtual void reload_from_file();
@@ -143,6 +149,8 @@ public:
void set_storage(Storage p_storage);
Storage get_storage() const;
+ bool is_pixel_opaque(int p_x, int p_y) const;
+
void set_lossy_storage_quality(float p_lossy_storage_quality);
float get_lossy_storage_quality() const;
@@ -183,6 +191,7 @@ private:
Image::Format format;
uint32_t flags;
int w, h;
+ mutable Ref<BitMap> alpha_cache;
virtual void reload_from_file();
@@ -215,6 +224,7 @@ public:
virtual bool has_alpha() const;
virtual void set_flags(uint32_t p_flags);
+ bool is_pixel_opaque(int p_x, int p_y) const;
virtual Ref<Image> get_data() const;
@@ -272,6 +282,8 @@ public:
virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = true) const;
virtual bool get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const;
+ bool is_pixel_opaque(int p_x, int p_y) const;
+
AtlasTexture();
};
@@ -319,6 +331,8 @@ public:
virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const;
virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = true) const;
+ bool is_pixel_opaque(int p_x, int p_y) const;
+
LargeTexture();
};
@@ -609,7 +623,8 @@ public:
class AnimatedTexture : public Texture {
GDCLASS(AnimatedTexture, Texture)
- _THREAD_SAFE_CLASS_
+ //use readers writers lock for this, since its far more times read than written to
+ RWLock *rw_lock;
private:
enum {
@@ -668,6 +683,8 @@ public:
virtual Ref<Image> get_data() const;
+ bool is_pixel_opaque(int p_x, int p_y) const;
+
AnimatedTexture();
~AnimatedTexture();
};