summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/error_macros.h20
-rw-r--r--core/io/resource_importer.cpp5
-rw-r--r--core/io/resource_importer.h2
-rw-r--r--core/io/resource_loader.cpp25
-rw-r--r--core/io/resource_loader.h2
-rw-r--r--core/math/geometry.cpp35
-rw-r--r--core/math/geometry.h2
-rw-r--r--core/math/quick_hull.cpp4
-rw-r--r--core/math/quick_hull.h2
-rw-r--r--core/object.cpp25
-rw-r--r--core/os/file_access.cpp17
-rw-r--r--core/os/file_access.h1
-rw-r--r--core/os/input.cpp1
-rw-r--r--core/os/input.h3
-rw-r--r--core/os/input_event.cpp40
-rw-r--r--core/os/input_event.h3
-rw-r--r--core/os/os.h1
-rw-r--r--core/script_debugger_remote.cpp1
-rw-r--r--core/typedefs.h15
-rw-r--r--core/undo_redo.cpp11
-rw-r--r--core/undo_redo.h3
-rw-r--r--core/variant_op.cpp70
22 files changed, 266 insertions, 22 deletions
diff --git a/core/error_macros.h b/core/error_macros.h
index 3aa8ed4596..ca5ccd24cf 100644
--- a/core/error_macros.h
+++ b/core/error_macros.h
@@ -310,6 +310,16 @@ extern bool _err_error_exists;
_err_error_exists = false; \
}
+#define ERR_PRINT_ONCE(m_string) \
+ { \
+ static bool first_print = true; \
+ if (first_print) { \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string); \
+ _err_error_exists = false; \
+ first_print = false; \
+ } \
+ }
+
/** Print a warning string.
*/
@@ -325,6 +335,16 @@ extern bool _err_error_exists;
_err_error_exists = false; \
}
+#define WARN_PRINT_ONCE(m_string) \
+ { \
+ static bool first_print = true; \
+ if (first_print) { \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_string, ERR_HANDLER_WARNING); \
+ _err_error_exists = false; \
+ first_print = false; \
+ } \
+ }
+
#define WARN_DEPRECATED \
{ \
static volatile bool warning_shown = false; \
diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp
index 69907a710a..b5fa412576 100644
--- a/core/io/resource_importer.cpp
+++ b/core/io/resource_importer.cpp
@@ -183,6 +183,11 @@ void ResourceFormatImporter::get_recognized_extensions_for_type(const String &p_
}
}
+bool ResourceFormatImporter::exists(const String &p_path) const {
+
+ return FileAccess::exists(p_path + ".import");
+}
+
bool ResourceFormatImporter::recognize_path(const String &p_path, const String &p_for_type) const {
return FileAccess::exists(p_path + ".import");
diff --git a/core/io/resource_importer.h b/core/io/resource_importer.h
index 1d27d4dec3..1c146c33d7 100644
--- a/core/io/resource_importer.h
+++ b/core/io/resource_importer.h
@@ -68,6 +68,8 @@ public:
virtual Variant get_resource_metadata(const String &p_path) const;
virtual bool is_import_valid(const String &p_path) const;
virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false);
+ virtual bool is_imported(const String &p_path) const { return recognize_path(p_path); }
+ virtual bool exists(const String &p_path) const;
virtual bool can_be_imported(const String &p_path) const;
virtual int get_import_order(const String &p_path) const;
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index 98309048bb..c917b9ba28 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -633,6 +633,31 @@ bool ResourceLoader::is_import_valid(const String &p_path) {
return false; //not found
}
+bool ResourceLoader::is_imported(const String &p_path) {
+
+ String path = _path_remap(p_path);
+
+ String local_path;
+ if (path.is_rel_path())
+ local_path = "res://" + path;
+ else
+ local_path = ProjectSettings::get_singleton()->localize_path(path);
+
+ for (int i = 0; i < loader_count; i++) {
+
+ if (!loader[i]->recognize_path(local_path))
+ continue;
+ /*
+ if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
+ continue;
+ */
+
+ return loader[i]->is_imported(p_path);
+ }
+
+ return false; //not found
+}
+
void ResourceLoader::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) {
String path = _path_remap(p_path);
diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h
index 70eb1a3de0..ca7610a0d2 100644
--- a/core/io/resource_loader.h
+++ b/core/io/resource_loader.h
@@ -79,6 +79,7 @@ public:
virtual void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false);
virtual Error rename_dependencies(const String &p_path, const Map<String, String> &p_map);
virtual bool is_import_valid(const String &p_path) const { return true; }
+ virtual bool is_imported(const String &p_path) const { return false; }
virtual int get_import_order(const String &p_path) const { return 0; }
virtual ~ResourceFormatLoader() {}
@@ -154,6 +155,7 @@ public:
static void get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types = false);
static Error rename_dependencies(const String &p_path, const Map<String, String> &p_map);
static bool is_import_valid(const String &p_path);
+ static bool is_imported(const String &p_path);
static int get_import_order(const String &p_path);
static void set_timestamp_on_load(bool p_timestamp) { timestamp_on_load = p_timestamp; }
diff --git a/core/math/geometry.cpp b/core/math/geometry.cpp
index 12c88f43b3..194a6f6352 100644
--- a/core/math/geometry.cpp
+++ b/core/math/geometry.cpp
@@ -31,6 +31,7 @@
#include "geometry.h"
#include "core/print_string.h"
+#include "thirdparty/misc/triangulator.h"
/* this implementation is very inefficient, commenting unless bugs happen. See the other one.
bool Geometry::is_point_in_polygon(const Vector2 &p_point, const Vector<Vector2> &p_polygon) {
@@ -737,6 +738,40 @@ PoolVector<Face3> Geometry::wrap_geometry(PoolVector<Face3> p_array, real_t *p_e
return wrapped_faces;
}
+Vector<Vector<Vector2> > Geometry::decompose_polygon_in_convex(Vector<Point2> polygon) {
+ Vector<Vector<Vector2> > decomp;
+ List<TriangulatorPoly> in_poly, out_poly;
+
+ TriangulatorPoly inp;
+ inp.Init(polygon.size());
+ for (int i = 0; i < polygon.size(); i++) {
+ inp.GetPoint(i) = polygon[i];
+ }
+ inp.SetOrientation(TRIANGULATOR_CCW);
+ in_poly.push_back(inp);
+ TriangulatorPartition tpart;
+ if (tpart.ConvexPartition_HM(&in_poly, &out_poly) == 0) { //failed!
+ ERR_PRINT("Convex decomposing failed!");
+ return decomp;
+ }
+
+ decomp.resize(out_poly.size());
+ int idx = 0;
+ for (List<TriangulatorPoly>::Element *I = out_poly.front(); I; I = I->next()) {
+ TriangulatorPoly &tp = I->get();
+
+ decomp.write[idx].resize(tp.GetNumPoints());
+
+ for (int i = 0; i < tp.GetNumPoints(); i++) {
+ decomp.write[idx].write[i] = tp.GetPoint(i);
+ }
+
+ idx++;
+ }
+
+ return decomp;
+}
+
Geometry::MeshData Geometry::build_convex_mesh(const PoolVector<Plane> &p_planes) {
MeshData mesh;
diff --git a/core/math/geometry.h b/core/math/geometry.h
index f927a63ed5..4b478b6b16 100644
--- a/core/math/geometry.h
+++ b/core/math/geometry.h
@@ -950,6 +950,8 @@ public:
return H;
}
+ static Vector<Vector<Vector2> > decompose_polygon_in_convex(Vector<Point2> polygon);
+
static MeshData build_convex_mesh(const PoolVector<Plane> &p_planes);
static PoolVector<Plane> build_sphere_planes(real_t p_radius, int p_lats, int p_lons, Vector3::Axis p_axis = Vector3::AXIS_Z);
static PoolVector<Plane> build_box_planes(const Vector3 &p_extents);
diff --git a/core/math/quick_hull.cpp b/core/math/quick_hull.cpp
index bc2b4e6fe0..fc2eb1454d 100644
--- a/core/math/quick_hull.cpp
+++ b/core/math/quick_hull.cpp
@@ -36,8 +36,6 @@ uint32_t QuickHull::debug_stop_after = 0xFFFFFFFF;
Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_mesh) {
- static const real_t over_tolerance = 0.0001;
-
/* CREATE AABB VOLUME */
AABB aabb;
@@ -180,6 +178,8 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
faces.push_back(f);
}
+ real_t over_tolerance = 3 * UNIT_EPSILON * (aabb.size.x + aabb.size.y + aabb.size.z);
+
/* COMPUTE AVAILABLE VERTICES */
for (int i = 0; i < p_points.size(); i++) {
diff --git a/core/math/quick_hull.h b/core/math/quick_hull.h
index 2e659cab6e..a445a47cbe 100644
--- a/core/math/quick_hull.h
+++ b/core/math/quick_hull.h
@@ -64,7 +64,7 @@ public:
struct Face {
Plane plane;
- int vertices[3];
+ uint32_t vertices[3];
Vector<int> points_over;
bool operator<(const Face &p_face) const {
diff --git a/core/object.cpp b/core/object.cpp
index c46ecc5193..8b693f039c 100644
--- a/core/object.cpp
+++ b/core/object.cpp
@@ -832,23 +832,22 @@ void Object::setvar(const Variant &p_key, const Variant &p_value, bool *r_valid)
}
Variant Object::callv(const StringName &p_method, const Array &p_args) {
+ const Variant **argptrs = NULL;
- if (p_args.size() == 0) {
- return call(p_method);
- }
-
- Vector<Variant> args;
- args.resize(p_args.size());
- Vector<const Variant *> argptrs;
- argptrs.resize(p_args.size());
-
- for (int i = 0; i < p_args.size(); i++) {
- args.write[i] = p_args[i];
- argptrs.write[i] = &args[i];
+ if (p_args.size() > 0) {
+ argptrs = (const Variant **)alloca(sizeof(Variant *) * p_args.size());
+ for (int i = 0; i < p_args.size(); i++) {
+ argptrs[i] = &p_args[i];
+ }
}
Variant::CallError ce;
- return call(p_method, (const Variant **)argptrs.ptr(), p_args.size(), ce);
+ Variant ret = call(p_method, argptrs, p_args.size(), ce);
+ if (ce.error != Variant::CallError::CALL_OK) {
+ ERR_EXPLAIN("Error calling method from 'callv': " + Variant::get_call_error_text(this, p_method, argptrs, p_args.size(), ce));
+ ERR_FAIL_V(Variant());
+ }
+ return ret;
}
Variant Object::call(const StringName &p_name, VARIANT_ARG_DECLARE) {
diff --git a/core/os/file_access.cpp b/core/os/file_access.cpp
index d1f8236898..39d9f45bd7 100644
--- a/core/os/file_access.cpp
+++ b/core/os/file_access.cpp
@@ -409,6 +409,23 @@ int FileAccess::get_buffer(uint8_t *p_dst, int p_length) const {
return i;
}
+String FileAccess::get_as_utf8_string() const {
+ PoolVector<uint8_t> sourcef;
+ int len = get_len();
+ sourcef.resize(len + 1);
+
+ PoolVector<uint8_t>::Write w = sourcef.write();
+ int r = get_buffer(w.ptr(), len);
+ ERR_FAIL_COND_V(r != len, String());
+ w[len] = 0;
+
+ String s;
+ if (s.parse_utf8((const char *)w.ptr())) {
+ return String();
+ }
+ return s;
+}
+
void FileAccess::store_16(uint16_t p_dest) {
uint8_t a, b;
diff --git a/core/os/file_access.h b/core/os/file_access.h
index 7bfbf6e7f0..c65b75369c 100644
--- a/core/os/file_access.h
+++ b/core/os/file_access.h
@@ -113,6 +113,7 @@ public:
virtual String get_line() const;
virtual String get_token() const;
virtual Vector<String> get_csv_line(const String &p_delim = ",") const;
+ virtual String get_as_utf8_string() const;
/**< use this for files WRITTEN in _big_ endian machines (ie, amiga/mac)
* It's not about the current CPU type but file formats.
diff --git a/core/os/input.cpp b/core/os/input.cpp
index cf11ba3c6d..caa9fb1493 100644
--- a/core/os/input.cpp
+++ b/core/os/input.cpp
@@ -91,6 +91,7 @@ void Input::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_default_cursor_shape", "shape"), &Input::set_default_cursor_shape, DEFVAL(CURSOR_ARROW));
ClassDB::bind_method(D_METHOD("set_custom_mouse_cursor", "image", "shape", "hotspot"), &Input::set_custom_mouse_cursor, DEFVAL(CURSOR_ARROW), DEFVAL(Vector2()));
ClassDB::bind_method(D_METHOD("parse_input_event", "event"), &Input::parse_input_event);
+ ClassDB::bind_method(D_METHOD("set_use_accumulated_input", "enable"), &Input::set_use_accumulated_input);
BIND_ENUM_CONSTANT(MOUSE_MODE_VISIBLE);
BIND_ENUM_CONSTANT(MOUSE_MODE_HIDDEN);
diff --git a/core/os/input.h b/core/os/input.h
index b354acd961..c8b80b28d0 100644
--- a/core/os/input.h
+++ b/core/os/input.h
@@ -132,6 +132,9 @@ public:
virtual int get_joy_axis_index_from_string(String p_axis) = 0;
virtual void parse_input_event(const Ref<InputEvent> &p_event) = 0;
+ virtual void accumulate_input_event(const Ref<InputEvent> &p_event) = 0;
+ virtual void flush_accumulated_events() = 0;
+ virtual void set_use_accumulated_input(bool p_enable) = 0;
Input();
};
diff --git a/core/os/input_event.cpp b/core/os/input_event.cpp
index 24ec8a1963..40308f4f7d 100644
--- a/core/os/input_event.cpp
+++ b/core/os/input_event.cpp
@@ -122,6 +122,8 @@ void InputEvent::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_action_type"), &InputEvent::is_action_type);
+ ClassDB::bind_method(D_METHOD("accumulate", "with_event"), &InputEvent::accumulate);
+
ClassDB::bind_method(D_METHOD("xformed_by", "xform", "local_ofs"), &InputEvent::xformed_by, DEFVAL(Vector2()));
ADD_PROPERTY(PropertyInfo(Variant::INT, "device"), "set_device", "get_device");
@@ -620,6 +622,44 @@ String InputEventMouseMotion::as_text() const {
return "InputEventMouseMotion : button_mask=" + button_mask_string + ", position=(" + String(get_position()) + "), relative=(" + String(get_relative()) + "), speed=(" + String(get_speed()) + ")";
}
+bool InputEventMouseMotion::accumulate(const Ref<InputEvent> &p_event) {
+
+ Ref<InputEventMouseMotion> motion = p_event;
+ if (motion.is_null())
+ return false;
+
+ if (is_pressed() != motion->is_pressed()) {
+ return false;
+ }
+
+ if (get_button_mask() != motion->get_button_mask()) {
+ return false;
+ }
+
+ if (get_shift() != motion->get_shift()) {
+ return false;
+ }
+
+ if (get_control() != motion->get_control()) {
+ return false;
+ }
+
+ if (get_alt() != motion->get_alt()) {
+ return false;
+ }
+
+ if (get_metakey() != motion->get_metakey()) {
+ return false;
+ }
+
+ set_position(motion->get_position());
+ set_global_position(motion->get_global_position());
+ set_speed(motion->get_speed());
+ relative += motion->get_relative();
+
+ return true;
+}
+
void InputEventMouseMotion::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_relative", "relative"), &InputEventMouseMotion::set_relative);
diff --git a/core/os/input_event.h b/core/os/input_event.h
index a6a7012298..47f9293a7f 100644
--- a/core/os/input_event.h
+++ b/core/os/input_event.h
@@ -186,6 +186,7 @@ public:
virtual bool shortcut_match(const Ref<InputEvent> &p_event) const;
virtual bool is_action_type() const;
+ virtual bool accumulate(const Ref<InputEvent> &p_event) { return false; }
InputEvent();
};
@@ -351,6 +352,8 @@ public:
virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const;
virtual String as_text() const;
+ virtual bool accumulate(const Ref<InputEvent> &p_event);
+
InputEventMouseMotion();
};
diff --git a/core/os/os.h b/core/os/os.h
index d6541034fd..ebfe7d20dc 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -518,6 +518,7 @@ public:
bool is_restart_on_exit_set() const;
List<String> get_restart_on_exit_arguments() const;
+ virtual void process_and_drop_events() {}
OS();
virtual ~OS();
};
diff --git a/core/script_debugger_remote.cpp b/core/script_debugger_remote.cpp
index 3ed25f118d..e7ff7a3aef 100644
--- a/core/script_debugger_remote.cpp
+++ b/core/script_debugger_remote.cpp
@@ -311,6 +311,7 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script, bool p_can_continue)
} else {
OS::get_singleton()->delay_usec(10000);
+ OS::get_singleton()->process_and_drop_events();
}
}
diff --git a/core/typedefs.h b/core/typedefs.h
index 966360d4f2..03514466c0 100644
--- a/core/typedefs.h
+++ b/core/typedefs.h
@@ -250,21 +250,34 @@ static inline int get_shift_from_power_of_2(unsigned int p_pixel) {
}
/** Swap 16 bits value for endianness */
+#if defined(__GNUC__) || _llvm_has_builtin(__builtin_bswap16)
+#define BSWAP16(x) __builtin_bswap16(x)
+#else
static inline uint16_t BSWAP16(uint16_t x) {
return (x >> 8) | (x << 8);
}
+#endif
+
/** Swap 32 bits value for endianness */
+#if defined(__GNUC__) || _llvm_has_builtin(__builtin_bswap32)
+#define BSWAP32(x) __builtin_bswap32(x)
+#else
static inline uint32_t BSWAP32(uint32_t x) {
return ((x << 24) | ((x << 8) & 0x00FF0000) | ((x >> 8) & 0x0000FF00) | (x >> 24));
}
-/** Swap 64 bits value for endianness */
+#endif
+/** Swap 64 bits value for endianness */
+#if defined(__GNUC__) || _llvm_has_builtin(__builtin_bswap64)
+#define BSWAP64(x) __builtin_bswap64(x)
+#else
static inline uint64_t BSWAP64(uint64_t x) {
x = (x & 0x00000000FFFFFFFF) << 32 | (x & 0xFFFFFFFF00000000) >> 32;
x = (x & 0x0000FFFF0000FFFF) << 16 | (x & 0xFFFF0000FFFF0000) >> 16;
x = (x & 0x00FF00FF00FF00FF) << 8 | (x & 0xFF00FF00FF00FF00) >> 8;
return x;
}
+#endif
/** When compiling with RTTI, we can add an "extra"
* layer of safeness in many operations, so dynamic_cast
diff --git a/core/undo_redo.cpp b/core/undo_redo.cpp
index 00894b41d8..e13164d50f 100644
--- a/core/undo_redo.cpp
+++ b/core/undo_redo.cpp
@@ -239,6 +239,10 @@ void UndoRedo::_pop_history_tail() {
}
}
+bool UndoRedo::is_commiting_action() const {
+ return commiting > 0;
+}
+
void UndoRedo::commit_action() {
ERR_FAIL_COND(action_level <= 0);
@@ -246,8 +250,9 @@ void UndoRedo::commit_action() {
if (action_level > 0)
return; //still nested
+ commiting++;
redo(); // perform action
-
+ commiting--;
if (callback && actions.size() > 0) {
callback(callback_ud, actions[actions.size() - 1].name);
}
@@ -321,6 +326,7 @@ bool UndoRedo::redo() {
if ((current_action + 1) >= actions.size())
return false; //nothing to redo
+
current_action++;
_process_operation_list(actions.write[current_action].do_ops.front());
@@ -337,7 +343,6 @@ bool UndoRedo::undo() {
_process_operation_list(actions.write[current_action].undo_ops.front());
current_action--;
version--;
-
return true;
}
@@ -386,6 +391,7 @@ void UndoRedo::set_property_notify_callback(PropertyNotifyCallback p_property_ca
UndoRedo::UndoRedo() {
+ commiting = 0;
version = 1;
action_level = 0;
current_action = -1;
@@ -484,6 +490,7 @@ void UndoRedo::_bind_methods() {
ClassDB::bind_method(D_METHOD("create_action", "name", "merge_mode"), &UndoRedo::create_action, DEFVAL(MERGE_DISABLE));
ClassDB::bind_method(D_METHOD("commit_action"), &UndoRedo::commit_action);
+ ClassDB::bind_method(D_METHOD("is_commiting_action"), &UndoRedo::is_commiting_action);
//ClassDB::bind_method(D_METHOD("add_do_method","p_object", "p_method", "VARIANT_ARG_LIST"),&UndoRedo::add_do_method);
//ClassDB::bind_method(D_METHOD("add_undo_method","p_object", "p_method", "VARIANT_ARG_LIST"),&UndoRedo::add_undo_method);
diff --git a/core/undo_redo.h b/core/undo_redo.h
index 4ee64dbfcf..b626149ce6 100644
--- a/core/undo_redo.h
+++ b/core/undo_redo.h
@@ -94,6 +94,8 @@ private:
MethodNotifyCallback method_callback;
PropertyNotifyCallback property_callback;
+ int commiting;
+
protected:
static void _bind_methods();
@@ -107,6 +109,7 @@ public:
void add_do_reference(Object *p_object);
void add_undo_reference(Object *p_object);
+ bool is_commiting_action() const;
void commit_action();
bool redo();
diff --git a/core/variant_op.cpp b/core/variant_op.cpp
index 26851e4c23..b40b6ce4a6 100644
--- a/core/variant_op.cpp
+++ b/core/variant_op.cpp
@@ -3656,11 +3656,55 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
}
return;
case POOL_INT_ARRAY: {
- r_dst = a;
+ const PoolVector<int> *arr_a = reinterpret_cast<const PoolVector<int> *>(a._data._mem);
+ const PoolVector<int> *arr_b = reinterpret_cast<const PoolVector<int> *>(b._data._mem);
+ int sz = arr_a->size();
+ if (sz == 0 || arr_b->size() != sz) {
+
+ r_dst = a;
+ } else {
+
+ PoolVector<int> v;
+ v.resize(sz);
+ {
+ PoolVector<int>::Write vw = v.write();
+ PoolVector<int>::Read ar = arr_a->read();
+ PoolVector<int>::Read br = arr_b->read();
+
+ Variant va;
+ for (int i = 0; i < sz; i++) {
+ Variant::interpolate(ar[i], br[i], c, va);
+ vw[i] = va;
+ }
+ }
+ r_dst = v;
+ }
}
return;
case POOL_REAL_ARRAY: {
- r_dst = a;
+ const PoolVector<real_t> *arr_a = reinterpret_cast<const PoolVector<real_t> *>(a._data._mem);
+ const PoolVector<real_t> *arr_b = reinterpret_cast<const PoolVector<real_t> *>(b._data._mem);
+ int sz = arr_a->size();
+ if (sz == 0 || arr_b->size() != sz) {
+
+ r_dst = a;
+ } else {
+
+ PoolVector<real_t> v;
+ v.resize(sz);
+ {
+ PoolVector<real_t>::Write vw = v.write();
+ PoolVector<real_t>::Read ar = arr_a->read();
+ PoolVector<real_t>::Read br = arr_b->read();
+
+ Variant va;
+ for (int i = 0; i < sz; i++) {
+ Variant::interpolate(ar[i], br[i], c, va);
+ vw[i] = va;
+ }
+ }
+ r_dst = v;
+ }
}
return;
case POOL_STRING_ARRAY: {
@@ -3717,7 +3761,27 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
}
return;
case POOL_COLOR_ARRAY: {
- r_dst = a;
+ const PoolVector<Color> *arr_a = reinterpret_cast<const PoolVector<Color> *>(a._data._mem);
+ const PoolVector<Color> *arr_b = reinterpret_cast<const PoolVector<Color> *>(b._data._mem);
+ int sz = arr_a->size();
+ if (sz == 0 || arr_b->size() != sz) {
+
+ r_dst = a;
+ } else {
+
+ PoolVector<Color> v;
+ v.resize(sz);
+ {
+ PoolVector<Color>::Write vw = v.write();
+ PoolVector<Color>::Read ar = arr_a->read();
+ PoolVector<Color>::Read br = arr_b->read();
+
+ for (int i = 0; i < sz; i++) {
+ vw[i] = ar[i].linear_interpolate(br[i], c);
+ }
+ }
+ r_dst = v;
+ }
}
return;
default: {