aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/os/memory.cpp40
-rw-r--r--core/os/memory.h12
-rw-r--r--core/safe_refcount.cpp56
-rw-r--r--core/safe_refcount.h2
-rw-r--r--doc/base/classes.xml122
-rw-r--r--editor/editor_themes.cpp11
-rw-r--r--editor/icons/2x/icon_GUI_dropdown.pngbin183 -> 198 bytes
-rw-r--r--editor/icons/icon_GUI_dropdown.pngbin130 -> 136 bytes
-rw-r--r--editor/icons/source/icon_GUI_dropdown.svg22
-rw-r--r--editor/icons/source/icon_connect.svg46
-rw-r--r--editor/import/resource_importer_texture.cpp2
-rw-r--r--editor/import/resource_importer_wav.cpp4
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp48
-rw-r--r--editor/plugins/texture_editor_plugin.cpp16
-rw-r--r--editor/plugins/texture_editor_plugin.h1
-rw-r--r--editor/plugins/texture_region_editor_plugin.cpp38
-rw-r--r--editor/project_settings_editor.cpp18
-rw-r--r--editor/script_create_dialog.cpp31
-rw-r--r--main/main.cpp1
-rw-r--r--main/performance.cpp4
-rw-r--r--platform/android/SCsub2
-rw-r--r--platform/android/detect.py28
-rw-r--r--platform/android/export/export.cpp15
-rw-r--r--platform/android/java_class_wrapper.cpp12
-rw-r--r--platform/windows/os_windows.cpp7
-rw-r--r--scene/2d/sprite.cpp1
-rw-r--r--scene/gui/menu_button.cpp2
-rw-r--r--scene/gui/patch_9_rect.cpp1
-rw-r--r--scene/gui/text_edit.cpp104
-rw-r--r--scene/gui/tree.cpp1
-rw-r--r--scene/resources/style_box.cpp1
-rw-r--r--scene/resources/surface_tool.cpp19
-rw-r--r--scene/resources/texture.cpp10
-rw-r--r--servers/audio_server.cpp3
-rw-r--r--servers/physics/area_sw.h1
-rw-r--r--servers/physics/body_sw.cpp3
-rw-r--r--servers/physics/body_sw.h1
-rw-r--r--servers/physics/physics_server_sw.cpp30
-rw-r--r--servers/physics/space_sw.cpp6
-rw-r--r--servers/physics_2d/area_2d_sw.h1
-rw-r--r--servers/physics_2d/body_2d_sw.h1
-rw-r--r--servers/physics_2d/broad_phase_2d_hash_grid.cpp6
-rw-r--r--servers/physics_2d/physics_2d_server_sw.cpp31
43 files changed, 523 insertions, 237 deletions
diff --git a/core/os/memory.cpp b/core/os/memory.cpp
index 069ee48fa..acc960acd 100644
--- a/core/os/memory.cpp
+++ b/core/os/memory.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "memory.h"
#include "copymem.h"
+#include "core/safe_refcount.h"
#include "error_macros.h"
#include <stdio.h>
#include <stdlib.h>
@@ -43,14 +44,12 @@ void *operator new(size_t p_size, void *(*p_allocfunc)(size_t p_size)) {
return p_allocfunc(p_size);
}
-#include <stdio.h>
-
#ifdef DEBUG_ENABLED
-size_t Memory::mem_usage = 0;
-size_t Memory::max_usage = 0;
+uint64_t Memory::mem_usage = 0;
+uint64_t Memory::max_usage = 0;
#endif
-size_t Memory::alloc_count = 0;
+uint64_t Memory::alloc_count = 0;
void *Memory::alloc_static(size_t p_bytes, bool p_pad_align) {
@@ -62,10 +61,10 @@ void *Memory::alloc_static(size_t p_bytes, bool p_pad_align) {
void *mem = malloc(p_bytes + (prepad ? PAD_ALIGN : 0));
- alloc_count++;
-
ERR_FAIL_COND_V(!mem, NULL);
+ atomic_increment(&alloc_count);
+
if (prepad) {
uint64_t *s = (uint64_t *)mem;
*s = p_bytes;
@@ -73,10 +72,8 @@ void *Memory::alloc_static(size_t p_bytes, bool p_pad_align) {
uint8_t *s8 = (uint8_t *)mem;
#ifdef DEBUG_ENABLED
- mem_usage += p_bytes;
- if (mem_usage > max_usage) {
- max_usage = mem_usage;
- }
+ atomic_add(&mem_usage, p_bytes);
+ atomic_exchange_if_greater(&max_usage, mem_usage);
#endif
return s8 + PAD_ALIGN;
} else {
@@ -103,8 +100,12 @@ void *Memory::realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align) {
uint64_t *s = (uint64_t *)mem;
#ifdef DEBUG_ENABLED
- mem_usage -= *s;
- mem_usage += p_bytes;
+ if (p_bytes > *s) {
+ atomic_add(&mem_usage, p_bytes - *s);
+ atomic_exchange_if_greater(&max_usage, mem_usage);
+ } else {
+ atomic_sub(&mem_usage, *s - p_bytes);
+ }
#endif
if (p_bytes == 0) {
@@ -144,14 +145,14 @@ void Memory::free_static(void *p_ptr, bool p_pad_align) {
bool prepad = p_pad_align;
#endif
- alloc_count--;
+ atomic_decrement(&alloc_count);
if (prepad) {
mem -= PAD_ALIGN;
uint64_t *s = (uint64_t *)mem;
#ifdef DEBUG_ENABLED
- mem_usage -= *s;
+ atomic_sub(&mem_usage, *s);
#endif
free(mem);
@@ -161,19 +162,20 @@ void Memory::free_static(void *p_ptr, bool p_pad_align) {
}
}
-size_t Memory::get_mem_available() {
+uint64_t Memory::get_mem_available() {
- return 0xFFFFFFFFFFFFF;
+ return -1; // 0xFFFF...
}
-size_t Memory::get_mem_usage() {
+uint64_t Memory::get_mem_usage() {
#ifdef DEBUG_ENABLED
return mem_usage;
#else
return 0;
#endif
}
-size_t Memory::get_mem_max_usage() {
+
+uint64_t Memory::get_mem_max_usage() {
#ifdef DEBUG_ENABLED
return max_usage;
#else
diff --git a/core/os/memory.h b/core/os/memory.h
index b3eb59995..e1d7138ad 100644
--- a/core/os/memory.h
+++ b/core/os/memory.h
@@ -45,20 +45,20 @@ class Memory {
Memory();
#ifdef DEBUG_ENABLED
- static size_t mem_usage;
- static size_t max_usage;
+ static uint64_t mem_usage;
+ static uint64_t max_usage;
#endif
- static size_t alloc_count;
+ static uint64_t alloc_count;
public:
static void *alloc_static(size_t p_bytes, bool p_pad_align = false);
static void *realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align = false);
static void free_static(void *p_ptr, bool p_pad_align = false);
- static size_t get_mem_available();
- static size_t get_mem_usage();
- static size_t get_mem_max_usage();
+ static uint64_t get_mem_available();
+ static uint64_t get_mem_usage();
+ static uint64_t get_mem_max_usage();
};
class DefaultAllocator {
diff --git a/core/safe_refcount.cpp b/core/safe_refcount.cpp
index d7e529732..971e9ad1d 100644
--- a/core/safe_refcount.cpp
+++ b/core/safe_refcount.cpp
@@ -78,6 +78,15 @@ static _ALWAYS_INLINE_ T _atomic_add_impl(register T *pw, register T val) {
return *pw;
}
+template <class T>
+static _ALWAYS_INLINE_ T _atomic_exchange_if_greater_impl(register T *pw, register T val) {
+
+ if (val > *pw)
+ *pw = val;
+
+ return *pw;
+}
+
#elif defined(__GNUC__)
/* Implementation for GCC & Clang */
@@ -121,6 +130,18 @@ static _ALWAYS_INLINE_ T _atomic_add_impl(register T *pw, register T val) {
return __sync_add_and_fetch(pw, val);
}
+template <class T>
+static _ALWAYS_INLINE_ T _atomic_exchange_if_greater_impl(register T *pw, register T val) {
+
+ while (true) {
+ T tmp = static_cast<T const volatile &>(*pw);
+ if (tmp >= val)
+ return tmp; // already greater, or equal
+ if (__sync_val_compare_and_swap(pw, tmp, val) == tmp)
+ return val;
+ }
+}
+
#elif defined(_MSC_VER)
/* Implementation for MSVC-Windows */
@@ -139,6 +160,15 @@ static _ALWAYS_INLINE_ T _atomic_add_impl(register T *pw, register T val) {
return tmp + 1; \
}
+#define ATOMIC_EXCHANGE_IF_GREATER_BODY(m_pw, m_val, m_win_type, m_win_cmpxchg, m_cpp_type) \
+ while (true) { \
+ m_cpp_type tmp = static_cast<m_cpp_type const volatile &>(*(m_pw)); \
+ if (tmp >= m_val) \
+ return tmp; /* already greater, or equal */ \
+ if (m_win_cmpxchg((m_win_type volatile *)(m_pw), m_val, tmp) == tmp) \
+ return m_val; \
+ }
+
static _ALWAYS_INLINE_ uint32_t _atomic_conditional_increment_impl(register uint32_t *pw) {
ATOMIC_CONDITIONAL_INCREMENT_BODY(pw, LONG, InterlockedCompareExchange, uint32_t)
@@ -156,11 +186,7 @@ static _ALWAYS_INLINE_ uint32_t _atomic_increment_impl(register uint32_t *pw) {
static _ALWAYS_INLINE_ uint32_t _atomic_sub_impl(register uint32_t *pw, register uint32_t val) {
-#if _WIN32_WINNT >= 0x0601 // Windows 7+
- return InterlockedExchangeSubtract(pw, val) - val;
-#else
return InterlockedExchangeAdd((LONG volatile *)pw, -(int32_t)val) - val;
-#endif
}
static _ALWAYS_INLINE_ uint32_t _atomic_add_impl(register uint32_t *pw, register uint32_t val) {
@@ -168,6 +194,11 @@ static _ALWAYS_INLINE_ uint32_t _atomic_add_impl(register uint32_t *pw, register
return InterlockedAdd((LONG volatile *)pw, val);
}
+static _ALWAYS_INLINE_ uint32_t _atomic_exchange_if_greater_impl(register uint32_t *pw, register uint32_t val) {
+
+ ATOMIC_EXCHANGE_IF_GREATER_BODY(pw, val, LONG, InterlockedCompareExchange, uint32_t)
+}
+
static _ALWAYS_INLINE_ uint64_t _atomic_conditional_increment_impl(register uint64_t *pw) {
ATOMIC_CONDITIONAL_INCREMENT_BODY(pw, LONGLONG, InterlockedCompareExchange64, uint64_t)
@@ -185,11 +216,7 @@ static _ALWAYS_INLINE_ uint64_t _atomic_increment_impl(register uint64_t *pw) {
static _ALWAYS_INLINE_ uint64_t _atomic_sub_impl(register uint64_t *pw, register uint64_t val) {
-#if _WIN32_WINNT >= 0x0601 && !defined(UWP_ENABLED) // Windows 7+ except UWP
- return InterlockedExchangeSubtract64(pw, val) - val;
-#else
return InterlockedExchangeAdd64((LONGLONG volatile *)pw, -(int64_t)val) - val;
-#endif
}
static _ALWAYS_INLINE_ uint64_t _atomic_add_impl(register uint64_t *pw, register uint64_t val) {
@@ -197,6 +224,11 @@ static _ALWAYS_INLINE_ uint64_t _atomic_add_impl(register uint64_t *pw, register
return InterlockedAdd64((LONGLONG volatile *)pw, val);
}
+static _ALWAYS_INLINE_ uint64_t _atomic_exchange_if_greater_impl(register uint64_t *pw, register uint64_t val) {
+
+ ATOMIC_EXCHANGE_IF_GREATER_BODY(pw, val, LONGLONG, InterlockedCompareExchange64, uint64_t)
+}
+
#else
//no threads supported?
@@ -226,6 +258,10 @@ uint32_t atomic_add(register uint32_t *pw, register uint32_t val) {
return _atomic_add_impl(pw, val);
}
+uint32_t atomic_exchange_if_greater(register uint32_t *pw, register uint32_t val) {
+ return _atomic_exchange_if_greater_impl(pw, val);
+}
+
uint64_t atomic_conditional_increment(register uint64_t *counter) {
return _atomic_conditional_increment_impl(counter);
}
@@ -245,3 +281,7 @@ uint64_t atomic_sub(register uint64_t *pw, register uint64_t val) {
uint64_t atomic_add(register uint64_t *pw, register uint64_t val) {
return _atomic_add_impl(pw, val);
}
+
+uint64_t atomic_exchange_if_greater(register uint64_t *pw, register uint64_t val) {
+ return _atomic_exchange_if_greater_impl(pw, val);
+}
diff --git a/core/safe_refcount.h b/core/safe_refcount.h
index a2d2b5e12..ed0620c77 100644
--- a/core/safe_refcount.h
+++ b/core/safe_refcount.h
@@ -41,12 +41,14 @@ uint32_t atomic_decrement(register uint32_t *pw);
uint32_t atomic_increment(register uint32_t *pw);
uint32_t atomic_sub(register uint32_t *pw, register uint32_t val);
uint32_t atomic_add(register uint32_t *pw, register uint32_t val);
+uint32_t atomic_exchange_if_greater(register uint32_t *pw, register uint32_t val);
uint64_t atomic_conditional_increment(register uint64_t *counter);
uint64_t atomic_decrement(register uint64_t *pw);
uint64_t atomic_increment(register uint64_t *pw);
uint64_t atomic_sub(register uint64_t *pw, register uint64_t val);
uint64_t atomic_add(register uint64_t *pw, register uint64_t val);
+uint64_t atomic_exchange_if_greater(register uint64_t *pw, register uint64_t val);
struct SafeRefCount {
diff --git a/doc/base/classes.xml b/doc/base/classes.xml
index 058753132..70a7dcb65 100644
--- a/doc/base/classes.xml
+++ b/doc/base/classes.xml
@@ -10169,12 +10169,73 @@
<description>
</description>
</method>
+ <method name="create_shape_owner">
+ <return type="int">
+ </return>
+ <argument index="0" name="owner" type="Object">
+ </argument>
+ <description>
+ Creates new holder for the shapes. Argument is a [CollisionShape] node. It will return owner_id which usually you will want to save for later use.
+ </description>
+ </method>
<method name="get_rid" qualifiers="const">
<return type="RID">
</return>
<description>
</description>
</method>
+ <method name="get_shape_owners">
+ <return type="Array">
+ </return>
+ <description>
+ Shape owner is a node which is holding concrete shape resources. This method will return an array which is holding an integer numbers that are representing unique ID of each owner. You can use those ids when you are using others shape_owner methods.
+ </description>
+ </method>
+ <method name="shape_owner_clear_shapes">
+ <argument index="0" name="owner_id" type="int">
+ </argument>
+ <description>
+ Will remove all the shapes associated with given owner.
+ </description>
+ </method>
+ <method name="shape_owner_get_shape">
+ <return type="Shape">
+ </return>
+ <argument index="0" name="owner_id" type="int">
+ </argument>
+ <argument index="1" name="shape_id" type="int">
+ </argument>
+ <description>
+ Will return a [Shape]. First argument owner_id is an integer that can be obtained from [method get_shape_owners]. Shape_id is a position of the shape inside owner; it's a value in range from 0 to [method shape_owner_get_shape_count].
+ </description>
+ </method>
+ <method name="shape_owner_get_shape_count">
+ <return type="int">
+ </return>
+ <argument index="0" name="owner_id" type="int">
+ </argument>
+ <description>
+ Returns number of shapes to which given owner is associated to.
+ </description>
+ </method>
+ <method name="shape_owner_get_transform">
+ <return type="Transform">
+ </return>
+ <argument index="0" name="owner_id" type="int">
+ </argument>
+ <description>
+ Will return [Transform] of an owner node.
+ </description>
+ </method>
+ <method name="shape_owner_remove_shape">
+ <argument index="0" name="owner_id" type="int">
+ </argument>
+ <argument index="1" name="shape_id" type="int">
+ </argument>
+ <description>
+ Removes related shape from the owner.
+ </description>
+ </method>
<method name="is_ray_pickable" qualifiers="const">
<return type="bool">
</return>
@@ -10245,6 +10306,15 @@
<description>
</description>
</method>
+ <method name="create_shape_owner">
+ <return type="int">
+ </return>
+ <argument index="0" name="owner" type="Object">
+ </argument>
+ <description>
+ Creates new holder for the shapes. Argument is a [CollisionShape2D] node. It will return owner_id which usually you will want to save for later use.
+ </description>
+ </method>
<method name="get_rid" qualifiers="const">
<return type="RID">
</return>
@@ -10252,6 +10322,58 @@
Return the RID of this object.
</description>
</method>
+ <method name="get_shape_owners">
+ <return type="Array">
+ </return>
+ <description>
+ Shape owner is a node which is holding concrete shape resources. This method will return an array which is holding an integer numbers that are representing unique ID of each owner. You can use those ids when you are using others shape_owner methods.
+ </description>
+ </method>
+ <method name="shape_owner_clear_shapes">
+ <argument index="0" name="owner_id" type="int">
+ </argument>
+ <description>
+ Will remove all the shapes associated with given owner.
+ </description>
+ </method>
+ <method name="shape_owner_get_shape">
+ <return type="Shape2D">
+ </return>
+ <argument index="0" name="owner_id" type="int">
+ </argument>
+ <argument index="1" name="shape_id" type="int">
+ </argument>
+ <description>
+ Will return a [Shape2D]. First argument owner_id is an integer that can be obtained from [method get_shape_owners]. Shape_id is a position of the shape inside owner; it's a value in range from 0 to [method shape_owner_get_shape_count].
+ </description>
+ </method>
+ <method name="shape_owner_get_shape_count">
+ <return type="int">
+ </return>
+ <argument index="0" name="owner_id" type="int">
+ </argument>
+ <description>
+ Returns number of shapes to which given owner is associated to.
+ </description>
+ </method>
+ <method name="shape_owner_get_transform">
+ <return type="Transform2D">
+ </return>
+ <argument index="0" name="owner_id" type="int">
+ </argument>
+ <description>
+ Will return [Transform2D] of an owner node.
+ </description>
+ </method>
+ <method name="shape_owner_remove_shape">
+ <argument index="0" name="owner_id" type="int">
+ </argument>
+ <argument index="1" name="shape_id" type="int">
+ </argument>
+ <description>
+ Removes related shape from the owner.
+ </description>
+ </method>
<method name="is_pickable" qualifiers="const">
<return type="bool">
</return>
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index 6b985c7b4..df16de947 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -163,6 +163,13 @@ Ref<Theme> create_editor_theme() {
theme->set_color("light_color_1", "Editor", light_color_1);
theme->set_color("light_color_2", "Editor", light_color_2);
+ Color success_color = highlight_color.linear_interpolate(Color(0, 1, .8), 0.8);
+ Color warning_color = highlight_color.linear_interpolate(Color(1, 1, .2), 0.8);
+ Color error_color = highlight_color.linear_interpolate(Color(1, .2, .2), 0.8);
+ theme->set_color("success_color", "Editor", success_color);
+ theme->set_color("warning_color", "Editor", warning_color);
+ theme->set_color("error_color", "Editor", error_color);
+
// Checkbox icon
theme->set_icon("checked", "CheckBox", theme->get_icon("GuiChecked", "EditorIcons"));
theme->set_icon("unchecked", "CheckBox", theme->get_icon("GuiUnchecked", "EditorIcons"));
@@ -307,8 +314,8 @@ Ref<Theme> create_editor_theme() {
theme->set_icon("arrow_collapsed", "Tree", theme->get_icon("GuiTreeArrowRight", "EditorIcons"));
theme->set_icon("select_arrow", "Tree", theme->get_icon("GuiDropdown", "EditorIcons"));
theme->set_stylebox("bg_focus", "Tree", focus_sbt);
- theme->set_stylebox("custom_button", "Tree", style_button_type);
- theme->set_stylebox("custom_button_pressed", "Tree", style_button_type);
+ theme->set_stylebox("custom_button", "Tree", make_empty_stylebox());
+ theme->set_stylebox("custom_button_pressed", "Tree", make_empty_stylebox());
theme->set_stylebox("custom_button_hover", "Tree", style_button_type);
theme->set_color("custom_button_font_highlight", "Tree", HIGHLIGHT_COLOR_LIGHT);
diff --git a/editor/icons/2x/icon_GUI_dropdown.png b/editor/icons/2x/icon_GUI_dropdown.png
index c95937843..78d3352e4 100644
--- a/editor/icons/2x/icon_GUI_dropdown.png
+++ b/editor/icons/2x/icon_GUI_dropdown.png
Binary files differ
diff --git a/editor/icons/icon_GUI_dropdown.png b/editor/icons/icon_GUI_dropdown.png
index 4bd654483..d21cdb634 100644
--- a/editor/icons/icon_GUI_dropdown.png
+++ b/editor/icons/icon_GUI_dropdown.png
Binary files differ
diff --git a/editor/icons/source/icon_GUI_dropdown.svg b/editor/icons/source/icon_GUI_dropdown.svg
index f313b0998..897f63c26 100644
--- a/editor/icons/source/icon_GUI_dropdown.svg
+++ b/editor/icons/source/icon_GUI_dropdown.svg
@@ -9,9 +9,9 @@
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="8"
+ width="14"
height="14"
- viewBox="0 0 8 14"
+ viewBox="0 0 14 14"
id="svg2"
version="1.1"
inkscape:version="0.92+devel unknown"
@@ -28,9 +28,9 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
- inkscape:zoom="45.254834"
- inkscape:cx="1.2944669"
- inkscape:cy="5.9830116"
+ inkscape:zoom="32"
+ inkscape:cx="6.5843041"
+ inkscape:cy="6.8000184"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
@@ -72,21 +72,21 @@
id="layer1"
transform="translate(0,-1038.3622)">
<circle
- style="fill:#ffffff;fill-opacity:0.58823532;stroke-width:2;stroke-linejoin:round;stroke-opacity:0.39215686"
+ style="fill:#ffffff;fill-opacity:0.58823529;stroke-width:2;stroke-linejoin:round;stroke-opacity:0.39215686"
id="path4268"
- cx="4.5"
+ cx="7.5"
cy="1040.8622"
r="1.5" />
<circle
r="1.5"
cy="1045.8622"
- cx="4.5"
+ cx="7.5"
id="circle4271"
- style="fill:#ffffff;fill-opacity:0.58823532;stroke-width:2;stroke-linejoin:round;stroke-opacity:0.39215686" />
+ style="fill:#ffffff;fill-opacity:0.58823529;stroke-width:2;stroke-linejoin:round;stroke-opacity:0.39215686" />
<circle
- style="fill:#ffffff;fill-opacity:0.58823532;stroke-width:2;stroke-linejoin:round;stroke-opacity:0.39215686"
+ style="fill:#ffffff;fill-opacity:0.58823529;stroke-width:2;stroke-linejoin:round;stroke-opacity:0.39215686"
id="circle4273"
- cx="4.5"
+ cx="7.5"
cy="1050.8622"
r="1.5" />
</g>
diff --git a/editor/icons/source/icon_connect.svg b/editor/icons/source/icon_connect.svg
index 745d3cc43..15c8b481a 100644
--- a/editor/icons/source/icon_connect.svg
+++ b/editor/icons/source/icon_connect.svg
@@ -14,7 +14,7 @@
viewBox="0 0 16 16"
id="svg2"
version="1.1"
- inkscape:version="0.91 r13725"
+ inkscape:version="0.92+devel unknown"
inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_add_track.png"
inkscape:export-xdpi="45"
inkscape:export-ydpi="45"
@@ -28,9 +28,9 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
- inkscape:zoom="22.627418"
- inkscape:cx="0.78663326"
- inkscape:cy="12.940707"
+ inkscape:zoom="32.000001"
+ inkscape:cx="13.864856"
+ inkscape:cy="7.2235346"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
@@ -46,7 +46,8 @@
inkscape:window-height="1016"
inkscape:window-x="0"
inkscape:window-y="27"
- inkscape:window-maximized="1">
+ inkscape:window-maximized="1"
+ inkscape:document-rotation="0">
<inkscape:grid
type="xygrid"
id="grid3336" />
@@ -68,10 +69,37 @@
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-1036.3622)">
+ <circle
+ style="fill:#e0e0e0;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round"
+ id="path4266"
+ cx="4"
+ cy="1048.3622"
+ r="2" />
<path
- style="fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="M 7 2 A 2 2 0 0 0 5 4 L 5 7 L 1 7 L 1 9 L 5 9 L 5 12 A 2 2 0 0 0 7 14 L 11 14 L 11 12 L 14 12 L 14 10 L 11 10 L 11 6 L 14 6 L 14 4 L 11 4 L 11 2 L 7 2 z "
- transform="translate(0,1036.3622)"
- id="rect4155" />
+ id="circle4268"
+ style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:type="arc"
+ sodipodi:cx="4"
+ sodipodi:cy="1048.3622"
+ sodipodi:rx="5"
+ sodipodi:ry="5"
+ sodipodi:start="4.712389"
+ sodipodi:end="0"
+ sodipodi:arc-type="arc"
+ d="M 4.0000001,1043.3622 A 5,5 0 0 1 9,1048.3622"
+ sodipodi:open="true" />
+ <path
+ id="circle4270"
+ style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:type="arc"
+ sodipodi:cx="4"
+ sodipodi:cy="1048.3622"
+ sodipodi:rx="9"
+ sodipodi:ry="9"
+ sodipodi:start="4.712389"
+ sodipodi:end="0"
+ sodipodi:open="true"
+ sodipodi:arc-type="arc"
+ d="m 4.0000002,1039.3622 a 9,9 0 0 1 8.9999998,9" />
</g>
</svg>
diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp
index 98020ed9b..c0c507c2d 100644
--- a/editor/import/resource_importer_texture.cpp
+++ b/editor/import/resource_importer_texture.cpp
@@ -236,7 +236,7 @@ void ResourceImporterTexture::_save_stex(const Ref<Image> &p_image, const String
format |= StreamTexture::FORMAT_BIT_DETECT_NORMAL;
if ((p_compress_mode == COMPRESS_LOSSLESS || p_compress_mode == COMPRESS_LOSSY) && p_image->get_format() > Image::FORMAT_RGBA8) {
- p_compress_mode == COMPRESS_UNCOMPRESSED; //these can't go as lossy
+ p_compress_mode = COMPRESS_UNCOMPRESSED; //these can't go as lossy
}
switch (p_compress_mode) {
diff --git a/editor/import/resource_importer_wav.cpp b/editor/import/resource_importer_wav.cpp
index 18c4bed5d..8cb712cb7 100644
--- a/editor/import/resource_importer_wav.cpp
+++ b/editor/import/resource_importer_wav.cpp
@@ -291,7 +291,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
bool limit_rate = p_options["force/max_rate"];
int limit_rate_hz = p_options["force/max_rate_hz"];
- if (limit_rate && rate > limit_rate_hz) {
+ if (limit_rate && rate > limit_rate_hz && rate > 0 && frames > 0) {
//resampleeee!!!
int new_data_frames = frames * limit_rate_hz / rate;
Vector<float> new_data;
@@ -356,7 +356,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
bool trim = p_options["edit/trim"];
- if (trim && !loop) {
+ if (trim && !loop && format_channels > 0) {
int first = 0;
int last = (frames * format_channels) - 1;
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index c31e11cc3..2d77bfb2c 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -3142,7 +3142,7 @@ void SpatialEditor::_menu_item_pressed(int p_option) {
xform_scale[i]->set_text("1");
}
- xform_dialog->popup_centered(Size2(200, 200));
+ xform_dialog->popup_centered(Size2(320, 240) * EDSCALE);
} break;
case MENU_VIEW_USE_1_VIEWPORT: {
@@ -3964,55 +3964,59 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
xform_dialog = memnew(ConfirmationDialog);
xform_dialog->set_title(TTR("Transform Change"));
add_child(xform_dialog);
+
+ VBoxContainer *xform_vbc = memnew(VBoxContainer);
+ xform_dialog->add_child(xform_vbc);
+
Label *l = memnew(Label);
l->set_text(TTR("Translate:"));
- l->set_position(Point2(5, 5));
- xform_dialog->add_child(l);
+ xform_vbc->add_child(l);
+
+ HBoxContainer *xform_hbc = memnew(HBoxContainer);
+ xform_vbc->add_child(xform_hbc);
for (int i = 0; i < 3; i++) {
xform_translate[i] = memnew(LineEdit);
- xform_translate[i]->set_position(Point2(15 + i * 60, 22));
- xform_translate[i]->set_size(Size2(50, 12));
- xform_dialog->add_child(xform_translate[i]);
+ xform_translate[i]->set_h_size_flags(SIZE_EXPAND_FILL);
+ xform_hbc->add_child(xform_translate[i]);
}
l = memnew(Label);
l->set_text(TTR("Rotate (deg.):"));
- l->set_position(Point2(5, 45));
- xform_dialog->add_child(l);
+ xform_vbc->add_child(l);
+
+ xform_hbc = memnew(HBoxContainer);
+ xform_vbc->add_child(xform_hbc);
for (int i = 0; i < 3; i++) {
xform_rotate[i] = memnew(LineEdit);
- xform_rotate[i]->set_position(Point2(15 + i * 60, 62));
- xform_rotate[i]->set_size(Size2(50, 22));
- xform_dialog->add_child(xform_rotate[i]);
+ xform_rotate[i]->set_h_size_flags(SIZE_EXPAND_FILL);
+ xform_hbc->add_child(xform_rotate[i]);
}
l = memnew(Label);
l->set_text(TTR("Scale (ratio):"));
- l->set_position(Point2(5, 85));
- xform_dialog->add_child(l);
+ xform_vbc->add_child(l);
+
+ xform_hbc = memnew(HBoxContainer);
+ xform_vbc->add_child(xform_hbc);
for (int i = 0; i < 3; i++) {
xform_scale[i] = memnew(LineEdit);
- xform_scale[i]->set_position(Point2(15 + i * 60, 102));
- xform_scale[i]->set_size(Size2(50, 22));
- xform_dialog->add_child(xform_scale[i]);
+ xform_scale[i]->set_h_size_flags(SIZE_EXPAND_FILL);
+ xform_hbc->add_child(xform_scale[i]);
}
l = memnew(Label);
l->set_text(TTR("Transform Type"));
- l->set_position(Point2(5, 125));
- xform_dialog->add_child(l);
+ xform_vbc->add_child(l);
xform_type = memnew(OptionButton);
- xform_type->set_anchor(MARGIN_RIGHT, ANCHOR_END);
- xform_type->set_begin(Point2(15, 142));
- xform_type->set_end(Point2(15, 75));
+ xform_type->set_h_size_flags(SIZE_EXPAND_FILL);
xform_type->add_item(TTR("Pre"));
xform_type->add_item(TTR("Post"));
- xform_dialog->add_child(xform_type);
+ xform_vbc->add_child(xform_type);
xform_dialog->connect("confirmed", this, "_xform_dialog_action");
diff --git a/editor/plugins/texture_editor_plugin.cpp b/editor/plugins/texture_editor_plugin.cpp
index 125d90646..57c27a8a7 100644
--- a/editor/plugins/texture_editor_plugin.cpp
+++ b/editor/plugins/texture_editor_plugin.cpp
@@ -102,14 +102,24 @@ void TextureEditor::_notification(int p_what) {
}
}
+void TextureEditor::_changed_callback(Object *p_changed, const char *p_prop) {
+
+ if (!is_visible())
+ return;
+ update();
+}
+
void TextureEditor::edit(Ref<Texture> p_texture) {
+ if (!texture.is_null())
+ texture->remove_change_receptor(this);
+
texture = p_texture;
- if (!texture.is_null())
+ if (!texture.is_null()) {
+ texture->add_change_receptor(this);
update();
- else {
-
+ } else {
hide();
}
}
diff --git a/editor/plugins/texture_editor_plugin.h b/editor/plugins/texture_editor_plugin.h
index 938298353..13f8dd7fb 100644
--- a/editor/plugins/texture_editor_plugin.h
+++ b/editor/plugins/texture_editor_plugin.h
@@ -43,6 +43,7 @@ class TextureEditor : public Control {
protected:
void _notification(int p_what);
void _gui_input(Ref<InputEvent> p_event);
+ void _changed_callback(Object *p_changed, const char *p_prop);
static void _bind_methods();
public:
diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp
index 8a7dcea39..4cd18b090 100644
--- a/editor/plugins/texture_region_editor_plugin.cpp
+++ b/editor/plugins/texture_region_editor_plugin.cpp
@@ -617,38 +617,24 @@ void TextureRegionEditor::_bind_methods() {
}
void TextureRegionEditor::edit(Object *p_obj) {
- if (node_sprite && node_sprite->is_connected("texture_changed", this, "_edit_region"))
- node_sprite->disconnect("texture_changed", this, "_edit_region");
- if (node_patch9 && node_patch9->is_connected("texture_changed", this, "_edit_region"))
- node_patch9->disconnect("texture_changed", this, "_edit_region");
- if (obj_styleBox.is_valid() && obj_styleBox->is_connected("texture_changed", this, "_edit_region"))
- obj_styleBox->disconnect("texture_changed", this, "_edit_region");
- if (atlas_tex.is_valid() && atlas_tex->is_connected("atlas_changed", this, "_edit_region"))
- atlas_tex->disconnect("atlas_changed", this, "_edit_region");
+ if (node_sprite)
+ node_sprite->remove_change_receptor(this);
+ if (node_patch9)
+ node_patch9->remove_change_receptor(this);
+ if (obj_styleBox.is_valid())
+ obj_styleBox->remove_change_receptor(this);
+ if (atlas_tex.is_valid())
+ atlas_tex->remove_change_receptor(this);
if (p_obj) {
node_sprite = p_obj->cast_to<Sprite>();
node_patch9 = p_obj->cast_to<NinePatchRect>();
if (p_obj->cast_to<StyleBoxTexture>())
obj_styleBox = Ref<StyleBoxTexture>(p_obj->cast_to<StyleBoxTexture>());
- if (p_obj->cast_to<AtlasTexture>()) {
+ if (p_obj->cast_to<AtlasTexture>())
atlas_tex = Ref<AtlasTexture>(p_obj->cast_to<AtlasTexture>());
- atlas_tex->connect("atlas_changed", this, "_edit_region");
- } else {
- p_obj->connect("texture_changed", this, "_edit_region");
- }
p_obj->add_change_receptor(this);
- p_obj->connect("tree_exited", this, "_node_removed", varray(p_obj), CONNECT_ONESHOT);
_edit_region();
} else {
- if (node_sprite)
- node_sprite->disconnect("tree_exited", this, "_node_removed");
- else if (node_patch9)
- node_patch9->disconnect("tree_exited", this, "_node_removed");
- else if (obj_styleBox.is_valid())
- obj_styleBox->disconnect("tree_exited", this, "_node_removed");
- else if (atlas_tex.is_valid())
- atlas_tex->disconnect("tree_exited", this, "_node_removed");
-
node_sprite = NULL;
node_patch9 = NULL;
obj_styleBox = Ref<StyleBoxTexture>(NULL);
@@ -658,9 +644,11 @@ void TextureRegionEditor::edit(Object *p_obj) {
}
void TextureRegionEditor::_changed_callback(Object *p_changed, const char *p_prop) {
- if ((String)p_prop == "region_rect") {
+
+ if (!is_visible())
+ return;
+ if (p_prop == StringName("atlas") || p_prop == StringName("texture"))
_edit_region();
- }
}
void TextureRegionEditor::_edit_region() {
diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp
index 6d23e874d..6238cad14 100644
--- a/editor/project_settings_editor.cpp
+++ b/editor/project_settings_editor.cpp
@@ -140,7 +140,7 @@ void ProjectSettingsEditor::_action_edited() {
add_at = "input/" + old_name;
message->set_text(TTR("Invalid action (anything goes but '/' or ':')."));
- message->popup_centered(Size2(300, 100));
+ message->popup_centered(Size2(300, 100) * EDSCALE);
return;
}
@@ -152,7 +152,7 @@ void ProjectSettingsEditor::_action_edited() {
add_at = "input/" + old_name;
message->set_text(vformat(TTR("Action '%s' already exists!"), new_name));
- message->popup_centered(Size2(300, 100));
+ message->popup_centered(Size2(300, 100) * EDSCALE);
return;
}
@@ -399,7 +399,7 @@ void ProjectSettingsEditor::_add_item(int p_item, Ref<InputEvent> p_exiting_even
device_index->add_item(TTR("Button 7"));
device_index->add_item(TTR("Button 8"));
device_index->add_item(TTR("Button 9"));
- device_input->popup_centered_minsize(Size2(350, 95));
+ device_input->popup_centered_minsize(Size2(350, 95) * EDSCALE);
Ref<InputEventMouseButton> mb = p_exiting_event;
if (mb.is_valid()) {
@@ -420,7 +420,7 @@ void ProjectSettingsEditor::_add_item(int p_item, Ref<InputEvent> p_exiting_even
String desc = _axis_names[i];
device_index->add_item(TTR("Axis") + " " + itos(i / 2) + " " + (i & 1 ? "+" : "-") + desc);
}
- device_input->popup_centered_minsize(Size2(350, 95));
+ device_input->popup_centered_minsize(Size2(350, 95) * EDSCALE);
Ref<InputEventJoypadMotion> jm = p_exiting_event;
if (jm.is_valid()) {
@@ -441,7 +441,7 @@ void ProjectSettingsEditor::_add_item(int p_item, Ref<InputEvent> p_exiting_even
device_index->add_item(itos(i) + ": " + String(_button_names[i]));
}
- device_input->popup_centered_minsize(Size2(350, 95));
+ device_input->popup_centered_minsize(Size2(350, 95) * EDSCALE);
Ref<InputEventJoypadButton> jb = p_exiting_event;
if (jb.is_valid()) {
@@ -835,13 +835,13 @@ void ProjectSettingsEditor::_action_add() {
String action = action_name->get_text();
if (action.find("/") != -1 || action.find(":") != -1 || action == "") {
message->set_text(TTR("Invalid action (anything goes but '/' or ':')."));
- message->popup_centered(Size2(300, 100));
+ message->popup_centered(Size2(300, 100) * EDSCALE);
return;
}
if (ProjectSettings::get_singleton()->has("input/" + action)) {
message->set_text(vformat(TTR("Action '%s' already exists!"), action));
- message->popup_centered(Size2(300, 100));
+ message->popup_centered(Size2(300, 100) * EDSCALE);
return;
}
@@ -879,7 +879,7 @@ void ProjectSettingsEditor::_save() {
Error err = ProjectSettings::get_singleton()->save();
message->set_text(err != OK ? TTR("Error saving settings.") : TTR("Settings saved OK."));
- message->popup_centered(Size2(300, 100));
+ message->popup_centered(Size2(300, 100) * EDSCALE);
}
void ProjectSettingsEditor::_settings_prop_edited(const String &p_name) {
@@ -1554,7 +1554,7 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
add = memnew(Button);
hbc->add_child(add);
- add->set_custom_minimum_size(Size2(150, 0));
+ add->set_custom_minimum_size(Size2(150, 0) * EDSCALE);
add->set_text(TTR("Add"));
add->connect("pressed", this, "_action_add");
diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp
index d81161ae9..0748c43b5 100644
--- a/editor/script_create_dialog.cpp
+++ b/editor/script_create_dialog.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "script_create_dialog.h"
+#include "editor/editor_node.h"
#include "editor/editor_scale.h"
#include "editor_file_system.h"
#include "io/resource_saver.h"
@@ -229,7 +230,7 @@ void ScriptCreateDialog::_lang_changed(int l) {
List<String> extensions;
// get all possible extensions for script
for (int l = 0; l < language_menu->get_item_count(); l++) {
- language->get_recognized_extensions(&extensions);
+ ScriptServer::get_language(l)->get_recognized_extensions(&extensions);
}
for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
@@ -240,8 +241,11 @@ void ScriptCreateDialog::_lang_changed(int l) {
}
}
}
- file_path->set_text(path);
+ } else {
+ path = "class" + selected_ext;
+ _path_changed(path);
}
+ file_path->set_text(path);
bool use_templates = language->is_using_templates();
template_menu->set_disabled(!use_templates);
@@ -403,9 +407,9 @@ void ScriptCreateDialog::_msg_script_valid(bool valid, const String &p_msg) {
error_label->set_text(TTR(p_msg));
if (valid) {
- error_label->add_color_override("font_color", Color(0, 1.0, 0.8, 0.8));
+ error_label->add_color_override("font_color", get_color("success_color", "Editor"));
} else {
- error_label->add_color_override("font_color", Color(1, 0.2, 0.2, 0.8));
+ error_label->add_color_override("font_color", get_color("error_color", "Editor"));
}
}
@@ -413,9 +417,9 @@ void ScriptCreateDialog::_msg_path_valid(bool valid, const String &p_msg) {
path_error_label->set_text(TTR(p_msg));
if (valid) {
- path_error_label->add_color_override("font_color", Color(0, 1.0, 0.8, 0.8));
+ path_error_label->add_color_override("font_color", get_color("success_color", "Editor"));
} else {
- path_error_label->add_color_override("font_color", Color(1, 0.4, 0.0, 0.8));
+ path_error_label->add_color_override("font_color", get_color("error_color", "Editor"));
}
}
@@ -543,19 +547,6 @@ ScriptCreateDialog::ScriptCreateDialog() {
gc = memnew(GridContainer);
gc->set_columns(2);
- /* Error Stylebox Background */
-
- StyleBoxFlat *sb = memnew(StyleBoxFlat);
- sb->set_bg_color(Color(0, 0, 0, 0.05));
- sb->set_light_color(Color(1, 1, 1, 0.05));
- sb->set_dark_color(Color(1, 1, 1, 0.05));
- sb->set_border_blend(false);
- sb->set_border_size(1);
- sb->set_default_margin(MARGIN_TOP, 10.0 * EDSCALE);
- sb->set_default_margin(MARGIN_BOTTOM, 10.0 * EDSCALE);
- sb->set_default_margin(MARGIN_LEFT, 10.0 * EDSCALE);
- sb->set_default_margin(MARGIN_RIGHT, 10.0 * EDSCALE);
-
/* Error Messages Field */
vb = memnew(VBoxContainer);
@@ -582,7 +573,7 @@ ScriptCreateDialog::ScriptCreateDialog() {
pc = memnew(PanelContainer);
pc->set_h_size_flags(Control::SIZE_FILL);
- pc->add_style_override("panel", sb);
+ pc->add_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_stylebox("bg", "Tree"));
pc->add_child(vb);
/* Margins */
diff --git a/main/main.cpp b/main/main.cpp
index 8960d85c4..ed6ed019f 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -1704,6 +1704,7 @@ void Main::cleanup() {
#endif
if (audio_server) {
+ audio_server->finish();
memdelete(audio_server);
}
diff --git a/main/performance.cpp b/main/performance.cpp
index c819e15f7..3d8e21bf3 100644
--- a/main/performance.cpp
+++ b/main/performance.cpp
@@ -117,8 +117,8 @@ float Performance::get_monitor(Monitor p_monitor) const {
case TIME_FIXED_PROCESS: return _fixed_process_time;
case MEMORY_STATIC: return Memory::get_mem_usage();
case MEMORY_DYNAMIC: return MemoryPool::total_memory;
- case MEMORY_STATIC_MAX: return MemoryPool::max_memory;
- case MEMORY_DYNAMIC_MAX: return 0;
+ case MEMORY_STATIC_MAX: return Memory::get_mem_max_usage();
+ case MEMORY_DYNAMIC_MAX: return MemoryPool::max_memory;
case MEMORY_MESSAGE_BUFFER_MAX: return MessageQueue::get_singleton()->get_max_buffer_usage();
case OBJECT_COUNT: return ObjectDB::get_object_count();
case OBJECT_RESOURCE_COUNT: return ResourceCache::get_cached_resource_count();
diff --git a/platform/android/SCsub b/platform/android/SCsub
index 7fb3c876b..b124a1a5a 100644
--- a/platform/android/SCsub
+++ b/platform/android/SCsub
@@ -141,6 +141,8 @@ if env['android_arch'] == 'armv6':
lib_arch_dir = 'armeabi'
elif env['android_arch'] == 'armv7':
lib_arch_dir = 'armeabi-v7a'
+elif env['android_arch'] == 'arm64v8':
+ lib_arch_dir = 'arm64-v8a'
elif env['android_arch'] == 'x86':
lib_arch_dir = 'x86'
else:
diff --git a/platform/android/detect.py b/platform/android/detect.py
index fae1df3f2..ad5bfb494 100644
--- a/platform/android/detect.py
+++ b/platform/android/detect.py
@@ -22,7 +22,7 @@ def get_opts():
return [
('ANDROID_NDK_ROOT', 'Path to the Android NDK', os.environ.get("ANDROID_NDK_ROOT", 0)),
('ndk_platform', 'Target platform (android-<api>, e.g. "android-18")', "android-18"),
- ('android_arch', 'Target architecture (armv7/armv6/x86)', "armv7"),
+ ('android_arch', 'Target architecture (armv7/armv6/arm64v8/x86)', "armv7"),
('android_neon', 'Enable NEON support (armv7 only)', "yes"),
('android_stl', 'Enable Android STL support (for modules)', "no")
]
@@ -89,7 +89,7 @@ def configure(env):
## Architecture
- if env['android_arch'] not in ['armv7', 'armv6', 'x86']:
+ if env['android_arch'] not in ['armv7', 'armv6', 'arm64v8', 'x86']:
env['android_arch'] = 'armv7'
neon_text = ""
@@ -99,18 +99,21 @@ def configure(env):
can_vectorize = True
if env['android_arch'] == 'x86':
+ env['ARCH'] = 'arch-x86'
env.extra_suffix = ".x86" + env.extra_suffix
target_subpath = "x86-4.9"
abi_subpath = "i686-linux-android"
arch_subpath = "x86"
env["x86_libtheora_opt_gcc"] = True
elif env['android_arch'] == 'armv6':
+ env['ARCH'] = 'arch-arm'
env.extra_suffix = ".armv6" + env.extra_suffix
target_subpath = "arm-linux-androideabi-4.9"
abi_subpath = "arm-linux-androideabi"
arch_subpath = "armeabi"
can_vectorize = False
elif env["android_arch"] == "armv7":
+ env['ARCH'] = 'arch-arm'
target_subpath = "arm-linux-androideabi-4.9"
abi_subpath = "arm-linux-androideabi"
arch_subpath = "armeabi-v7a"
@@ -118,6 +121,12 @@ def configure(env):
env.extra_suffix = ".armv7.neon" + env.extra_suffix
else:
env.extra_suffix = ".armv7" + env.extra_suffix
+ elif env["android_arch"] == "arm64v8":
+ env['ARCH'] = 'arch-arm64'
+ target_subpath = "aarch64-linux-android-4.9"
+ abi_subpath = "aarch64-linux-android"
+ arch_subpath = "arm64-v8a"
+ env.extra_suffix = ".armv8" + env.extra_suffix
## Build type
@@ -149,6 +158,8 @@ def configure(env):
elif (sys.platform.startswith('win')):
if (platform.machine().endswith('64')):
host_subpath = "windows-x86_64"
+ if env["android_arch"] == "arm64v8":
+ mt_link = False
else:
mt_link = False
host_subpath = "windows"
@@ -166,11 +177,6 @@ def configure(env):
env['RANLIB'] = tools_path + "/ranlib"
env['AS'] = tools_path + "/as"
- if env['android_arch'] == 'x86':
- env['ARCH'] = 'arch-x86'
- else:
- env['ARCH'] = 'arch-arm'
-
sysroot = env["ANDROID_NDK_ROOT"] + "/platforms/" + env['ndk_platform'] + "/" + env['ARCH']
common_opts = ['-fno-integrated-as', '-gcc-toolchain', gcc_toolchain_path]
@@ -199,6 +205,11 @@ def configure(env):
else:
env.Append(CPPFLAGS=['-mfpu=vfpv3-d16'])
+ elif env["android_arch"] == "arm64v8":
+ target_opts = ['-target', 'aarch64-none-linux-android']
+ env.Append(CPPFLAGS=['-D__ARM_ARCH_8A__'])
+ env.Append(CPPFLAGS=['-mfix-cortex-a53-835769'])
+
env.Append(CPPFLAGS=target_opts)
env.Append(CPPFLAGS=common_opts)
@@ -213,7 +224,8 @@ def configure(env):
## Link flags
env['LINKFLAGS'] = ['-shared', '--sysroot=' + sysroot, '-Wl,--warn-shared-textrel']
- env.Append(LINKFLAGS=string.split('-Wl,--fix-cortex-a8'))
+ if env["android_arch"] == "armv7":
+ env.Append(LINKFLAGS=string.split('-Wl,--fix-cortex-a8'))
env.Append(LINKFLAGS=string.split('-Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now'))
env.Append(LINKFLAGS=string.split('-Wl,-soname,libgodot_android.so -Wl,--gc-sections'))
if mt_link:
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index a722cd1b8..3c52834d9 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -219,6 +219,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
bool use_32_fb;
bool immersive;
bool export_arm;
+ bool export_arm64;
bool export_x86;
String apk_expansion_salt;
String apk_expansion_pkey;
@@ -319,6 +320,8 @@ bool EditorExportPlatformAndroid::_set(const StringName& p_name, const Variant&
_signed=p_value;
else if (n=="architecture/arm")
export_arm=p_value;
+ else if (n=="architecture/arm64")
+ export_arm64=p_value;
else if (n=="architecture/x86")
export_x86=p_value;
else if (n=="screen/use_32_bits_view")
@@ -392,6 +395,8 @@ bool EditorExportPlatformAndroid::_get(const StringName& p_name,Variant &r_ret)
r_ret=_signed;
else if (n=="architecture/arm")
r_ret=export_arm;
+ else if (n=="architecture/arm64")
+ r_ret=export_arm64;
else if (n=="architecture/x86")
r_ret=export_x86;
else if (n=="screen/use_32_bits_view")
@@ -1164,6 +1169,10 @@ Error EditorExportPlatformAndroid::export_project(const String& p_path, bool p_d
skip=true;
}
+ if (file.match("lib/arm64*/libgodot_android.so") && !export_arm64) {
+ skip = true;
+ }
+
if (file.begins_with("META-INF") && _signed) {
skip=true;
}
@@ -1801,6 +1810,7 @@ EditorExportPlatformAndroid::EditorExportPlatformAndroid() {
immersive=true;
export_arm=true;
+ export_arm64=false;
export_x86=false;
@@ -3176,6 +3186,7 @@ public:
bool export_x86 = p_preset->get("architecture/x86");
bool export_arm = p_preset->get("architecture/arm");
+ bool export_arm64 = p_preset->get("architecture/arm64");
bool use_32_fb = p_preset->get("screen/use_32_bits_view");
bool immersive = p_preset->get("screen/immersive_mode");
@@ -3267,6 +3278,10 @@ public:
skip = true;
}
+ if (file.match("lib/arm64*/libgodot_android.so") && !export_arm64) {
+ skip = true;
+ }
+
if (file.begins_with("META-INF") && _signed) {
skip = true;
}
diff --git a/platform/android/java_class_wrapper.cpp b/platform/android/java_class_wrapper.cpp
index 56a27fa0e..52ff9cd56 100644
--- a/platform/android/java_class_wrapper.cpp
+++ b/platform/android/java_class_wrapper.cpp
@@ -190,7 +190,7 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
argv[i].i = *p_args[i];
} break;
case ARG_TYPE_LONG: {
- argv[i].j = *p_args[i];
+ argv[i].j = (int64_t)*p_args[i];
} break;
case ARG_TYPE_FLOAT: {
argv[i].f = *p_args[i];
@@ -350,7 +350,7 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
Array arr = *p_args[i];
jlongArray a = env->NewLongArray(arr.size());
for (int j = 0; j < arr.size(); j++) {
- jlong val = arr[j];
+ jlong val = (int64_t)arr[j];
env->SetLongArrayRegion(a, j, 1, &val);
}
argv[i].l = a;
@@ -460,9 +460,9 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
case ARG_TYPE_LONG: {
if (method->_static) {
- ret = env->CallStaticLongMethodA(_class, method->method, argv);
+ ret = (int64_t)env->CallStaticLongMethodA(_class, method->method, argv);
} else {
- ret = env->CallLongMethodA(p_instance->instance, method->method, argv);
+ ret = (int64_t)env->CallLongMethodA(p_instance->instance, method->method, argv);
}
} break;
@@ -680,7 +680,7 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
} break;
case ARG_TYPE_LONG | ARG_NUMBER_CLASS_BIT: {
- var = env->CallLongMethod(obj, JavaClassWrapper::singleton->Long_longValue);
+ var = (int64_t)env->CallLongMethod(obj, JavaClassWrapper::singleton->Long_longValue);
return true;
} break;
@@ -802,7 +802,7 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
jlong val;
env->GetLongArrayRegion((jlongArray)arr, 0, 1, &val);
- ret.push_back(val);
+ ret.push_back((int64_t)val);
}
var = ret;
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index c091c7d02..da14d5c28 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -805,7 +805,12 @@ void OS_Windows::process_key_events() {
k->set_pressed(ke.uMsg == WM_KEYDOWN);
- k->set_scancode(KeyMappingWindows::get_keysym(ke.wParam));
+ if ((ke.lParam & (1 << 24)) && (ke.wParam == VK_RETURN)) {
+ // Special case for Numpad Enter key
+ k->set_scancode(KEY_ENTER);
+ } else {
+ k->set_scancode(KeyMappingWindows::get_keysym(ke.wParam));
+ }
if (i + 1 < key_event_pos && key_event_buffer[i + 1].uMsg == WM_CHAR) {
k->set_unicode(key_event_buffer[i + 1].wParam);
diff --git a/scene/2d/sprite.cpp b/scene/2d/sprite.cpp
index b46901381..ad34dfd63 100644
--- a/scene/2d/sprite.cpp
+++ b/scene/2d/sprite.cpp
@@ -109,6 +109,7 @@ void Sprite::set_texture(const Ref<Texture> &p_texture) {
update();
emit_signal("texture_changed");
item_rect_changed();
+ _change_notify("texture");
}
void Sprite::set_normal_map(const Ref<Texture> &p_texture) {
diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp
index fe76b1646..57aa72b7d 100644
--- a/scene/gui/menu_button.cpp
+++ b/scene/gui/menu_button.cpp
@@ -55,7 +55,6 @@ void MenuButton::pressed() {
popup->set_size(Size2(size.width, 0));
popup->set_parent_rect(Rect2(Point2(gp - popup->get_global_position()), get_size()));
popup->popup();
- popup->call_deferred("grab_click_focus");
popup->set_invalidate_click_until_motion();
}
@@ -112,6 +111,7 @@ MenuButton::MenuButton() {
popup->hide();
add_child(popup);
popup->set_as_toplevel(true);
+ connect("button_up", popup, "call_deferred", make_binds("grab_click_focus"));
set_process_unhandled_key_input(true);
set_action_mode(ACTION_MODE_BUTTON_PRESS);
}
diff --git a/scene/gui/patch_9_rect.cpp b/scene/gui/patch_9_rect.cpp
index 16f2bb6b6..e577000f9 100644
--- a/scene/gui/patch_9_rect.cpp
+++ b/scene/gui/patch_9_rect.cpp
@@ -99,6 +99,7 @@ void NinePatchRect::set_texture(const Ref<Texture> &p_tex) {
*/
minimum_size_changed();
emit_signal("texture_changed");
+ _change_notify("texture");
}
Ref<Texture> NinePatchRect::get_texture() const {
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 8baca50d3..d604738da 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -49,6 +49,10 @@ static bool _is_symbol(CharType c) {
return c != '_' && ((c >= '!' && c <= '/') || (c >= ':' && c <= '@') || (c >= '[' && c <= '`') || (c >= '{' && c <= '~') || c == '\t' || c == ' ');
}
+static bool _is_whitespace(CharType c) {
+ return c == '\t' || c == ' ';
+}
+
static bool _is_char(CharType c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_';
@@ -2096,45 +2100,43 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
break;
#ifdef APPLE_STYLE_KEYS
- if (k->get_alt()) {
+ if (k->get_alt() && cursor.column > 1) {
#else
if (k->get_alt()) {
scancode_handled = false;
break;
- } else if (k->get_command()) {
+ } else if (k->get_command() && cursor.column > 1) {
#endif
int line = cursor.line;
int column = cursor.column;
- bool prev_char = false;
- bool only_whitespace = true;
-
- while (only_whitespace && line > 0) {
-
- while (column > 0) {
- CharType c = text[line][column - 1];
-
- if (c != '\t' && c != ' ') {
- only_whitespace = false;
- break;
- }
+ // check if we are removing a single whitespace, if so remove it and the next char type
+ // else we just remove the whitespace
+ bool only_whitespace = false;
+ if (_is_whitespace(text[line][column - 1]) && _is_whitespace(text[line][column - 2])) {
+ only_whitespace = true;
+ } else if (_is_whitespace(text[line][column - 1])) {
+ // remove the single whitespace
+ column--;
+ }
- column--;
- }
+ // check if its a text char
+ bool only_char = (_is_text_char(text[line][column - 1]) && !only_whitespace);
- if (only_whitespace) {
- line--;
- column = text[line].length();
- }
- }
+ // if its not whitespace or char then symbol.
+ bool only_symbols = !(only_whitespace || only_char);
while (column > 0) {
- bool ischar = _is_text_char(text[line][column - 1]);
+ bool is_whitespace = _is_whitespace(text[line][column - 1]);
+ bool is_text_char = _is_text_char(text[line][column - 1]);
- if (prev_char && !ischar)
+ if (only_whitespace && !is_whitespace) {
break;
-
- prev_char = ischar;
+ } else if (only_char && !is_text_char) {
+ break;
+ } else if (only_symbols && (is_whitespace || is_text_char)) {
+ break;
+ }
column--;
}
@@ -2356,52 +2358,50 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
int next_column;
#ifdef APPLE_STYLE_KEYS
- if (k->get_alt()) {
+ if (k->get_alt() && cursor.column < curline_len - 1) {
#else
if (k->get_alt()) {
scancode_handled = false;
break;
- } else if (k->get_command()) {
+ } else if (k->get_command() && cursor.column < curline_len - 1) {
#endif
- int last_line = text.size() - 1;
int line = cursor.line;
int column = cursor.column;
- bool prev_char = false;
- bool only_whitespace = true;
-
- while (only_whitespace && line < last_line) {
-
- while (column < text[line].length()) {
- CharType c = text[line][column];
-
- if (c != '\t' && c != ' ') {
- only_whitespace = false;
- break;
- }
-
- column++;
- }
-
- if (only_whitespace) {
- line++;
- column = 0;
- }
+ // check if we are removing a single whitespace, if so remove it and the next char type
+ // else we just remove the whitespace
+ bool only_whitespace = false;
+ if (_is_whitespace(text[line][column]) && _is_whitespace(text[line][column + 1])) {
+ only_whitespace = true;
+ } else if (_is_whitespace(text[line][column])) {
+ // remove the single whitespace
+ column++;
}
- while (column < text[line].length()) {
+ // check if its a text char
+ bool only_char = (_is_text_char(text[line][column]) && !only_whitespace);
- bool ischar = _is_text_char(text[line][column]);
+ // if its not whitespace or char then symbol.
+ bool only_symbols = !(only_whitespace || only_char);
- if (prev_char && !ischar)
+ while (column < curline_len) {
+ bool is_whitespace = _is_whitespace(text[line][column]);
+ bool is_text_char = _is_text_char(text[line][column]);
+
+ if (only_whitespace && !is_whitespace) {
break;
- prev_char = ischar;
+ } else if (only_char && !is_text_char) {
+ break;
+ } else if (only_symbols && (is_whitespace || is_text_char)) {
+ break;
+ }
column++;
}
next_line = line;
next_column = column;
+
} else {
next_column = cursor.column < curline_len ? (cursor.column + 1) : 0;
}
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index 1456ab51c..0b57841be 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -1605,7 +1605,6 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
int plus = 1;
while (i + plus < columns.size() && !p_item->cells[i + plus].editable && p_item->cells[i + plus].mode == TreeItem::CELL_MODE_STRING && p_item->cells[i + plus].text == "" && p_item->cells[i + plus].icon.is_null()) {
- plus++;
col_width += cache.hseparation;
col_width += get_column_width(i + plus);
plus++;
diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp
index e0a9de606..3666c1848 100644
--- a/scene/resources/style_box.cpp
+++ b/scene/resources/style_box.cpp
@@ -107,6 +107,7 @@ void StyleBoxTexture::set_texture(RES p_texture) {
region_rect = Rect2(Point2(), texture->get_size());
emit_signal("texture_changed");
emit_changed();
+ _change_notify("texture");
}
RES StyleBoxTexture::get_texture() const {
diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp
index 8b747e1b4..8478432a0 100644
--- a/scene/resources/surface_tool.cpp
+++ b/scene/resources/surface_tool.cpp
@@ -818,6 +818,7 @@ void SurfaceTool::clear() {
void SurfaceTool::_bind_methods() {
ClassDB::bind_method(D_METHOD("begin", "primitive"), &SurfaceTool::begin);
+
ClassDB::bind_method(D_METHOD("add_vertex", "vertex"), &SurfaceTool::add_vertex);
ClassDB::bind_method(D_METHOD("add_color", "color"), &SurfaceTool::add_color);
ClassDB::bind_method(D_METHOD("add_normal", "normal"), &SurfaceTool::add_normal);
@@ -827,15 +828,25 @@ void SurfaceTool::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_bones", "bones"), &SurfaceTool::add_bones);
ClassDB::bind_method(D_METHOD("add_weights", "weights"), &SurfaceTool::add_weights);
ClassDB::bind_method(D_METHOD("add_smooth_group", "smooth"), &SurfaceTool::add_smooth_group);
+
ClassDB::bind_method(D_METHOD("add_triangle_fan", "vertexes", "uvs", "colors", "uv2s", "normals", "tangents"), &SurfaceTool::add_triangle_fan, DEFVAL(Vector<Vector2>()), DEFVAL(Vector<Color>()), DEFVAL(Vector<Vector2>()), DEFVAL(Vector<Vector3>()), DEFVAL(Vector<Plane>()));
- ClassDB::bind_method(D_METHOD("set_material", "material:Material"), &SurfaceTool::set_material);
+
+ ClassDB::bind_method(D_METHOD("add_index", "index"), &SurfaceTool::add_index);
+
ClassDB::bind_method(D_METHOD("index"), &SurfaceTool::index);
ClassDB::bind_method(D_METHOD("deindex"), &SurfaceTool::deindex);
- ///ClassDB::bind_method(D_METHOD("generate_flat_normals"),&SurfaceTool::generate_flat_normals);
ClassDB::bind_method(D_METHOD("generate_normals"), &SurfaceTool::generate_normals);
- ClassDB::bind_method(D_METHOD("add_index", "index"), &SurfaceTool::add_index);
- ClassDB::bind_method(D_METHOD("commit:Mesh", "existing:Mesh"), &SurfaceTool::commit, DEFVAL(Variant()));
+ ClassDB::bind_method(D_METHOD("generate_tangents"), &SurfaceTool::generate_tangents);
+
+ ClassDB::bind_method(D_METHOD("add_to_format", "flags"), &SurfaceTool::add_to_format);
+
+ ClassDB::bind_method(D_METHOD("set_material", "material:Material"), &SurfaceTool::set_material);
+
ClassDB::bind_method(D_METHOD("clear"), &SurfaceTool::clear);
+
+ ClassDB::bind_method(D_METHOD("create_from", "existing:Mesh", "surface"), &SurfaceTool::create_from);
+ ClassDB::bind_method(D_METHOD("append_from", "existing:Mesh", "surface", "transform"), &SurfaceTool::append_from);
+ ClassDB::bind_method(D_METHOD("commit:Mesh", "existing:Mesh"), &SurfaceTool::commit, DEFVAL(Variant()));
}
SurfaceTool::SurfaceTool() {
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 5cd75b5a6..fe7cd0097 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -830,7 +830,7 @@ void AtlasTexture::set_atlas(const Ref<Texture> &p_atlas) {
return;
atlas = p_atlas;
emit_changed();
- emit_signal("atlas_changed");
+ _change_notify("atlas");
}
Ref<Texture> AtlasTexture::get_atlas() const {
@@ -839,8 +839,11 @@ Ref<Texture> AtlasTexture::get_atlas() const {
void AtlasTexture::set_region(const Rect2 &p_region) {
+ if (region == p_region)
+ return;
region = p_region;
emit_changed();
+ _change_notify("region");
}
Rect2 AtlasTexture::get_region() const {
@@ -850,8 +853,11 @@ Rect2 AtlasTexture::get_region() const {
void AtlasTexture::set_margin(const Rect2 &p_margin) {
+ if (margin == p_margin)
+ return;
margin = p_margin;
emit_changed();
+ _change_notify("margin");
}
Rect2 AtlasTexture::get_margin() const {
@@ -870,8 +876,6 @@ void AtlasTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_margin", "margin"), &AtlasTexture::set_margin);
ClassDB::bind_method(D_METHOD("get_margin"), &AtlasTexture::get_margin);
- ADD_SIGNAL(MethodInfo("atlas_changed"));
-
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "atlas", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_atlas", "get_atlas");
ADD_PROPERTY(PropertyInfo(Variant::RECT2, "region"), "set_region", "get_region");
ADD_PROPERTY(PropertyInfo(Variant::RECT2, "margin"), "set_margin", "get_margin");
diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp
index 5303aea6d..0d2550e53 100644
--- a/servers/audio_server.cpp
+++ b/servers/audio_server.cpp
@@ -66,7 +66,8 @@ void AudioDriver::audio_server_process(int p_frames, int32_t *p_buffer, bool p_u
void AudioDriver::update_mix_time(int p_frames) {
_mix_amount += p_frames;
- _last_mix_time = OS::get_singleton()->get_ticks_usec();
+ if (OS::get_singleton())
+ _last_mix_time = OS::get_singleton()->get_ticks_usec();
}
double AudioDriver::get_mix_time() const {
diff --git a/servers/physics/area_sw.h b/servers/physics/area_sw.h
index 06e58e3d5..3dae1db13 100644
--- a/servers/physics/area_sw.h
+++ b/servers/physics/area_sw.h
@@ -154,6 +154,7 @@ public:
_FORCE_INLINE_ void add_constraint(ConstraintSW *p_constraint) { constraints.insert(p_constraint); }
_FORCE_INLINE_ void remove_constraint(ConstraintSW *p_constraint) { constraints.erase(p_constraint); }
_FORCE_INLINE_ const Set<ConstraintSW *> &get_constraints() const { return constraints; }
+ _FORCE_INLINE_ void clear_constraints() { constraints.clear(); }
void set_monitorable(bool p_monitorable);
_FORCE_INLINE_ bool is_monitorable() const { return monitorable; }
diff --git a/servers/physics/body_sw.cpp b/servers/physics/body_sw.cpp
index 1f32c059a..e065fae2b 100644
--- a/servers/physics/body_sw.cpp
+++ b/servers/physics/body_sw.cpp
@@ -757,7 +757,8 @@ BodySW::BodySW()
contact_count = 0;
gravity_scale = 1.0;
-
+ linear_damp = -1;
+ angular_damp = -1;
area_angular_damp = 0;
area_linear_damp = 0;
diff --git a/servers/physics/body_sw.h b/servers/physics/body_sw.h
index c3e051c2d..512b86857 100644
--- a/servers/physics/body_sw.h
+++ b/servers/physics/body_sw.h
@@ -194,6 +194,7 @@ public:
_FORCE_INLINE_ void add_constraint(ConstraintSW *p_constraint, int p_pos) { constraint_map[p_constraint] = p_pos; }
_FORCE_INLINE_ void remove_constraint(ConstraintSW *p_constraint) { constraint_map.erase(p_constraint); }
const Map<ConstraintSW *, int> &get_constraint_map() const { return constraint_map; }
+ _FORCE_INLINE_ void clear_constraint_map() { constraint_map.clear(); }
_FORCE_INLINE_ void set_omit_force_integration(bool p_omit_force_integration) { omit_force_integration = p_omit_force_integration; }
_FORCE_INLINE_ bool get_omit_force_integration() const { return omit_force_integration; }
diff --git a/servers/physics/physics_server_sw.cpp b/servers/physics/physics_server_sw.cpp
index 101bd4b18..833c77216 100644
--- a/servers/physics/physics_server_sw.cpp
+++ b/servers/physics/physics_server_sw.cpp
@@ -222,12 +222,24 @@ void PhysicsServerSW::area_set_space(RID p_area, RID p_space) {
AreaSW *area = area_owner.get(p_area);
ERR_FAIL_COND(!area);
+
SpaceSW *space = NULL;
if (p_space.is_valid()) {
space = space_owner.get(p_space);
ERR_FAIL_COND(!space);
}
+ if (area->get_space() == space)
+ return; //pointless
+
+ for (Set<ConstraintSW *>::Element *E = area->get_constraints().front(); E; E = E->next()) {
+ RID self = E->get()->get_self();
+ if (!self.is_valid())
+ continue;
+ free(self);
+ }
+ area->clear_constraints();
+
area->set_space(space);
};
@@ -471,15 +483,23 @@ void PhysicsServerSW::body_set_space(RID p_body, RID p_space) {
BodySW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
- SpaceSW *space = NULL;
+ SpaceSW *space = NULL;
if (p_space.is_valid()) {
space = space_owner.get(p_space);
ERR_FAIL_COND(!space);
}
if (body->get_space() == space)
- return; //pointles
+ return; //pointless
+
+ while (body->get_constraint_map().size()) {
+ RID self = body->get_constraint_map().front()->key()->get_self();
+ if (!self.is_valid())
+ continue;
+ free(self);
+ }
+ body->clear_constraint_map();
body->set_space(space);
};
@@ -1329,12 +1349,6 @@ void PhysicsServerSW::free(RID p_rid) {
body->remove_shape(0);
}
- while (body->get_constraint_map().size()) {
- RID self = body->get_constraint_map().front()->key()->get_self();
- ERR_FAIL_COND(!self.is_valid());
- free(self);
- }
-
body_owner.free(p_rid);
memdelete(body);
diff --git a/servers/physics/space_sw.cpp b/servers/physics/space_sw.cpp
index 5679fc8f6..094cfa465 100644
--- a/servers/physics/space_sw.cpp
+++ b/servers/physics/space_sw.cpp
@@ -34,12 +34,12 @@
_FORCE_INLINE_ static bool _match_object_type_query(CollisionObjectSW *p_object, uint32_t p_collision_layer, uint32_t p_type_mask) {
- if (p_object->get_type() == CollisionObjectSW::TYPE_AREA)
- return p_type_mask & PhysicsDirectSpaceState::TYPE_MASK_AREA;
-
if ((p_object->get_collision_layer() & p_collision_layer) == 0)
return false;
+ if (p_object->get_type() == CollisionObjectSW::TYPE_AREA)
+ return p_type_mask & PhysicsDirectSpaceState::TYPE_MASK_AREA;
+
BodySW *body = static_cast<BodySW *>(p_object);
return (1 << body->get_mode()) & p_type_mask;
diff --git a/servers/physics_2d/area_2d_sw.h b/servers/physics_2d/area_2d_sw.h
index 68b3c61e4..6d74a4b0f 100644
--- a/servers/physics_2d/area_2d_sw.h
+++ b/servers/physics_2d/area_2d_sw.h
@@ -153,6 +153,7 @@ public:
_FORCE_INLINE_ void add_constraint(Constraint2DSW *p_constraint) { constraints.insert(p_constraint); }
_FORCE_INLINE_ void remove_constraint(Constraint2DSW *p_constraint) { constraints.erase(p_constraint); }
_FORCE_INLINE_ const Set<Constraint2DSW *> &get_constraints() const { return constraints; }
+ _FORCE_INLINE_ void clear_constraints() { constraints.clear(); }
void set_monitorable(bool p_monitorable);
_FORCE_INLINE_ bool is_monitorable() const { return monitorable; }
diff --git a/servers/physics_2d/body_2d_sw.h b/servers/physics_2d/body_2d_sw.h
index 9e5deef3f..412f2f51c 100644
--- a/servers/physics_2d/body_2d_sw.h
+++ b/servers/physics_2d/body_2d_sw.h
@@ -181,6 +181,7 @@ public:
_FORCE_INLINE_ void add_constraint(Constraint2DSW *p_constraint, int p_pos) { constraint_map[p_constraint] = p_pos; }
_FORCE_INLINE_ void remove_constraint(Constraint2DSW *p_constraint) { constraint_map.erase(p_constraint); }
const Map<Constraint2DSW *, int> &get_constraint_map() const { return constraint_map; }
+ _FORCE_INLINE_ void clear_constraint_map() { constraint_map.clear(); }
_FORCE_INLINE_ void set_omit_force_integration(bool p_omit_force_integration) { omit_force_integration = p_omit_force_integration; }
_FORCE_INLINE_ bool get_omit_force_integration() const { return omit_force_integration; }
diff --git a/servers/physics_2d/broad_phase_2d_hash_grid.cpp b/servers/physics_2d/broad_phase_2d_hash_grid.cpp
index 5b6c7e2f3..0330bfa9f 100644
--- a/servers/physics_2d/broad_phase_2d_hash_grid.cpp
+++ b/servers/physics_2d/broad_phase_2d_hash_grid.cpp
@@ -203,9 +203,11 @@ void BroadPhase2DHashGrid::_exit_grid(Element *p_elem, const Rect2 &p_rect, bool
if (sz.width * sz.height > large_object_min_surface) {
//unpair all elements, instead of checking all, just check what is already paired, so we at least save from checking static vs static
- for (Map<Element *, PairData *>::Element *E = p_elem->paired.front(); E; E = E->next()) {
-
+ Map<Element *, PairData *>::Element *E = p_elem->paired.front();
+ while (E) {
+ Map<Element *, PairData *>::Element *next = E->next();
_unpair_attempt(p_elem, E->key());
+ E = next;
}
if (large_elements[p_elem].dec() == 0) {
diff --git a/servers/physics_2d/physics_2d_server_sw.cpp b/servers/physics_2d/physics_2d_server_sw.cpp
index c20d0d14a..add376bfb 100644
--- a/servers/physics_2d/physics_2d_server_sw.cpp
+++ b/servers/physics_2d/physics_2d_server_sw.cpp
@@ -286,12 +286,24 @@ void Physics2DServerSW::area_set_space(RID p_area, RID p_space) {
Area2DSW *area = area_owner.get(p_area);
ERR_FAIL_COND(!area);
+
Space2DSW *space = NULL;
if (p_space.is_valid()) {
space = space_owner.get(p_space);
ERR_FAIL_COND(!space);
}
+ if (area->get_space() == space)
+ return; //pointless
+
+ for (Set<Constraint2DSW *>::Element *E = area->get_constraints().front(); E; E = E->next()) {
+ RID self = E->get()->get_self();
+ if (!self.is_valid())
+ continue;
+ free(self);
+ }
+ area->clear_constraints();
+
area->set_space(space);
};
@@ -533,6 +545,17 @@ void Physics2DServerSW::body_set_space(RID p_body, RID p_space) {
ERR_FAIL_COND(!space);
}
+ if (body->get_space() == space)
+ return; //pointless
+
+ while (body->get_constraint_map().size()) {
+ RID self = body->get_constraint_map().front()->key()->get_self();
+ if (!self.is_valid())
+ continue;
+ free(self);
+ }
+ body->clear_constraint_map();
+
body->set_space(space);
};
@@ -1073,19 +1096,13 @@ void Physics2DServerSW::free(RID p_rid) {
_clear_query(body->get_direct_state_query());
*/
- body->set_space(NULL);
+ body_set_space(p_rid, RID());
while (body->get_shape_count()) {
body->remove_shape(0);
}
- while (body->get_constraint_map().size()) {
- RID self = body->get_constraint_map().front()->key()->get_self();
- ERR_FAIL_COND(!self.is_valid());
- free(self);
- }
-
body_owner.free(p_rid);
memdelete(body);