summaryrefslogtreecommitdiff
path: root/core/variant
diff options
context:
space:
mode:
Diffstat (limited to 'core/variant')
-rw-r--r--core/variant/array.cpp10
-rw-r--r--core/variant/binder_common.h26
-rw-r--r--core/variant/callable.cpp21
-rw-r--r--core/variant/callable.h14
-rw-r--r--core/variant/callable_bind.cpp29
-rw-r--r--core/variant/callable_bind.h6
-rw-r--r--core/variant/method_ptrcall.h3
-rw-r--r--core/variant/type_info.h49
-rw-r--r--core/variant/variant.cpp331
-rw-r--r--core/variant/variant.h51
-rw-r--r--core/variant/variant_call.cpp181
-rw-r--r--core/variant/variant_construct.cpp15
-rw-r--r--core/variant/variant_construct.h3
-rw-r--r--core/variant/variant_internal.h104
-rw-r--r--core/variant/variant_op.cpp133
-rw-r--r--core/variant/variant_op.h48
-rw-r--r--core/variant/variant_parser.cpp61
-rw-r--r--core/variant/variant_setget.cpp21
-rw-r--r--core/variant/variant_setget.h15
-rw-r--r--core/variant/variant_utility.cpp166
20 files changed, 1181 insertions, 106 deletions
diff --git a/core/variant/array.cpp b/core/variant/array.cpp
index af166e09a3..c1bdd6a6bc 100644
--- a/core/variant/array.cpp
+++ b/core/variant/array.cpp
@@ -441,7 +441,7 @@ Array Array::filter(const Callable &p_callable) const {
Variant result;
Callable::CallError ce;
- p_callable.call(argptrs, 1, result, ce);
+ p_callable.callp(argptrs, 1, result, ce);
if (ce.error != Callable::CallError::CALL_OK) {
ERR_FAIL_V_MSG(Array(), "Error calling method from 'filter': " + Variant::get_callable_error_text(p_callable, argptrs, 1, ce));
}
@@ -467,7 +467,7 @@ Array Array::map(const Callable &p_callable) const {
Variant result;
Callable::CallError ce;
- p_callable.call(argptrs, 1, result, ce);
+ p_callable.callp(argptrs, 1, result, ce);
if (ce.error != Callable::CallError::CALL_OK) {
ERR_FAIL_V_MSG(Array(), "Error calling method from 'map': " + Variant::get_callable_error_text(p_callable, argptrs, 1, ce));
}
@@ -493,7 +493,7 @@ Variant Array::reduce(const Callable &p_callable, const Variant &p_accum) const
Variant result;
Callable::CallError ce;
- p_callable.call(argptrs, 2, result, ce);
+ p_callable.callp(argptrs, 2, result, ce);
if (ce.error != Callable::CallError::CALL_OK) {
ERR_FAIL_V_MSG(Variant(), "Error calling method from 'reduce': " + Variant::get_callable_error_text(p_callable, argptrs, 2, ce));
}
@@ -510,7 +510,7 @@ bool Array::any(const Callable &p_callable) const {
Variant result;
Callable::CallError ce;
- p_callable.call(argptrs, 1, result, ce);
+ p_callable.callp(argptrs, 1, result, ce);
if (ce.error != Callable::CallError::CALL_OK) {
ERR_FAIL_V_MSG(false, "Error calling method from 'any': " + Variant::get_callable_error_text(p_callable, argptrs, 1, ce));
}
@@ -532,7 +532,7 @@ bool Array::all(const Callable &p_callable) const {
Variant result;
Callable::CallError ce;
- p_callable.call(argptrs, 1, result, ce);
+ p_callable.callp(argptrs, 1, result, ce);
if (ce.error != Callable::CallError::CALL_OK) {
ERR_FAIL_V_MSG(false, "Error calling method from 'all': " + Variant::get_callable_error_text(p_callable, argptrs, 1, ce));
}
diff --git a/core/variant/binder_common.h b/core/variant/binder_common.h
index 22a13b0fab..f0c3b1ce38 100644
--- a/core/variant/binder_common.h
+++ b/core/variant/binder_common.h
@@ -106,6 +106,29 @@ struct VariantCaster<const T &> {
static void initialize(m_enum &value) { value = (m_enum)0; } \
};
+#define VARIANT_BITFIELD_CAST(m_enum) \
+ MAKE_BITFIELD_TYPE_INFO(m_enum) \
+ template <> \
+ struct VariantCaster<BitField<m_enum>> { \
+ static _FORCE_INLINE_ BitField<m_enum> cast(const Variant &p_variant) { \
+ return BitField<m_enum>(p_variant.operator int64_t()); \
+ } \
+ }; \
+ template <> \
+ struct PtrToArg<BitField<m_enum>> { \
+ _FORCE_INLINE_ static BitField<m_enum> convert(const void *p_ptr) { \
+ return BitField<m_enum>(*reinterpret_cast<const int64_t *>(p_ptr)); \
+ } \
+ typedef int64_t EncodeT; \
+ _FORCE_INLINE_ static void encode(BitField<m_enum> p_val, const void *p_ptr) { \
+ *(int64_t *)p_ptr = p_val; \
+ } \
+ }; \
+ template <> \
+ struct ZeroInitializer<BitField<m_enum>> { \
+ static void initialize(BitField<m_enum> &value) { value = 0; } \
+ };
+
// Object enum casts must go here
VARIANT_ENUM_CAST(Object::ConnectFlags);
@@ -113,7 +136,10 @@ VARIANT_ENUM_CAST(Vector2::Axis);
VARIANT_ENUM_CAST(Vector2i::Axis);
VARIANT_ENUM_CAST(Vector3::Axis);
VARIANT_ENUM_CAST(Vector3i::Axis);
+VARIANT_ENUM_CAST(Vector4::Axis);
+VARIANT_ENUM_CAST(Vector4i::Axis);
VARIANT_ENUM_CAST(Basis::EulerOrder);
+VARIANT_ENUM_CAST(Projection::Planes);
VARIANT_ENUM_CAST(Error);
VARIANT_ENUM_CAST(Side);
diff --git a/core/variant/callable.cpp b/core/variant/callable.cpp
index 5453f0d5c6..28efb43fc5 100644
--- a/core/variant/callable.cpp
+++ b/core/variant/callable.cpp
@@ -36,11 +36,11 @@
#include "core/object/ref_counted.h"
#include "core/object/script_language.h"
-void Callable::call_deferred(const Variant **p_arguments, int p_argcount) const {
+void Callable::call_deferredp(const Variant **p_arguments, int p_argcount) const {
MessageQueue::get_singleton()->push_callablep(*this, p_arguments, p_argcount);
}
-void Callable::call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, CallError &r_call_error) const {
+void Callable::callp(const Variant **p_arguments, int p_argcount, Variant &r_return_value, CallError &r_call_error) const {
if (is_null()) {
r_call_error.error = CallError::CALL_ERROR_INSTANCE_IS_NULL;
r_call_error.argument = 0;
@@ -63,21 +63,23 @@ void Callable::call(const Variant **p_arguments, int p_argcount, Variant &r_retu
}
}
-void Callable::rpc(int p_id, const Variant **p_arguments, int p_argcount, CallError &r_call_error) const {
+Error Callable::rpcp(int p_id, const Variant **p_arguments, int p_argcount, CallError &r_call_error) const {
if (is_null()) {
r_call_error.error = CallError::CALL_ERROR_INSTANCE_IS_NULL;
r_call_error.argument = 0;
r_call_error.expected = 0;
+ return ERR_UNCONFIGURED;
} else if (!is_custom()) {
r_call_error.error = CallError::CALL_ERROR_INVALID_METHOD;
r_call_error.argument = 0;
r_call_error.expected = 0;
+ return ERR_UNCONFIGURED;
} else {
- custom->rpc(p_id, p_arguments, p_argcount, r_call_error);
+ return custom->rpc(p_id, p_arguments, p_argcount, r_call_error);
}
}
-Callable Callable::bind(const Variant **p_arguments, int p_argcount) const {
+Callable Callable::bindp(const Variant **p_arguments, int p_argcount) const {
Vector<Variant> args;
args.resize(p_argcount);
for (int i = 0; i < p_argcount; i++) {
@@ -316,10 +318,11 @@ StringName CallableCustom::get_method() const {
ERR_FAIL_V_MSG(StringName(), vformat("Can't get method on CallableCustom \"%s\".", get_as_text()));
}
-void CallableCustom::rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const {
+Error CallableCustom::rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const {
r_call_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_call_error.argument = 0;
r_call_error.expected = 0;
+ return ERR_UNCONFIGURED;
}
const Callable *CallableCustom::get_base_comparator() const {
@@ -387,7 +390,7 @@ Error Signal::connect(const Callable &p_callable, uint32_t p_flags) {
Object *object = get_object();
ERR_FAIL_COND_V(!object, ERR_UNCONFIGURED);
- return object->connect(name, p_callable, varray(), p_flags);
+ return object->connect(name, p_callable, p_flags);
}
void Signal::disconnect(const Callable &p_callable) {
@@ -435,8 +438,8 @@ bool CallableComparator::operator()(const Variant &p_l, const Variant &p_r) cons
const Variant *args[2] = { &p_l, &p_r };
Callable::CallError err;
Variant res;
- func.call(args, 2, res, err);
+ func.callp(args, 2, res, err);
ERR_FAIL_COND_V_MSG(err.error != Callable::CallError::CALL_OK, false,
- "Error calling compare method: " + Variant::get_callable_error_text(func, args, 1, err));
+ "Error calling compare method: " + Variant::get_callable_error_text(func, args, 2, err));
return res;
}
diff --git a/core/variant/callable.h b/core/variant/callable.h
index bbcf5427ba..1f1c983eb3 100644
--- a/core/variant/callable.h
+++ b/core/variant/callable.h
@@ -45,6 +45,7 @@ class CallableCustom;
// but can be optimized or customized.
// Enforce 16 bytes with `alignas` to avoid arch-specific alignment issues on x86 vs armv7.
+
class Callable {
alignas(8) StringName method;
union {
@@ -68,10 +69,10 @@ public:
int expected = 0;
};
- void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, CallError &r_call_error) const;
- void call_deferred(const Variant **p_arguments, int p_argcount) const;
+ void callp(const Variant **p_arguments, int p_argcount, Variant &r_return_value, CallError &r_call_error) const;
+ void call_deferredp(const Variant **p_arguments, int p_argcount) const;
- void rpc(int p_id, const Variant **p_arguments, int p_argcount, CallError &r_call_error) const;
+ Error rpcp(int p_id, const Variant **p_arguments, int p_argcount, CallError &r_call_error) const;
_FORCE_INLINE_ bool is_null() const {
return method == StringName() && object == 0;
@@ -84,7 +85,10 @@ public:
}
bool is_valid() const;
- Callable bind(const Variant **p_arguments, int p_argcount) const;
+ template <typename... VarArgs>
+ Callable bind(VarArgs... p_args);
+
+ Callable bindp(const Variant **p_arguments, int p_argcount) const;
Callable unbind(int p_argcount) const;
Object *get_object() const;
@@ -129,7 +133,7 @@ public:
virtual StringName get_method() const;
virtual ObjectID get_object() const = 0; //must always be able to provide an object
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const = 0;
- virtual void rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const;
+ virtual Error rpc(int p_peer_id, const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) const;
virtual const Callable *get_base_comparator() const;
CallableCustom();
diff --git a/core/variant/callable_bind.cpp b/core/variant/callable_bind.cpp
index 1a400b4360..d26aa2ae46 100644
--- a/core/variant/callable_bind.cpp
+++ b/core/variant/callable_bind.cpp
@@ -96,7 +96,7 @@ void CallableCustomBind::call(const Variant **p_arguments, int p_argcount, Varia
args[i + p_argcount] = (const Variant *)&binds[i];
}
- callable.call(args, p_argcount + binds.size(), r_return_value, r_call_error);
+ callable.callp(args, p_argcount + binds.size(), r_return_value, r_call_error);
}
CallableCustomBind::CallableCustomBind(const Callable &p_callable, const Vector<Variant> &p_binds) {
@@ -171,7 +171,7 @@ void CallableCustomUnbind::call(const Variant **p_arguments, int p_argcount, Var
r_call_error.expected = argcount;
return;
}
- callable.call(p_arguments, p_argcount - argcount, r_return_value, r_call_error);
+ callable.callp(p_arguments, p_argcount - argcount, r_return_value, r_call_error);
}
CallableCustomUnbind::CallableCustomUnbind(const Callable &p_callable, int p_argcount) {
@@ -181,28 +181,3 @@ CallableCustomUnbind::CallableCustomUnbind(const Callable &p_callable, int p_arg
CallableCustomUnbind::~CallableCustomUnbind() {
}
-
-Callable callable_bind(const Callable &p_callable, const Variant &p_arg1) {
- const Variant *args[1] = { &p_arg1 };
- return p_callable.bind(args, 1);
-}
-
-Callable callable_bind(const Callable &p_callable, const Variant &p_arg1, const Variant &p_arg2) {
- const Variant *args[2] = { &p_arg1, &p_arg2 };
- return p_callable.bind(args, 2);
-}
-
-Callable callable_bind(const Callable &p_callable, const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3) {
- const Variant *args[3] = { &p_arg1, &p_arg2, &p_arg3 };
- return p_callable.bind(args, 3);
-}
-
-Callable callable_bind(const Callable &p_callable, const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3, const Variant &p_arg4) {
- const Variant *args[4] = { &p_arg1, &p_arg2, &p_arg3, &p_arg4 };
- return p_callable.bind(args, 4);
-}
-
-Callable callable_bind(const Callable &p_callable, const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3, const Variant &p_arg4, const Variant &p_arg5) {
- const Variant *args[5] = { &p_arg1, &p_arg2, &p_arg3, &p_arg4, &p_arg5 };
- return p_callable.bind(args, 5);
-}
diff --git a/core/variant/callable_bind.h b/core/variant/callable_bind.h
index a5c830e109..f7351d29e0 100644
--- a/core/variant/callable_bind.h
+++ b/core/variant/callable_bind.h
@@ -84,10 +84,4 @@ public:
virtual ~CallableCustomUnbind();
};
-Callable callable_bind(const Callable &p_callable, const Variant &p_arg1);
-Callable callable_bind(const Callable &p_callable, const Variant &p_arg1, const Variant &p_arg2);
-Callable callable_bind(const Callable &p_callable, const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3);
-Callable callable_bind(const Callable &p_callable, const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3, const Variant &p_arg4);
-Callable callable_bind(const Callable &p_callable, const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3, const Variant &p_arg4, const Variant &p_arg5);
-
#endif // CALLABLE_BIND_H
diff --git a/core/variant/method_ptrcall.h b/core/variant/method_ptrcall.h
index d0acf60c22..0ed70a5504 100644
--- a/core/variant/method_ptrcall.h
+++ b/core/variant/method_ptrcall.h
@@ -125,7 +125,10 @@ MAKE_PTRARG(Rect2);
MAKE_PTRARG(Rect2i);
MAKE_PTRARG_BY_REFERENCE(Vector3);
MAKE_PTRARG_BY_REFERENCE(Vector3i);
+MAKE_PTRARG_BY_REFERENCE(Vector4);
+MAKE_PTRARG_BY_REFERENCE(Vector4i);
MAKE_PTRARG(Transform2D);
+MAKE_PTRARG(Projection);
MAKE_PTRARG_BY_REFERENCE(Plane);
MAKE_PTRARG(Quaternion);
MAKE_PTRARG_BY_REFERENCE(AABB);
diff --git a/core/variant/type_info.h b/core/variant/type_info.h
index bacd0d19ce..7372c60754 100644
--- a/core/variant/type_info.h
+++ b/core/variant/type_info.h
@@ -144,12 +144,15 @@ MAKE_TYPE_INFO(Vector3, Variant::VECTOR3)
MAKE_TYPE_INFO(Vector2i, Variant::VECTOR2I)
MAKE_TYPE_INFO(Rect2i, Variant::RECT2I)
MAKE_TYPE_INFO(Vector3i, Variant::VECTOR3I)
+MAKE_TYPE_INFO(Vector4, Variant::VECTOR4)
+MAKE_TYPE_INFO(Vector4i, Variant::VECTOR4I)
MAKE_TYPE_INFO(Transform2D, Variant::TRANSFORM2D)
MAKE_TYPE_INFO(Plane, Variant::PLANE)
MAKE_TYPE_INFO(Quaternion, Variant::QUATERNION)
MAKE_TYPE_INFO(AABB, Variant::AABB)
MAKE_TYPE_INFO(Basis, Variant::BASIS)
MAKE_TYPE_INFO(Transform3D, Variant::TRANSFORM3D)
+MAKE_TYPE_INFO(Projection, Variant::PROJECTION)
MAKE_TYPE_INFO(Color, Variant::COLOR)
MAKE_TYPE_INFO(StringName, Variant::STRING_NAME)
MAKE_TYPE_INFO(NodePath, Variant::NODE_PATH)
@@ -279,6 +282,52 @@ inline StringName __constant_get_enum_name(T param, const String &p_constant) {
return GetTypeInfo<T>::get_class_info().class_name;
}
+template <class T>
+class BitField {
+ uint32_t value = 0;
+
+public:
+ _FORCE_INLINE_ void set_flag(T p_flag) { value |= p_flag; }
+ _FORCE_INLINE_ bool has_flag(T p_flag) const { return value & p_flag; }
+ _FORCE_INLINE_ void clear_flag(T p_flag) { return value &= ~p_flag; }
+ _FORCE_INLINE_ BitField(uint32_t p_value) { value = p_value; }
+ _FORCE_INLINE_ operator uint32_t() const { return value; }
+ _FORCE_INLINE_ operator Variant() const { return value; }
+};
+
+#define TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, m_impl) \
+ template <> \
+ struct GetTypeInfo<m_impl> { \
+ static const Variant::Type VARIANT_TYPE = Variant::INT; \
+ static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; \
+ static inline PropertyInfo get_class_info() { \
+ return PropertyInfo(Variant::INT, String(), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_BITFIELD, \
+ godot::details::enum_qualified_name_to_class_info_name(String(#m_enum))); \
+ } \
+ }; \
+ template <> \
+ struct GetTypeInfo<BitField<m_impl>> { \
+ static const Variant::Type VARIANT_TYPE = Variant::INT; \
+ static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; \
+ static inline PropertyInfo get_class_info() { \
+ return PropertyInfo(Variant::INT, String(), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_BITFIELD, \
+ godot::details::enum_qualified_name_to_class_info_name(String(#m_enum))); \
+ } \
+ };
+
+#define MAKE_BITFIELD_TYPE_INFO(m_enum) \
+ TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, m_enum) \
+ TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, m_enum const) \
+ TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, m_enum &) \
+ TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, const m_enum &)
+
+template <typename T>
+inline StringName __constant_get_bitfield_name(T param, const String &p_constant) {
+ if (GetTypeInfo<T>::VARIANT_TYPE == Variant::NIL) {
+ ERR_PRINT("Missing VARIANT_ENUM_CAST for constant's bitfield: " + p_constant);
+ }
+ return GetTypeInfo<BitField<T>>::get_class_info().class_name;
+}
#define CLASS_INFO(m_type) (GetTypeInfo<m_type *>::get_class_info())
template <typename T>
diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp
index ae92d7b5c4..a5bc6c229d 100644
--- a/core/variant/variant.cpp
+++ b/core/variant/variant.cpp
@@ -39,6 +39,10 @@
#include "core/string/print_string.h"
#include "core/variant/variant_parser.h"
+PagedAllocator<Variant::Pools::BucketSmall, true> Variant::Pools::_bucket_small;
+PagedAllocator<Variant::Pools::BucketMedium, true> Variant::Pools::_bucket_medium;
+PagedAllocator<Variant::Pools::BucketLarge, true> Variant::Pools::_bucket_large;
+
String Variant::get_type_name(Variant::Type p_type) {
switch (p_type) {
case NIL: {
@@ -83,6 +87,12 @@ String Variant::get_type_name(Variant::Type p_type) {
case VECTOR3I: {
return "Vector3i";
} break;
+ case VECTOR4: {
+ return "Vector4";
+ } break;
+ case VECTOR4I: {
+ return "Vector4i";
+ } break;
case PLANE: {
return "Plane";
@@ -102,6 +112,10 @@ String Variant::get_type_name(Variant::Type p_type) {
return "Transform3D";
} break;
+ case PROJECTION: {
+ return "Projection";
+
+ } break;
// misc types
case COLOR: {
@@ -298,6 +312,24 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
valid_types = valid;
} break;
+ case VECTOR4: {
+ static const Type valid[] = {
+ VECTOR4I,
+ NIL,
+ };
+
+ valid_types = valid;
+
+ } break;
+ case VECTOR4I: {
+ static const Type valid[] = {
+ VECTOR4,
+ NIL,
+ };
+
+ valid_types = valid;
+
+ } break;
case QUATERNION: {
static const Type valid[] = {
@@ -322,6 +354,16 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
TRANSFORM2D,
QUATERNION,
BASIS,
+ PROJECTION,
+ NIL
+ };
+
+ valid_types = valid;
+
+ } break;
+ case PROJECTION: {
+ static const Type valid[] = {
+ TRANSFORM3D,
NIL
};
@@ -604,6 +646,24 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
valid_types = valid;
} break;
+ case VECTOR4: {
+ static const Type valid[] = {
+ VECTOR4I,
+ NIL,
+ };
+
+ valid_types = valid;
+
+ } break;
+ case VECTOR4I: {
+ static const Type valid[] = {
+ VECTOR4,
+ NIL,
+ };
+
+ valid_types = valid;
+
+ } break;
case QUATERNION: {
static const Type valid[] = {
@@ -628,6 +688,16 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
TRANSFORM2D,
QUATERNION,
BASIS,
+ PROJECTION,
+ NIL
+ };
+
+ valid_types = valid;
+
+ } break;
+ case PROJECTION: {
+ static const Type valid[] = {
+ TRANSFORM3D,
NIL
};
@@ -858,6 +928,14 @@ bool Variant::is_zero() const {
return *reinterpret_cast<const Vector3i *>(_data._mem) == Vector3i();
} break;
+ case VECTOR4: {
+ return *reinterpret_cast<const Vector4 *>(_data._mem) == Vector4();
+
+ } break;
+ case VECTOR4I: {
+ return *reinterpret_cast<const Vector4i *>(_data._mem) == Vector4i();
+
+ } break;
case PLANE: {
return *reinterpret_cast<const Plane *>(_data._mem) == Plane();
@@ -877,6 +955,10 @@ bool Variant::is_zero() const {
return *_data._transform3d == Transform3D();
} break;
+ case PROJECTION: {
+ return *_data._projection == Projection();
+
+ } break;
// misc types
case COLOR: {
@@ -998,6 +1080,14 @@ bool Variant::is_one() const {
return *reinterpret_cast<const Vector3i *>(_data._mem) == Vector3i(1, 1, 1);
} break;
+ case VECTOR4: {
+ return *reinterpret_cast<const Vector4 *>(_data._mem) == Vector4(1, 1, 1, 1);
+
+ } break;
+ case VECTOR4I: {
+ return *reinterpret_cast<const Vector4i *>(_data._mem) == Vector4i(1, 1, 1, 1);
+
+ } break;
case PLANE: {
return *reinterpret_cast<const Plane *>(_data._mem) == Plane(1, 1, 1, 1);
@@ -1076,7 +1166,8 @@ void Variant::reference(const Variant &p_variant) {
memnew_placement(_data._mem, Rect2i(*reinterpret_cast<const Rect2i *>(p_variant._data._mem)));
} break;
case TRANSFORM2D: {
- _data._transform2d = memnew(Transform2D(*p_variant._data._transform2d));
+ _data._transform2d = (Transform2D *)Pools::_bucket_small.alloc();
+ memnew_placement(_data._transform2d, Transform2D(*p_variant._data._transform2d));
} break;
case VECTOR3: {
memnew_placement(_data._mem, Vector3(*reinterpret_cast<const Vector3 *>(p_variant._data._mem)));
@@ -1084,23 +1175,33 @@ void Variant::reference(const Variant &p_variant) {
case VECTOR3I: {
memnew_placement(_data._mem, Vector3i(*reinterpret_cast<const Vector3i *>(p_variant._data._mem)));
} break;
+ case VECTOR4: {
+ memnew_placement(_data._mem, Vector4(*reinterpret_cast<const Vector4 *>(p_variant._data._mem)));
+ } break;
+ case VECTOR4I: {
+ memnew_placement(_data._mem, Vector4i(*reinterpret_cast<const Vector4i *>(p_variant._data._mem)));
+ } break;
case PLANE: {
memnew_placement(_data._mem, Plane(*reinterpret_cast<const Plane *>(p_variant._data._mem)));
} break;
-
case AABB: {
- _data._aabb = memnew(::AABB(*p_variant._data._aabb));
+ _data._aabb = (::AABB *)Pools::_bucket_small.alloc();
+ memnew_placement(_data._aabb, ::AABB(*p_variant._data._aabb));
} break;
case QUATERNION: {
memnew_placement(_data._mem, Quaternion(*reinterpret_cast<const Quaternion *>(p_variant._data._mem)));
-
} break;
case BASIS: {
- _data._basis = memnew(Basis(*p_variant._data._basis));
-
+ _data._basis = (Basis *)Pools::_bucket_medium.alloc();
+ memnew_placement(_data._basis, Basis(*p_variant._data._basis));
} break;
case TRANSFORM3D: {
- _data._transform3d = memnew(Transform3D(*p_variant._data._transform3d));
+ _data._transform3d = (Transform3D *)Pools::_bucket_medium.alloc();
+ memnew_placement(_data._transform3d, Transform3D(*p_variant._data._transform3d));
+ } break;
+ case PROJECTION: {
+ _data._projection = (Projection *)Pools::_bucket_large.alloc();
+ memnew_placement(_data._projection, Projection(*p_variant._data._projection));
} break;
// misc types
@@ -1250,6 +1351,12 @@ void Variant::zero() {
case VECTOR3I:
*reinterpret_cast<Vector3i *>(this->_data._mem) = Vector3i();
break;
+ case VECTOR4:
+ *reinterpret_cast<Vector4 *>(this->_data._mem) = Vector4();
+ break;
+ case VECTOR4I:
+ *reinterpret_cast<Vector4i *>(this->_data._mem) = Vector4i();
+ break;
case PLANE:
*reinterpret_cast<Plane *>(this->_data._mem) = Plane();
break;
@@ -1280,18 +1387,40 @@ void Variant::_clear_internal() {
RECT2
*/
case TRANSFORM2D: {
- memdelete(_data._transform2d);
+ if (_data._transform2d) {
+ _data._transform2d->~Transform2D();
+ Pools::_bucket_small.free((Pools::BucketSmall *)_data._transform2d);
+ _data._transform2d = nullptr;
+ }
} break;
case AABB: {
- memdelete(_data._aabb);
+ if (_data._aabb) {
+ _data._aabb->~AABB();
+ Pools::_bucket_small.free((Pools::BucketSmall *)_data._aabb);
+ _data._aabb = nullptr;
+ }
} break;
case BASIS: {
- memdelete(_data._basis);
+ if (_data._basis) {
+ _data._basis->~Basis();
+ Pools::_bucket_medium.free((Pools::BucketMedium *)_data._basis);
+ _data._basis = nullptr;
+ }
} break;
case TRANSFORM3D: {
- memdelete(_data._transform3d);
+ if (_data._transform3d) {
+ _data._transform3d->~Transform3D();
+ Pools::_bucket_medium.free((Pools::BucketMedium *)_data._transform3d);
+ _data._transform3d = nullptr;
+ }
+ } break;
+ case PROJECTION: {
+ if (_data._projection) {
+ _data._projection->~Projection();
+ Pools::_bucket_large.free((Pools::BucketLarge *)_data._projection);
+ _data._projection = nullptr;
+ }
} break;
-
// misc types
case STRING_NAME: {
reinterpret_cast<StringName *>(_data._mem)->~StringName();
@@ -1681,6 +1810,10 @@ String Variant::stringify(int recursion_count) const {
return operator Vector3();
case VECTOR3I:
return operator Vector3i();
+ case VECTOR4:
+ return operator Vector4();
+ case VECTOR4I:
+ return operator Vector4i();
case PLANE:
return operator Plane();
case AABB:
@@ -1691,6 +1824,8 @@ String Variant::stringify(int recursion_count) const {
return operator Basis();
case TRANSFORM3D:
return operator Transform3D();
+ case PROJECTION:
+ return operator Projection();
case STRING_NAME:
return operator StringName();
case NODE_PATH:
@@ -1812,6 +1947,10 @@ Variant::operator Vector2() const {
return Vector2(reinterpret_cast<const Vector3 *>(_data._mem)->x, reinterpret_cast<const Vector3 *>(_data._mem)->y);
} else if (type == VECTOR3I) {
return Vector2(reinterpret_cast<const Vector3i *>(_data._mem)->x, reinterpret_cast<const Vector3i *>(_data._mem)->y);
+ } else if (type == VECTOR4) {
+ return Vector2(reinterpret_cast<const Vector4 *>(_data._mem)->x, reinterpret_cast<const Vector4 *>(_data._mem)->y);
+ } else if (type == VECTOR4I) {
+ return Vector2(reinterpret_cast<const Vector4i *>(_data._mem)->x, reinterpret_cast<const Vector4i *>(_data._mem)->y);
} else {
return Vector2();
}
@@ -1826,6 +1965,10 @@ Variant::operator Vector2i() const {
return Vector2(reinterpret_cast<const Vector3 *>(_data._mem)->x, reinterpret_cast<const Vector3 *>(_data._mem)->y);
} else if (type == VECTOR3I) {
return Vector2(reinterpret_cast<const Vector3i *>(_data._mem)->x, reinterpret_cast<const Vector3i *>(_data._mem)->y);
+ } else if (type == VECTOR4) {
+ return Vector2(reinterpret_cast<const Vector4 *>(_data._mem)->x, reinterpret_cast<const Vector4 *>(_data._mem)->y);
+ } else if (type == VECTOR4I) {
+ return Vector2(reinterpret_cast<const Vector4i *>(_data._mem)->x, reinterpret_cast<const Vector4i *>(_data._mem)->y);
} else {
return Vector2i();
}
@@ -1860,6 +2003,10 @@ Variant::operator Vector3() const {
return Vector3(reinterpret_cast<const Vector2 *>(_data._mem)->x, reinterpret_cast<const Vector2 *>(_data._mem)->y, 0.0);
} else if (type == VECTOR2I) {
return Vector3(reinterpret_cast<const Vector2i *>(_data._mem)->x, reinterpret_cast<const Vector2i *>(_data._mem)->y, 0.0);
+ } else if (type == VECTOR4) {
+ return Vector3(reinterpret_cast<const Vector4 *>(_data._mem)->x, reinterpret_cast<const Vector4 *>(_data._mem)->y, reinterpret_cast<const Vector4 *>(_data._mem)->z);
+ } else if (type == VECTOR4I) {
+ return Vector3(reinterpret_cast<const Vector4i *>(_data._mem)->x, reinterpret_cast<const Vector4i *>(_data._mem)->y, reinterpret_cast<const Vector4i *>(_data._mem)->z);
} else {
return Vector3();
}
@@ -1874,11 +2021,52 @@ Variant::operator Vector3i() const {
return Vector3i(reinterpret_cast<const Vector2 *>(_data._mem)->x, reinterpret_cast<const Vector2 *>(_data._mem)->y, 0.0);
} else if (type == VECTOR2I) {
return Vector3i(reinterpret_cast<const Vector2i *>(_data._mem)->x, reinterpret_cast<const Vector2i *>(_data._mem)->y, 0.0);
+ } else if (type == VECTOR4) {
+ return Vector3i(reinterpret_cast<const Vector4 *>(_data._mem)->x, reinterpret_cast<const Vector4 *>(_data._mem)->y, reinterpret_cast<const Vector4 *>(_data._mem)->z);
+ } else if (type == VECTOR4I) {
+ return Vector3i(reinterpret_cast<const Vector4i *>(_data._mem)->x, reinterpret_cast<const Vector4i *>(_data._mem)->y, reinterpret_cast<const Vector4i *>(_data._mem)->z);
} else {
return Vector3i();
}
}
+Variant::operator Vector4() const {
+ if (type == VECTOR4) {
+ return *reinterpret_cast<const Vector4 *>(_data._mem);
+ } else if (type == VECTOR4I) {
+ return *reinterpret_cast<const Vector4i *>(_data._mem);
+ } else if (type == VECTOR2) {
+ return Vector4(reinterpret_cast<const Vector2 *>(_data._mem)->x, reinterpret_cast<const Vector2 *>(_data._mem)->y, 0.0, 0.0);
+ } else if (type == VECTOR2I) {
+ return Vector4(reinterpret_cast<const Vector2i *>(_data._mem)->x, reinterpret_cast<const Vector2i *>(_data._mem)->y, 0.0, 0.0);
+ } else if (type == VECTOR3) {
+ return Vector4(reinterpret_cast<const Vector3 *>(_data._mem)->x, reinterpret_cast<const Vector3 *>(_data._mem)->y, reinterpret_cast<const Vector3 *>(_data._mem)->z, 0.0);
+ } else if (type == VECTOR3I) {
+ return Vector4(reinterpret_cast<const Vector3i *>(_data._mem)->x, reinterpret_cast<const Vector3i *>(_data._mem)->y, reinterpret_cast<const Vector3i *>(_data._mem)->z, 0.0);
+ } else {
+ return Vector4();
+ }
+}
+
+Variant::operator Vector4i() const {
+ if (type == VECTOR4I) {
+ return *reinterpret_cast<const Vector4i *>(_data._mem);
+ } else if (type == VECTOR4) {
+ const Vector4 &v4 = *reinterpret_cast<const Vector4 *>(_data._mem);
+ return Vector4i(v4.x, v4.y, v4.z, v4.w);
+ } else if (type == VECTOR2) {
+ return Vector4i(reinterpret_cast<const Vector2 *>(_data._mem)->x, reinterpret_cast<const Vector2 *>(_data._mem)->y, 0.0, 0.0);
+ } else if (type == VECTOR2I) {
+ return Vector4i(reinterpret_cast<const Vector2i *>(_data._mem)->x, reinterpret_cast<const Vector2i *>(_data._mem)->y, 0.0, 0.0);
+ } else if (type == VECTOR3) {
+ return Vector4i(reinterpret_cast<const Vector3 *>(_data._mem)->x, reinterpret_cast<const Vector3 *>(_data._mem)->y, reinterpret_cast<const Vector3 *>(_data._mem)->z, 0.0);
+ } else if (type == VECTOR3I) {
+ return Vector4i(reinterpret_cast<const Vector3i *>(_data._mem)->x, reinterpret_cast<const Vector3i *>(_data._mem)->y, reinterpret_cast<const Vector3i *>(_data._mem)->z, 0.0);
+ } else {
+ return Vector4i();
+ }
+}
+
Variant::operator Plane() const {
if (type == PLANE) {
return *reinterpret_cast<const Plane *>(_data._mem);
@@ -1936,11 +2124,37 @@ Variant::operator Transform3D() const {
m.origin[0] = t.columns[2][0];
m.origin[1] = t.columns[2][1];
return m;
+ } else if (type == PROJECTION) {
+ return *_data._projection;
} else {
return Transform3D();
}
}
+Variant::operator Projection() const {
+ if (type == TRANSFORM3D) {
+ return *_data._transform3d;
+ } else if (type == BASIS) {
+ return Transform3D(*_data._basis, Vector3());
+ } else if (type == QUATERNION) {
+ return Transform3D(Basis(*reinterpret_cast<const Quaternion *>(_data._mem)), Vector3());
+ } else if (type == TRANSFORM2D) {
+ const Transform2D &t = *_data._transform2d;
+ Transform3D m;
+ m.basis.rows[0][0] = t.columns[0][0];
+ m.basis.rows[1][0] = t.columns[0][1];
+ m.basis.rows[0][1] = t.columns[1][0];
+ m.basis.rows[1][1] = t.columns[1][1];
+ m.origin[0] = t.columns[2][0];
+ m.origin[1] = t.columns[2][1];
+ return m;
+ } else if (type == PROJECTION) {
+ return *_data._projection;
+ } else {
+ return Projection();
+ }
+}
+
Variant::operator Transform2D() const {
if (type == TRANSFORM2D) {
return *_data._transform2d;
@@ -2384,6 +2598,16 @@ Variant::Variant(const Vector3i &p_vector3i) {
memnew_placement(_data._mem, Vector3i(p_vector3i));
}
+Variant::Variant(const Vector4 &p_vector4) {
+ type = VECTOR4;
+ memnew_placement(_data._mem, Vector4(p_vector4));
+}
+
+Variant::Variant(const Vector4i &p_vector4i) {
+ type = VECTOR4I;
+ memnew_placement(_data._mem, Vector4i(p_vector4i));
+}
+
Variant::Variant(const Vector2 &p_vector2) {
type = VECTOR2;
memnew_placement(_data._mem, Vector2(p_vector2));
@@ -2411,12 +2635,14 @@ Variant::Variant(const Plane &p_plane) {
Variant::Variant(const ::AABB &p_aabb) {
type = AABB;
- _data._aabb = memnew(::AABB(p_aabb));
+ _data._aabb = (::AABB *)Pools::_bucket_small.alloc();
+ memnew_placement(_data._aabb, ::AABB(p_aabb));
}
Variant::Variant(const Basis &p_matrix) {
type = BASIS;
- _data._basis = memnew(Basis(p_matrix));
+ _data._basis = (Basis *)Pools::_bucket_medium.alloc();
+ memnew_placement(_data._basis, Basis(p_matrix));
}
Variant::Variant(const Quaternion &p_quaternion) {
@@ -2426,12 +2652,20 @@ Variant::Variant(const Quaternion &p_quaternion) {
Variant::Variant(const Transform3D &p_transform) {
type = TRANSFORM3D;
- _data._transform3d = memnew(Transform3D(p_transform));
+ _data._transform3d = (Transform3D *)Pools::_bucket_medium.alloc();
+ memnew_placement(_data._transform3d, Transform3D(p_transform));
+}
+
+Variant::Variant(const Projection &pp_projection) {
+ type = PROJECTION;
+ _data._projection = (Projection *)Pools::_bucket_large.alloc();
+ memnew_placement(_data._projection, Projection(pp_projection));
}
Variant::Variant(const Transform2D &p_transform) {
type = TRANSFORM2D;
- _data._transform2d = memnew(Transform2D(p_transform));
+ _data._transform2d = (Transform2D *)Pools::_bucket_small.alloc();
+ memnew_placement(_data._transform2d, Transform2D(p_transform));
}
Variant::Variant(const Color &p_color) {
@@ -2656,6 +2890,12 @@ void Variant::operator=(const Variant &p_variant) {
case VECTOR3I: {
*reinterpret_cast<Vector3i *>(_data._mem) = *reinterpret_cast<const Vector3i *>(p_variant._data._mem);
} break;
+ case VECTOR4: {
+ *reinterpret_cast<Vector4 *>(_data._mem) = *reinterpret_cast<const Vector4 *>(p_variant._data._mem);
+ } break;
+ case VECTOR4I: {
+ *reinterpret_cast<Vector4i *>(_data._mem) = *reinterpret_cast<const Vector4i *>(p_variant._data._mem);
+ } break;
case PLANE: {
*reinterpret_cast<Plane *>(_data._mem) = *reinterpret_cast<const Plane *>(p_variant._data._mem);
} break;
@@ -2672,6 +2912,9 @@ void Variant::operator=(const Variant &p_variant) {
case TRANSFORM3D: {
*_data._transform3d = *(p_variant._data._transform3d);
} break;
+ case PROJECTION: {
+ *_data._projection = *(p_variant._data._projection);
+ } break;
// misc types
case COLOR: {
@@ -2817,6 +3060,12 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
case VECTOR3I: {
return HashMapHasherDefault::hash(*reinterpret_cast<const Vector3i *>(_data._mem));
} break;
+ case VECTOR4: {
+ return HashMapHasherDefault::hash(*reinterpret_cast<const Vector4 *>(_data._mem));
+ } break;
+ case VECTOR4I: {
+ return HashMapHasherDefault::hash(*reinterpret_cast<const Vector4i *>(_data._mem));
+ } break;
case PLANE: {
uint32_t h = HASH_MURMUR3_SEED;
const Plane &p = *reinterpret_cast<const Plane *>(_data._mem);
@@ -2869,6 +3118,27 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
h = hash_murmur3_one_real(t.origin.z, h);
return hash_fmix32(h);
} break;
+ case PROJECTION: {
+ uint32_t h = HASH_MURMUR3_SEED;
+ const Projection &t = *_data._projection;
+ h = hash_murmur3_one_real(t.matrix[0].x, h);
+ h = hash_murmur3_one_real(t.matrix[0].y, h);
+ h = hash_murmur3_one_real(t.matrix[0].z, h);
+ h = hash_murmur3_one_real(t.matrix[0].w, h);
+ h = hash_murmur3_one_real(t.matrix[1].x, h);
+ h = hash_murmur3_one_real(t.matrix[1].y, h);
+ h = hash_murmur3_one_real(t.matrix[1].z, h);
+ h = hash_murmur3_one_real(t.matrix[1].w, h);
+ h = hash_murmur3_one_real(t.matrix[2].x, h);
+ h = hash_murmur3_one_real(t.matrix[2].y, h);
+ h = hash_murmur3_one_real(t.matrix[2].z, h);
+ h = hash_murmur3_one_real(t.matrix[2].w, h);
+ h = hash_murmur3_one_real(t.matrix[3].x, h);
+ h = hash_murmur3_one_real(t.matrix[3].y, h);
+ h = hash_murmur3_one_real(t.matrix[3].z, h);
+ h = hash_murmur3_one_real(t.matrix[3].w, h);
+ return hash_fmix32(h);
+ } break;
// misc types
case COLOR: {
uint32_t h = HASH_MURMUR3_SEED;
@@ -3062,6 +3332,11 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
(hash_compare_scalar((p_lhs).x, (p_rhs).x)) && \
(hash_compare_scalar((p_lhs).y, (p_rhs).y)) && \
(hash_compare_scalar((p_lhs).z, (p_rhs).z))
+#define hash_compare_vector4(p_lhs, p_rhs) \
+ (hash_compare_scalar((p_lhs).x, (p_rhs).x)) && \
+ (hash_compare_scalar((p_lhs).y, (p_rhs).y)) && \
+ (hash_compare_scalar((p_lhs).z, (p_rhs).z)) && \
+ (hash_compare_scalar((p_lhs).w, (p_rhs).w))
#define hash_compare_quaternion(p_lhs, p_rhs) \
(hash_compare_scalar((p_lhs).x, (p_rhs).x)) && \
@@ -3165,6 +3440,18 @@ bool Variant::hash_compare(const Variant &p_variant, int recursion_count) const
return *l == *r;
} break;
+ case VECTOR4: {
+ const Vector4 *l = reinterpret_cast<const Vector4 *>(_data._mem);
+ const Vector4 *r = reinterpret_cast<const Vector4 *>(p_variant._data._mem);
+
+ return hash_compare_vector4(*l, *r);
+ } break;
+ case VECTOR4I: {
+ const Vector4i *l = reinterpret_cast<const Vector4i *>(_data._mem);
+ const Vector4i *r = reinterpret_cast<const Vector4i *>(p_variant._data._mem);
+
+ return *l == *r;
+ } break;
case PLANE: {
const Plane *l = reinterpret_cast<const Plane *>(_data._mem);
@@ -3215,6 +3502,18 @@ bool Variant::hash_compare(const Variant &p_variant, int recursion_count) const
return hash_compare_vector3(l->origin, r->origin);
} break;
+ case PROJECTION: {
+ const Projection *l = _data._projection;
+ const Projection *r = p_variant._data._projection;
+
+ for (int i = 0; i < 4; i++) {
+ if (!(hash_compare_vector4(l->matrix[i], r->matrix[i]))) {
+ return false;
+ }
+ }
+
+ return true;
+ } break;
case COLOR: {
const Color *l = reinterpret_cast<const Color *>(_data._mem);
diff --git a/core/variant/variant.h b/core/variant/variant.h
index 872b374b13..212f94a9a8 100644
--- a/core/variant/variant.h
+++ b/core/variant/variant.h
@@ -38,6 +38,7 @@
#include "core/math/color.h"
#include "core/math/face3.h"
#include "core/math/plane.h"
+#include "core/math/projection.h"
#include "core/math/quaternion.h"
#include "core/math/rect2.h"
#include "core/math/rect2i.h"
@@ -47,10 +48,13 @@
#include "core/math/vector2i.h"
#include "core/math/vector3.h"
#include "core/math/vector3i.h"
+#include "core/math/vector4.h"
+#include "core/math/vector4i.h"
#include "core/object/object_id.h"
#include "core/os/keyboard.h"
#include "core/string/node_path.h"
#include "core/string/ustring.h"
+#include "core/templates/paged_allocator.h"
#include "core/templates/rid.h"
#include "core/variant/array.h"
#include "core/variant/callable.h"
@@ -91,11 +95,14 @@ public:
VECTOR3,
VECTOR3I,
TRANSFORM2D,
+ VECTOR4,
+ VECTOR4I,
PLANE,
QUATERNION,
AABB,
BASIS,
TRANSFORM3D,
+ PROJECTION,
// misc types
COLOR,
@@ -128,6 +135,30 @@ public:
};
private:
+ struct Pools {
+ union BucketSmall {
+ BucketSmall() {}
+ ~BucketSmall() {}
+ Transform2D _transform2d;
+ ::AABB _aabb;
+ };
+ union BucketMedium {
+ BucketMedium() {}
+ ~BucketMedium() {}
+ Basis _basis;
+ Transform3D _transform3d;
+ };
+ union BucketLarge {
+ BucketLarge() {}
+ ~BucketLarge() {}
+ Projection _projection;
+ };
+
+ static PagedAllocator<BucketSmall, true> _bucket_small;
+ static PagedAllocator<BucketMedium, true> _bucket_medium;
+ static PagedAllocator<BucketLarge, true> _bucket_large;
+ };
+
friend struct _VariantCall;
friend class VariantInternal;
// Variant takes 20 bytes when real_t is float, and 36 if double
@@ -210,6 +241,7 @@ private:
::AABB *_aabb;
Basis *_basis;
Transform3D *_transform3d;
+ Projection *_projection;
PackedArrayRefBase *packed_array;
void *_ptr; //generic pointer
uint8_t _mem[sizeof(ObjData) > (sizeof(real_t) * 4) ? sizeof(ObjData) : (sizeof(real_t) * 4)]{ 0 };
@@ -234,11 +266,14 @@ private:
false, //VECTOR3,
false, //VECTOR3I,
true, //TRANSFORM2D,
+ false, //VECTOR4,
+ false, //VECTOR4I,
false, //PLANE,
false, //QUATERNION,
true, //AABB,
true, //BASIS,
true, //TRANSFORM,
+ true, //PROJECTION,
// misc types
false, //COLOR,
@@ -339,12 +374,15 @@ public:
operator Rect2i() const;
operator Vector3() const;
operator Vector3i() const;
+ operator Vector4() const;
+ operator Vector4i() const;
operator Plane() const;
operator ::AABB() const;
operator Quaternion() const;
operator Basis() const;
operator Transform2D() const;
operator Transform3D() const;
+ operator Projection() const;
operator Color() const;
operator NodePath() const;
@@ -409,12 +447,15 @@ public:
Variant(const Rect2i &p_rect2i);
Variant(const Vector3 &p_vector3);
Variant(const Vector3i &p_vector3i);
+ Variant(const Vector4 &p_vector4);
+ Variant(const Vector4i &p_vector4i);
Variant(const Plane &p_plane);
Variant(const ::AABB &p_aabb);
Variant(const Quaternion &p_quat);
Variant(const Basis &p_matrix);
Variant(const Transform2D &p_transform);
Variant(const Transform3D &p_transform);
+ Variant(const Projection &p_projection);
Variant(const Color &p_color);
Variant(const NodePath &p_node_path);
Variant(const ::RID &p_rid);
@@ -768,4 +809,14 @@ const Variant::ObjData &Variant::_get_obj() const {
String vformat(const String &p_text, const Variant &p1 = Variant(), const Variant &p2 = Variant(), const Variant &p3 = Variant(), const Variant &p4 = Variant(), const Variant &p5 = Variant());
+template <typename... VarArgs>
+Callable Callable::bind(VarArgs... p_args) {
+ Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported.
+ const Variant *argptrs[sizeof...(p_args) + 1];
+ for (uint32_t i = 0; i < sizeof...(p_args); i++) {
+ argptrs[i] = &args[i];
+ }
+ return bindp(sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args));
+}
+
#endif // VARIANT_H
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index a4bb7630d6..5c298f9b3b 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -753,40 +753,56 @@ struct _VariantCall {
static PackedInt32Array func_PackedByteArray_decode_s32_array(PackedByteArray *p_instance) {
uint64_t size = p_instance->size();
PackedInt32Array dest;
- ERR_FAIL_COND_V_MSG(size < sizeof(int32_t), dest, "Size didn't match array of size int32_t, maybe you are trying to convert to the wrong type?");
+ if (size == 0) {
+ return dest;
+ }
+ ERR_FAIL_COND_V_MSG(size % sizeof(int32_t), dest, "PackedByteArray size must be a multiple of 4 (size of 32-bit integer) to convert to PackedInt32Array.");
const uint8_t *r = p_instance->ptr();
dest.resize(size / sizeof(int32_t));
- memcpy(dest.ptrw(), r, size);
+ ERR_FAIL_COND_V(dest.size() == 0, dest); // Avoid UB in case resize failed.
+ memcpy(dest.ptrw(), r, dest.size() * sizeof(int32_t));
return dest;
}
static PackedInt64Array func_PackedByteArray_decode_s64_array(PackedByteArray *p_instance) {
uint64_t size = p_instance->size();
PackedInt64Array dest;
- ERR_FAIL_COND_V_MSG(size < sizeof(int64_t), dest, "Size didn't match array of size int64_t, maybe you are trying to convert to the wrong type?");
+ if (size == 0) {
+ return dest;
+ }
+ ERR_FAIL_COND_V_MSG(size % sizeof(int64_t), dest, "PackedByteArray size must be a multiple of 8 (size of 64-bit integer) to convert to PackedInt64Array.");
const uint8_t *r = p_instance->ptr();
dest.resize(size / sizeof(int64_t));
- memcpy(dest.ptrw(), r, size);
+ ERR_FAIL_COND_V(dest.size() == 0, dest); // Avoid UB in case resize failed.
+ memcpy(dest.ptrw(), r, dest.size() * sizeof(int64_t));
return dest;
}
static PackedFloat32Array func_PackedByteArray_decode_float_array(PackedByteArray *p_instance) {
uint64_t size = p_instance->size();
PackedFloat32Array dest;
- ERR_FAIL_COND_V_MSG(size < sizeof(float), dest, "Size didn't match array of size float, maybe you are trying to convert to the wrong type?");
+ if (size == 0) {
+ return dest;
+ }
+ ERR_FAIL_COND_V_MSG(size % sizeof(float), dest, "PackedByteArray size must be a multiple of 4 (size of 32-bit float) to convert to PackedFloat32Array.");
const uint8_t *r = p_instance->ptr();
dest.resize(size / sizeof(float));
- memcpy(dest.ptrw(), r, size);
+ ERR_FAIL_COND_V(dest.size() == 0, dest); // Avoid UB in case resize failed.
+ memcpy(dest.ptrw(), r, dest.size() * sizeof(float));
return dest;
}
static PackedFloat64Array func_PackedByteArray_decode_double_array(PackedByteArray *p_instance) {
uint64_t size = p_instance->size();
PackedFloat64Array dest;
- ERR_FAIL_COND_V_MSG(size < sizeof(double), dest, "Size didn't match array of size double, maybe you are trying to convert to the wrong type?");
+ if (size == 0) {
+ return dest;
+ }
+ ERR_FAIL_COND_V_MSG(size % sizeof(double), dest, "PackedByteArray size must be a multiple of 8 (size of 64-bit double) to convert to PackedFloat64Array.");
const uint8_t *r = p_instance->ptr();
dest.resize(size / sizeof(double));
- memcpy(dest.ptrw(), r, size);
+ ERR_FAIL_COND_V(dest.size() == 0, dest); // Avoid UB in case resize failed.
+ memcpy(dest.ptrw(), r, dest.size() * sizeof(double));
return dest;
}
@@ -879,17 +895,17 @@ struct _VariantCall {
static void func_Callable_call(Variant *v, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
Callable *callable = VariantGetInternalPtr<Callable>::get_ptr(v);
- callable->call(p_args, p_argcount, r_ret, r_error);
+ callable->callp(p_args, p_argcount, r_ret, r_error);
}
static void func_Callable_call_deferred(Variant *v, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
Callable *callable = VariantGetInternalPtr<Callable>::get_ptr(v);
- callable->call_deferred(p_args, p_argcount);
+ callable->call_deferredp(p_args, p_argcount);
}
static void func_Callable_rpc(Variant *v, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
Callable *callable = VariantGetInternalPtr<Callable>::get_ptr(v);
- callable->rpc(0, p_args, p_argcount, r_error);
+ callable->rpcp(0, p_args, p_argcount, r_error);
}
static void func_Callable_rpc_id(Variant *v, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
@@ -904,13 +920,13 @@ struct _VariantCall {
r_error.expected = Variant::INT;
} else {
Callable *callable = VariantGetInternalPtr<Callable>::get_ptr(v);
- callable->rpc(*p_args[0], &p_args[1], p_argcount - 1, r_error);
+ callable->rpcp(*p_args[0], &p_args[1], p_argcount - 1, r_error);
}
}
static void func_Callable_bind(Variant *v, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
Callable *callable = VariantGetInternalPtr<Callable>::get_ptr(v);
- r_ret = callable->bind(p_args, p_argcount);
+ r_ret = callable->bindp(p_args, p_argcount);
}
static void func_Signal_emit(Variant *v, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
@@ -1709,14 +1725,49 @@ static void _register_variant_builtin_methods() {
bind_method(Vector3i, abs, sarray(), varray());
bind_method(Vector3i, clamp, sarray("min", "max"), varray());
+ /* Vector4 */
+
+ bind_method(Vector4, min_axis_index, sarray(), varray());
+ bind_method(Vector4, max_axis_index, sarray(), varray());
+ bind_method(Vector4, length, sarray(), varray());
+ bind_method(Vector4, length_squared, sarray(), varray());
+ bind_method(Vector4, abs, sarray(), varray());
+ bind_method(Vector4, sign, sarray(), varray());
+ bind_method(Vector4, floor, sarray(), varray());
+ bind_method(Vector4, ceil, sarray(), varray());
+ bind_method(Vector4, round, sarray(), varray());
+ bind_method(Vector4, lerp, sarray("to", "weight"), varray());
+ bind_method(Vector4, cubic_interpolate, sarray("b", "pre_a", "post_b", "weight"), varray());
+ bind_method(Vector4, posmod, sarray("mod"), varray());
+ bind_method(Vector4, posmodv, sarray("modv"), varray());
+ bind_method(Vector4, snapped, sarray("step"), varray());
+ bind_method(Vector4, clamp, sarray("min", "max"), varray());
+ bind_method(Vector4, normalized, sarray(), varray());
+ bind_method(Vector4, is_normalized, sarray(), varray());
+ bind_method(Vector4, direction_to, sarray("to"), varray());
+ bind_method(Vector4, distance_to, sarray("to"), varray());
+ bind_method(Vector4, dot, sarray("with"), varray());
+ bind_method(Vector4, inverse, sarray(), varray());
+ bind_method(Vector4, is_equal_approx, sarray("with"), varray());
+
+ /* Vector4i */
+
+ bind_method(Vector4i, min_axis_index, sarray(), varray());
+ bind_method(Vector4i, max_axis_index, sarray(), varray());
+ bind_method(Vector4i, length, sarray(), varray());
+ bind_method(Vector4i, length_squared, sarray(), varray());
+ bind_method(Vector4i, sign, sarray(), varray());
+ bind_method(Vector4i, abs, sarray(), varray());
+ bind_method(Vector4i, clamp, sarray("min", "max"), varray());
+
/* Plane */
bind_method(Plane, normalized, sarray(), varray());
bind_method(Plane, center, sarray(), varray());
bind_method(Plane, is_equal_approx, sarray("to_plane"), varray());
- bind_method(Plane, is_point_over, sarray("plane"), varray());
+ bind_method(Plane, is_point_over, sarray("point"), varray());
bind_method(Plane, distance_to, sarray("point"), varray());
- bind_method(Plane, has_point, sarray("point", "epsilon"), varray(CMP_EPSILON));
+ bind_method(Plane, has_point, sarray("point", "tolerance"), varray(CMP_EPSILON));
bind_method(Plane, project, sarray("point"), varray());
bind_methodv(Plane, intersect_3, &Plane::intersect_3_bind, sarray("b", "c"), varray());
bind_methodv(Plane, intersects_ray, &Plane::intersects_ray_bind, sarray("from", "dir"), varray());
@@ -1736,7 +1787,7 @@ static void _register_variant_builtin_methods() {
bind_method(Quaternion, dot, sarray("with"), varray());
bind_method(Quaternion, slerp, sarray("to", "weight"), varray());
bind_method(Quaternion, slerpni, sarray("to", "weight"), varray());
- bind_method(Quaternion, cubic_slerp, sarray("b", "pre_a", "post_b", "weight"), varray());
+ bind_method(Quaternion, spherical_cubic_interpolate, sarray("b", "pre_a", "post_b", "weight"), varray());
bind_method(Quaternion, get_euler, sarray(), varray());
bind_method(Quaternion, get_axis, sarray(), varray());
bind_method(Quaternion, get_angle, sarray(), varray());
@@ -1790,6 +1841,7 @@ static void _register_variant_builtin_methods() {
bind_method(NodePath, get_subname_count, sarray(), varray());
bind_method(NodePath, hash, sarray(), varray());
bind_method(NodePath, get_subname, sarray("idx"), varray());
+ bind_method(NodePath, get_concatenated_names, sarray(), varray());
bind_method(NodePath, get_concatenated_subnames, sarray(), varray());
bind_method(NodePath, get_as_property_path, sarray(), varray());
bind_method(NodePath, is_empty, sarray(), varray());
@@ -1836,8 +1888,11 @@ static void _register_variant_builtin_methods() {
bind_method(Transform2D, get_skew, sarray(), varray());
bind_method(Transform2D, orthonormalized, sarray(), varray());
bind_method(Transform2D, rotated, sarray("angle"), varray());
+ bind_method(Transform2D, rotated_local, sarray("angle"), varray());
bind_method(Transform2D, scaled, sarray("scale"), varray());
+ bind_method(Transform2D, scaled_local, sarray("scale"), varray());
bind_method(Transform2D, translated, sarray("offset"), varray());
+ bind_method(Transform2D, translated_local, sarray("offset"), varray());
bind_method(Transform2D, basis_xform, sarray("v"), varray());
bind_method(Transform2D, basis_xform_inv, sarray("v"), varray());
bind_method(Transform2D, interpolate_with, sarray("xform", "weight"), varray());
@@ -1901,13 +1956,50 @@ static void _register_variant_builtin_methods() {
bind_method(Transform3D, affine_inverse, sarray(), varray());
bind_method(Transform3D, orthonormalized, sarray(), varray());
bind_method(Transform3D, rotated, sarray("axis", "angle"), varray());
+ bind_method(Transform3D, rotated_local, sarray("axis", "angle"), varray());
bind_method(Transform3D, scaled, sarray("scale"), varray());
+ bind_method(Transform3D, scaled_local, sarray("scale"), varray());
bind_method(Transform3D, translated, sarray("offset"), varray());
+ bind_method(Transform3D, translated_local, sarray("offset"), varray());
bind_method(Transform3D, looking_at, sarray("target", "up"), varray(Vector3(0, 1, 0)));
- bind_method(Transform3D, sphere_interpolate_with, sarray("xform", "weight"), varray());
+ bind_method(Transform3D, spherical_interpolate_with, sarray("xform", "weight"), varray());
bind_method(Transform3D, interpolate_with, sarray("xform", "weight"), varray());
bind_method(Transform3D, is_equal_approx, sarray("xform"), varray());
+ /* Projection */
+
+ bind_static_method(Projection, create_depth_correction, sarray("flip_y"), varray());
+ bind_static_method(Projection, create_light_atlas_rect, sarray("rect"), varray());
+ bind_static_method(Projection, create_perspective, sarray("fovy", "aspect", "z_near", "z_far", "flip_fov"), varray(false));
+ bind_static_method(Projection, create_perspective_hmd, sarray("fovy", "aspect", "z_near", "z_far", "flip_fov", "eye", "intraocular_dist", " convergence_dist"), varray());
+ bind_static_method(Projection, create_for_hmd, sarray("eye", "aspect", "intraocular_dist", "display_width", "display_to_lens", "oversample", "z_near", "z_far"), varray());
+ bind_static_method(Projection, create_orthogonal, sarray("left", "right", "bottom", "top", "z_near", "z_far"), varray());
+ bind_static_method(Projection, create_orthogonal_aspect, sarray("size", "aspect", "z_near", "z_far", "flip_fov"), varray(false));
+ bind_static_method(Projection, create_frustum, sarray("left", "right", "bottom", "top", "z_near", "z_far"), varray());
+ bind_static_method(Projection, create_frustum_aspect, sarray("size", "aspect", "offset", "z_near", "z_far", "flip_fov"), varray(false));
+ bind_static_method(Projection, create_fit_aabb, sarray("aabb"), varray());
+
+ bind_method(Projection, determinant, sarray(), varray());
+ bind_method(Projection, perspective_znear_adjusted, sarray("new_znear"), varray());
+ bind_method(Projection, get_projection_plane, sarray("plane"), varray());
+ bind_method(Projection, flipped_y, sarray(), varray());
+ bind_method(Projection, jitter_offseted, sarray("offset"), varray());
+
+ bind_static_method(Projection, get_fovy, sarray("fovx", "aspect"), varray());
+
+ bind_method(Projection, get_z_far, sarray(), varray());
+ bind_method(Projection, get_z_near, sarray(), varray());
+ bind_method(Projection, get_aspect, sarray(), varray());
+ bind_method(Projection, get_fov, sarray(), varray());
+ bind_method(Projection, is_orthogonal, sarray(), varray());
+
+ bind_method(Projection, get_viewport_half_extents, sarray(), varray());
+ bind_method(Projection, get_far_plane_half_extents, sarray(), varray());
+
+ bind_method(Projection, inverse, sarray(), varray());
+ bind_method(Projection, get_pixels_per_meter, sarray("for_pixel_width"), varray());
+ bind_method(Projection, get_lod_multiplier, sarray(), varray());
+
/* Dictionary */
bind_method(Dictionary, size, sarray(), varray());
@@ -1974,7 +2066,7 @@ static void _register_variant_builtin_methods() {
bind_method(PackedByteArray, remove_at, sarray("index"), varray());
bind_method(PackedByteArray, insert, sarray("at_index", "value"), varray());
bind_method(PackedByteArray, fill, sarray("value"), varray());
- bind_method(PackedByteArray, resize, sarray("new_size"), varray());
+ bind_methodv(PackedByteArray, resize, &PackedByteArray::resize_zeroed, sarray("new_size"), varray());
bind_method(PackedByteArray, has, sarray("value"), varray());
bind_method(PackedByteArray, reverse, sarray(), varray());
bind_method(PackedByteArray, slice, sarray("begin", "end"), varray(INT_MAX));
@@ -2038,7 +2130,7 @@ static void _register_variant_builtin_methods() {
bind_method(PackedInt32Array, remove_at, sarray("index"), varray());
bind_method(PackedInt32Array, insert, sarray("at_index", "value"), varray());
bind_method(PackedInt32Array, fill, sarray("value"), varray());
- bind_method(PackedInt32Array, resize, sarray("new_size"), varray());
+ bind_methodv(PackedInt32Array, resize, &PackedInt32Array::resize_zeroed, sarray("new_size"), varray());
bind_method(PackedInt32Array, has, sarray("value"), varray());
bind_method(PackedInt32Array, reverse, sarray(), varray());
bind_method(PackedInt32Array, slice, sarray("begin", "end"), varray(INT_MAX));
@@ -2061,7 +2153,7 @@ static void _register_variant_builtin_methods() {
bind_method(PackedInt64Array, remove_at, sarray("index"), varray());
bind_method(PackedInt64Array, insert, sarray("at_index", "value"), varray());
bind_method(PackedInt64Array, fill, sarray("value"), varray());
- bind_method(PackedInt64Array, resize, sarray("new_size"), varray());
+ bind_methodv(PackedInt64Array, resize, &PackedInt64Array::resize_zeroed, sarray("new_size"), varray());
bind_method(PackedInt64Array, has, sarray("value"), varray());
bind_method(PackedInt64Array, reverse, sarray(), varray());
bind_method(PackedInt64Array, slice, sarray("begin", "end"), varray(INT_MAX));
@@ -2084,7 +2176,7 @@ static void _register_variant_builtin_methods() {
bind_method(PackedFloat32Array, remove_at, sarray("index"), varray());
bind_method(PackedFloat32Array, insert, sarray("at_index", "value"), varray());
bind_method(PackedFloat32Array, fill, sarray("value"), varray());
- bind_method(PackedFloat32Array, resize, sarray("new_size"), varray());
+ bind_methodv(PackedFloat32Array, resize, &PackedFloat32Array::resize_zeroed, sarray("new_size"), varray());
bind_method(PackedFloat32Array, has, sarray("value"), varray());
bind_method(PackedFloat32Array, reverse, sarray(), varray());
bind_method(PackedFloat32Array, slice, sarray("begin", "end"), varray(INT_MAX));
@@ -2107,7 +2199,7 @@ static void _register_variant_builtin_methods() {
bind_method(PackedFloat64Array, remove_at, sarray("index"), varray());
bind_method(PackedFloat64Array, insert, sarray("at_index", "value"), varray());
bind_method(PackedFloat64Array, fill, sarray("value"), varray());
- bind_method(PackedFloat64Array, resize, sarray("new_size"), varray());
+ bind_methodv(PackedFloat64Array, resize, &PackedFloat64Array::resize_zeroed, sarray("new_size"), varray());
bind_method(PackedFloat64Array, has, sarray("value"), varray());
bind_method(PackedFloat64Array, reverse, sarray(), varray());
bind_method(PackedFloat64Array, slice, sarray("begin", "end"), varray(INT_MAX));
@@ -2236,6 +2328,19 @@ static void _register_variant_builtin_methods() {
_VariantCall::add_variant_constant(Variant::VECTOR3, "FORWARD", Vector3(0, 0, -1));
_VariantCall::add_variant_constant(Variant::VECTOR3, "BACK", Vector3(0, 0, 1));
+ _VariantCall::add_constant(Variant::VECTOR4, "AXIS_X", Vector4::AXIS_X);
+ _VariantCall::add_constant(Variant::VECTOR4, "AXIS_Y", Vector4::AXIS_Y);
+ _VariantCall::add_constant(Variant::VECTOR4, "AXIS_Z", Vector4::AXIS_Z);
+ _VariantCall::add_constant(Variant::VECTOR4, "AXIS_W", Vector4::AXIS_W);
+
+ _VariantCall::add_enum_constant(Variant::VECTOR4, "Axis", "AXIS_X", Vector4::AXIS_X);
+ _VariantCall::add_enum_constant(Variant::VECTOR4, "Axis", "AXIS_Y", Vector4::AXIS_Y);
+ _VariantCall::add_enum_constant(Variant::VECTOR4, "Axis", "AXIS_Z", Vector4::AXIS_Z);
+ _VariantCall::add_enum_constant(Variant::VECTOR4, "Axis", "AXIS_W", Vector4::AXIS_W);
+ _VariantCall::add_variant_constant(Variant::VECTOR4, "ZERO", Vector4(0, 0, 0, 0));
+ _VariantCall::add_variant_constant(Variant::VECTOR4, "ONE", Vector4(1, 1, 1, 1));
+ _VariantCall::add_variant_constant(Variant::VECTOR4, "INF", Vector4(INFINITY, INFINITY, INFINITY, INFINITY));
+
_VariantCall::add_constant(Variant::VECTOR3I, "AXIS_X", Vector3i::AXIS_X);
_VariantCall::add_constant(Variant::VECTOR3I, "AXIS_Y", Vector3i::AXIS_Y);
_VariantCall::add_constant(Variant::VECTOR3I, "AXIS_Z", Vector3i::AXIS_Z);
@@ -2244,6 +2349,19 @@ static void _register_variant_builtin_methods() {
_VariantCall::add_enum_constant(Variant::VECTOR3I, "Axis", "AXIS_Y", Vector3i::AXIS_Y);
_VariantCall::add_enum_constant(Variant::VECTOR3I, "Axis", "AXIS_Z", Vector3i::AXIS_Z);
+ _VariantCall::add_constant(Variant::VECTOR4I, "AXIS_X", Vector4i::AXIS_X);
+ _VariantCall::add_constant(Variant::VECTOR4I, "AXIS_Y", Vector4i::AXIS_Y);
+ _VariantCall::add_constant(Variant::VECTOR4I, "AXIS_Z", Vector4i::AXIS_Z);
+ _VariantCall::add_constant(Variant::VECTOR4I, "AXIS_W", Vector4i::AXIS_W);
+
+ _VariantCall::add_enum_constant(Variant::VECTOR4I, "Axis", "AXIS_X", Vector4i::AXIS_X);
+ _VariantCall::add_enum_constant(Variant::VECTOR4I, "Axis", "AXIS_Y", Vector4i::AXIS_Y);
+ _VariantCall::add_enum_constant(Variant::VECTOR4I, "Axis", "AXIS_Z", Vector4i::AXIS_Z);
+ _VariantCall::add_enum_constant(Variant::VECTOR4I, "Axis", "AXIS_W", Vector4i::AXIS_W);
+
+ _VariantCall::add_variant_constant(Variant::VECTOR4I, "ZERO", Vector4i(0, 0, 0, 0));
+ _VariantCall::add_variant_constant(Variant::VECTOR4I, "ONE", Vector4i(1, 1, 1, 1));
+
_VariantCall::add_variant_constant(Variant::VECTOR3I, "ZERO", Vector3i(0, 0, 0));
_VariantCall::add_variant_constant(Variant::VECTOR3I, "ONE", Vector3i(1, 1, 1));
_VariantCall::add_variant_constant(Variant::VECTOR3I, "LEFT", Vector3i(-1, 0, 0));
@@ -2321,6 +2439,25 @@ static void _register_variant_builtin_methods() {
_VariantCall::add_variant_constant(Variant::PLANE, "PLANE_XY", Plane(Vector3(0, 0, 1), 0));
_VariantCall::add_variant_constant(Variant::QUATERNION, "IDENTITY", Quaternion(0, 0, 0, 1));
+
+ _VariantCall::add_constant(Variant::PROJECTION, "PLANE_NEAR", Projection::PLANE_NEAR);
+ _VariantCall::add_constant(Variant::PROJECTION, "PLANE_FAR", Projection::PLANE_FAR);
+ _VariantCall::add_constant(Variant::PROJECTION, "PLANE_LEFT", Projection::PLANE_LEFT);
+ _VariantCall::add_constant(Variant::PROJECTION, "PLANE_TOP", Projection::PLANE_TOP);
+ _VariantCall::add_constant(Variant::PROJECTION, "PLANE_RIGHT", Projection::PLANE_RIGHT);
+ _VariantCall::add_constant(Variant::PROJECTION, "PLANE_BOTTOM", Projection::PLANE_BOTTOM);
+
+ _VariantCall::add_enum_constant(Variant::PROJECTION, "Planes", "PLANE_NEAR", Projection::PLANE_NEAR);
+ _VariantCall::add_enum_constant(Variant::PROJECTION, "Planes", "PLANE_FAR", Projection::PLANE_FAR);
+ _VariantCall::add_enum_constant(Variant::PROJECTION, "Planes", "PLANE_LEFT", Projection::PLANE_LEFT);
+ _VariantCall::add_enum_constant(Variant::PROJECTION, "Planes", "PLANE_TOP", Projection::PLANE_TOP);
+ _VariantCall::add_enum_constant(Variant::PROJECTION, "Planes", "PLANE_RIGHT", Projection::PLANE_RIGHT);
+ _VariantCall::add_enum_constant(Variant::PROJECTION, "Planes", "PLANE_BOTTOM", Projection::PLANE_BOTTOM);
+
+ Projection p;
+ _VariantCall::add_variant_constant(Variant::PROJECTION, "IDENTITY", p);
+ p.set_zero();
+ _VariantCall::add_variant_constant(Variant::PROJECTION, "ZERO", p);
}
void Variant::_register_variant_methods() {
diff --git a/core/variant/variant_construct.cpp b/core/variant/variant_construct.cpp
index 78d5433d8c..3a0b6c1bb9 100644
--- a/core/variant/variant_construct.cpp
+++ b/core/variant/variant_construct.cpp
@@ -111,6 +111,16 @@ void Variant::_register_variant_constructors() {
add_constructor<VariantConstructor<Vector3i, Vector3>>(sarray("from"));
add_constructor<VariantConstructor<Vector3i, int64_t, int64_t, int64_t>>(sarray("x", "y", "z"));
+ add_constructor<VariantConstructNoArgs<Vector4>>(sarray());
+ add_constructor<VariantConstructor<Vector4, Vector4>>(sarray("from"));
+ add_constructor<VariantConstructor<Vector4, Vector4i>>(sarray("from"));
+ add_constructor<VariantConstructor<Vector4, double, double, double, double>>(sarray("x", "y", "z", "w"));
+
+ add_constructor<VariantConstructNoArgs<Vector4i>>(sarray());
+ add_constructor<VariantConstructor<Vector4i, Vector4i>>(sarray("from"));
+ add_constructor<VariantConstructor<Vector4i, Vector4>>(sarray("from"));
+ add_constructor<VariantConstructor<Vector4i, int64_t, int64_t, int64_t, int64_t>>(sarray("x", "y", "z", "w"));
+
add_constructor<VariantConstructNoArgs<Transform2D>>(sarray());
add_constructor<VariantConstructor<Transform2D, Transform2D>>(sarray("from"));
add_constructor<VariantConstructor<Transform2D, float, Vector2>>(sarray("rotation", "position"));
@@ -147,6 +157,11 @@ void Variant::_register_variant_constructors() {
add_constructor<VariantConstructor<Transform3D, Transform3D>>(sarray("from"));
add_constructor<VariantConstructor<Transform3D, Basis, Vector3>>(sarray("basis", "origin"));
add_constructor<VariantConstructor<Transform3D, Vector3, Vector3, Vector3, Vector3>>(sarray("x_axis", "y_axis", "z_axis", "origin"));
+ add_constructor<VariantConstructor<Transform3D, Projection>>(sarray("from"));
+
+ add_constructor<VariantConstructNoArgs<Projection>>(sarray());
+ add_constructor<VariantConstructor<Projection, Projection>>(sarray("from"));
+ add_constructor<VariantConstructor<Projection, Transform3D>>(sarray("from"));
add_constructor<VariantConstructNoArgs<Color>>(sarray());
add_constructor<VariantConstructor<Color, Color>>(sarray("from"));
diff --git a/core/variant/variant_construct.h b/core/variant/variant_construct.h
index 638c0136f3..58a0f34c1e 100644
--- a/core/variant/variant_construct.h
+++ b/core/variant/variant_construct.h
@@ -63,12 +63,15 @@ MAKE_PTRCONSTRUCT(Rect2);
MAKE_PTRCONSTRUCT(Rect2i);
MAKE_PTRCONSTRUCT(Vector3);
MAKE_PTRCONSTRUCT(Vector3i);
+MAKE_PTRCONSTRUCT(Vector4);
+MAKE_PTRCONSTRUCT(Vector4i);
MAKE_PTRCONSTRUCT(Transform2D);
MAKE_PTRCONSTRUCT(Plane);
MAKE_PTRCONSTRUCT(Quaternion);
MAKE_PTRCONSTRUCT(AABB);
MAKE_PTRCONSTRUCT(Basis);
MAKE_PTRCONSTRUCT(Transform3D);
+MAKE_PTRCONSTRUCT(Projection);
MAKE_PTRCONSTRUCT(Color);
MAKE_PTRCONSTRUCT(StringName);
MAKE_PTRCONSTRUCT(NodePath);
diff --git a/core/variant/variant_internal.h b/core/variant/variant_internal.h
index e0cfb42e1e..874a183d29 100644
--- a/core/variant/variant_internal.h
+++ b/core/variant/variant_internal.h
@@ -36,6 +36,8 @@
// For use when you want to access the internal pointer of a Variant directly.
// Use with caution. You need to be sure that the type is correct.
class VariantInternal {
+ friend class Variant;
+
public:
// Set type.
_FORCE_INLINE_ static void initialize(Variant *v, Variant::Type p_type) {
@@ -138,6 +140,10 @@ public:
_FORCE_INLINE_ static const Vector3 *get_vector3(const Variant *v) { return reinterpret_cast<const Vector3 *>(v->_data._mem); }
_FORCE_INLINE_ static Vector3i *get_vector3i(Variant *v) { return reinterpret_cast<Vector3i *>(v->_data._mem); }
_FORCE_INLINE_ static const Vector3i *get_vector3i(const Variant *v) { return reinterpret_cast<const Vector3i *>(v->_data._mem); }
+ _FORCE_INLINE_ static Vector4 *get_vector4(Variant *v) { return reinterpret_cast<Vector4 *>(v->_data._mem); }
+ _FORCE_INLINE_ static const Vector4 *get_vector4(const Variant *v) { return reinterpret_cast<const Vector4 *>(v->_data._mem); }
+ _FORCE_INLINE_ static Vector4i *get_vector4i(Variant *v) { return reinterpret_cast<Vector4i *>(v->_data._mem); }
+ _FORCE_INLINE_ static const Vector4i *get_vector4i(const Variant *v) { return reinterpret_cast<const Vector4i *>(v->_data._mem); }
_FORCE_INLINE_ static Transform2D *get_transform2d(Variant *v) { return v->_data._transform2d; }
_FORCE_INLINE_ static const Transform2D *get_transform2d(const Variant *v) { return v->_data._transform2d; }
_FORCE_INLINE_ static Plane *get_plane(Variant *v) { return reinterpret_cast<Plane *>(v->_data._mem); }
@@ -150,6 +156,8 @@ public:
_FORCE_INLINE_ static const Basis *get_basis(const Variant *v) { return v->_data._basis; }
_FORCE_INLINE_ static Transform3D *get_transform(Variant *v) { return v->_data._transform3d; }
_FORCE_INLINE_ static const Transform3D *get_transform(const Variant *v) { return v->_data._transform3d; }
+ _FORCE_INLINE_ static Projection *get_projection(Variant *v) { return v->_data._projection; }
+ _FORCE_INLINE_ static const Projection *get_projection(const Variant *v) { return v->_data._projection; }
// Misc types.
_FORCE_INLINE_ static Color *get_color(Variant *v) { return reinterpret_cast<Color *>(v->_data._mem); }
@@ -209,21 +217,30 @@ public:
}
_FORCE_INLINE_ static void init_transform2d(Variant *v) {
- v->_data._transform2d = memnew(Transform2D);
+ v->_data._transform2d = (Transform2D *)Variant::Pools::_bucket_small.alloc();
+ memnew_placement(v->_data._transform2d, Transform2D);
v->type = Variant::TRANSFORM2D;
}
_FORCE_INLINE_ static void init_aabb(Variant *v) {
- v->_data._aabb = memnew(AABB);
+ v->_data._aabb = (AABB *)Variant::Pools::_bucket_small.alloc();
+ memnew_placement(v->_data._aabb, AABB);
v->type = Variant::AABB;
}
_FORCE_INLINE_ static void init_basis(Variant *v) {
- v->_data._basis = memnew(Basis);
+ v->_data._basis = (Basis *)Variant::Pools::_bucket_medium.alloc();
+ memnew_placement(v->_data._basis, Basis);
v->type = Variant::BASIS;
}
_FORCE_INLINE_ static void init_transform(Variant *v) {
- v->_data._transform3d = memnew(Transform3D);
+ v->_data._transform3d = (Transform3D *)Variant::Pools::_bucket_medium.alloc();
+ memnew_placement(v->_data._transform3d, Transform3D);
v->type = Variant::TRANSFORM3D;
}
+ _FORCE_INLINE_ static void init_projection(Variant *v) {
+ v->_data._projection = (Projection *)Variant::Pools::_bucket_large.alloc();
+ memnew_placement(v->_data._projection, Projection);
+ v->type = Variant::PROJECTION;
+ }
_FORCE_INLINE_ static void init_string_name(Variant *v) {
memnew_placement(v->_data._mem, StringName);
v->type = Variant::STRING_NAME;
@@ -331,12 +348,18 @@ public:
return get_vector3(v);
case Variant::VECTOR3I:
return get_vector3i(v);
+ case Variant::VECTOR4:
+ return get_vector4(v);
+ case Variant::VECTOR4I:
+ return get_vector4i(v);
case Variant::RECT2:
return get_rect2(v);
case Variant::RECT2I:
return get_rect2i(v);
case Variant::TRANSFORM3D:
return get_transform(v);
+ case Variant::PROJECTION:
+ return get_projection(v);
case Variant::TRANSFORM2D:
return get_transform2d(v);
case Variant::QUATERNION:
@@ -409,12 +432,18 @@ public:
return get_vector3(v);
case Variant::VECTOR3I:
return get_vector3i(v);
+ case Variant::VECTOR4:
+ return get_vector4(v);
+ case Variant::VECTOR4I:
+ return get_vector4i(v);
case Variant::RECT2:
return get_rect2(v);
case Variant::RECT2I:
return get_rect2i(v);
case Variant::TRANSFORM3D:
return get_transform(v);
+ case Variant::PROJECTION:
+ return get_projection(v);
case Variant::TRANSFORM2D:
return get_transform2d(v);
case Variant::QUATERNION:
@@ -599,6 +628,17 @@ struct VariantGetInternalPtr<Vector3i> {
};
template <>
+struct VariantGetInternalPtr<Vector4> {
+ static Vector4 *get_ptr(Variant *v) { return VariantInternal::get_vector4(v); }
+ static const Vector4 *get_ptr(const Variant *v) { return VariantInternal::get_vector4(v); }
+};
+
+template <>
+struct VariantGetInternalPtr<Vector4i> {
+ static Vector4i *get_ptr(Variant *v) { return VariantInternal::get_vector4i(v); }
+ static const Vector4i *get_ptr(const Variant *v) { return VariantInternal::get_vector4i(v); }
+};
+template <>
struct VariantGetInternalPtr<Transform2D> {
static Transform2D *get_ptr(Variant *v) { return VariantInternal::get_transform2d(v); }
static const Transform2D *get_ptr(const Variant *v) { return VariantInternal::get_transform2d(v); }
@@ -611,6 +651,12 @@ struct VariantGetInternalPtr<Transform3D> {
};
template <>
+struct VariantGetInternalPtr<Projection> {
+ static Projection *get_ptr(Variant *v) { return VariantInternal::get_projection(v); }
+ static const Projection *get_ptr(const Variant *v) { return VariantInternal::get_projection(v); }
+};
+
+template <>
struct VariantGetInternalPtr<Plane> {
static Plane *get_ptr(Variant *v) { return VariantInternal::get_plane(v); }
static const Plane *get_ptr(const Variant *v) { return VariantInternal::get_plane(v); }
@@ -772,6 +818,10 @@ VARIANT_ACCESSOR_NUMBER(Vector2::Axis)
VARIANT_ACCESSOR_NUMBER(Vector2i::Axis)
VARIANT_ACCESSOR_NUMBER(Vector3::Axis)
VARIANT_ACCESSOR_NUMBER(Vector3i::Axis)
+VARIANT_ACCESSOR_NUMBER(Vector4::Axis)
+VARIANT_ACCESSOR_NUMBER(Vector4i::Axis)
+
+VARIANT_ACCESSOR_NUMBER(Projection::Planes)
template <>
struct VariantInternalAccessor<Basis::EulerOrder> {
@@ -840,6 +890,17 @@ struct VariantInternalAccessor<Vector3i> {
};
template <>
+struct VariantInternalAccessor<Vector4> {
+ static _FORCE_INLINE_ const Vector4 &get(const Variant *v) { return *VariantInternal::get_vector4(v); }
+ static _FORCE_INLINE_ void set(Variant *v, const Vector4 &p_value) { *VariantInternal::get_vector4(v) = p_value; }
+};
+
+template <>
+struct VariantInternalAccessor<Vector4i> {
+ static _FORCE_INLINE_ const Vector4i &get(const Variant *v) { return *VariantInternal::get_vector4i(v); }
+ static _FORCE_INLINE_ void set(Variant *v, const Vector4i &p_value) { *VariantInternal::get_vector4i(v) = p_value; }
+};
+template <>
struct VariantInternalAccessor<Transform2D> {
static _FORCE_INLINE_ const Transform2D &get(const Variant *v) { return *VariantInternal::get_transform2d(v); }
static _FORCE_INLINE_ void set(Variant *v, const Transform2D &p_value) { *VariantInternal::get_transform2d(v) = p_value; }
@@ -852,6 +913,12 @@ struct VariantInternalAccessor<Transform3D> {
};
template <>
+struct VariantInternalAccessor<Projection> {
+ static _FORCE_INLINE_ const Projection &get(const Variant *v) { return *VariantInternal::get_projection(v); }
+ static _FORCE_INLINE_ void set(Variant *v, const Projection &p_value) { *VariantInternal::get_projection(v) = p_value; }
+};
+
+template <>
struct VariantInternalAccessor<Plane> {
static _FORCE_INLINE_ const Plane &get(const Variant *v) { return *VariantInternal::get_plane(v); }
static _FORCE_INLINE_ void set(Variant *v, const Plane &p_value) { *VariantInternal::get_plane(v) = p_value; }
@@ -1041,6 +1108,8 @@ INITIALIZER_INT(Vector2::Axis)
INITIALIZER_INT(Vector2i::Axis)
INITIALIZER_INT(Vector3::Axis)
INITIALIZER_INT(Vector3i::Axis)
+INITIALIZER_INT(Vector4::Axis)
+INITIALIZER_INT(Vector4i::Axis)
template <>
struct VariantInitializer<double> {
@@ -1086,8 +1155,16 @@ template <>
struct VariantInitializer<Vector3i> {
static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Vector3i>(v); }
};
+template <>
+struct VariantInitializer<Vector4> {
+ static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Vector4>(v); }
+};
template <>
+struct VariantInitializer<Vector4i> {
+ static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Vector4i>(v); }
+};
+template <>
struct VariantInitializer<Transform2D> {
static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_transform2d(v); }
};
@@ -1116,6 +1193,10 @@ template <>
struct VariantInitializer<Transform3D> {
static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_transform(v); }
};
+template <>
+struct VariantInitializer<Projection> {
+ static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_projection(v); }
+};
template <>
struct VariantInitializer<Color> {
@@ -1267,6 +1348,16 @@ struct VariantZeroAssigner<Vector3i> {
};
template <>
+struct VariantZeroAssigner<Vector4> {
+ static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_vector4(v) = Vector4(); }
+};
+
+template <>
+struct VariantZeroAssigner<Vector4i> {
+ static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_vector4i(v) = Vector4i(); }
+};
+
+template <>
struct VariantZeroAssigner<Transform2D> {
static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_transform2d(v) = Transform2D(); }
};
@@ -1297,6 +1388,11 @@ struct VariantZeroAssigner<Transform3D> {
};
template <>
+struct VariantZeroAssigner<Projection> {
+ static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_projection(v) = Projection(); }
+};
+
+template <>
struct VariantZeroAssigner<Color> {
static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_color(v) = Color(); }
};
diff --git a/core/variant/variant_op.cpp b/core/variant/variant_op.cpp
index adace2b534..6cca7955ae 100644
--- a/core/variant/variant_op.cpp
+++ b/core/variant/variant_op.cpp
@@ -165,6 +165,70 @@ public:
static Variant::Type get_return_type() { return GetTypeInfo<Vector3>::VARIANT_TYPE; }
};
+//
+
+template <>
+class OperatorEvaluatorMul<Vector4, Vector4i, double> {
+public:
+ static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
+ const Vector4i &a = *VariantGetInternalPtr<Vector4i>::get_ptr(&p_left);
+ const double &b = *VariantGetInternalPtr<double>::get_ptr(&p_right);
+ *r_ret = Vector4(a.x, a.y, a.z, a.w) * b;
+ r_valid = true;
+ }
+ static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
+ *VariantGetInternalPtr<Vector4>::get_ptr(r_ret) = Vector4(VariantGetInternalPtr<Vector4i>::get_ptr(left)->x, VariantGetInternalPtr<Vector4i>::get_ptr(left)->y, VariantGetInternalPtr<Vector4i>::get_ptr(left)->z, VariantGetInternalPtr<Vector4i>::get_ptr(left)->w) * *VariantGetInternalPtr<double>::get_ptr(right);
+ }
+ static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
+ PtrToArg<Vector4>::encode(Vector4(PtrToArg<Vector4i>::convert(left).x, PtrToArg<Vector4i>::convert(left).y, PtrToArg<Vector4i>::convert(left).z, PtrToArg<Vector4i>::convert(left).w) * PtrToArg<double>::convert(right), r_ret);
+ }
+ static Variant::Type get_return_type() { return GetTypeInfo<Vector4>::VARIANT_TYPE; }
+};
+
+template <>
+class OperatorEvaluatorMul<Vector4, double, Vector4i> {
+public:
+ static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
+ const Vector4i &a = *VariantGetInternalPtr<Vector4i>::get_ptr(&p_right);
+ const double &b = *VariantGetInternalPtr<double>::get_ptr(&p_left);
+ *r_ret = Vector4(a.x, a.y, a.z, a.w) * b;
+ r_valid = true;
+ }
+ static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
+ *VariantGetInternalPtr<Vector4>::get_ptr(r_ret) = Vector4(VariantGetInternalPtr<Vector4i>::get_ptr(right)->x, VariantGetInternalPtr<Vector4i>::get_ptr(right)->y, VariantGetInternalPtr<Vector4i>::get_ptr(right)->z, VariantGetInternalPtr<Vector4i>::get_ptr(right)->w) * *VariantGetInternalPtr<double>::get_ptr(left);
+ }
+ static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
+ PtrToArg<Vector4>::encode(Vector4(PtrToArg<Vector4i>::convert(right).x, PtrToArg<Vector4i>::convert(right).y, PtrToArg<Vector4i>::convert(right).z, PtrToArg<Vector4i>::convert(right).w) * PtrToArg<double>::convert(left), r_ret);
+ }
+ static Variant::Type get_return_type() { return GetTypeInfo<Vector4>::VARIANT_TYPE; }
+};
+
+template <>
+class OperatorEvaluatorDivNZ<Vector4, Vector4i, double> {
+public:
+ static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
+ const Vector4i &a = *VariantGetInternalPtr<Vector4i>::get_ptr(&p_left);
+ const double &b = *VariantGetInternalPtr<double>::get_ptr(&p_right);
+ if (unlikely(b == 0)) {
+ r_valid = false;
+ *r_ret = "Division by zero error";
+ return;
+ }
+ *r_ret = Vector4(a.x, a.y, a.z, a.w) / b;
+ r_valid = true;
+ }
+
+ static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
+ *VariantGetInternalPtr<Vector4>::get_ptr(r_ret) = Vector4(VariantGetInternalPtr<Vector4i>::get_ptr(left)->x, VariantGetInternalPtr<Vector4i>::get_ptr(left)->y, VariantGetInternalPtr<Vector4i>::get_ptr(left)->z, VariantGetInternalPtr<Vector4i>::get_ptr(left)->w) / *VariantGetInternalPtr<double>::get_ptr(right);
+ }
+
+ static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
+ PtrToArg<Vector4>::encode(Vector4(PtrToArg<Vector4i>::convert(left).x, PtrToArg<Vector4i>::convert(left).y, PtrToArg<Vector4i>::convert(left).z, PtrToArg<Vector4i>::convert(left).w) / PtrToArg<double>::convert(right), r_ret);
+ }
+
+ static Variant::Type get_return_type() { return GetTypeInfo<Vector4>::VARIANT_TYPE; }
+};
+
void Variant::_register_variant_operators() {
memset(operator_return_type_table, 0, sizeof(operator_return_type_table));
memset(operator_evaluator_table, 0, sizeof(operator_evaluator_table));
@@ -182,6 +246,8 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorAdd<Vector2i, Vector2i, Vector2i>>(Variant::OP_ADD, Variant::VECTOR2I, Variant::VECTOR2I);
register_op<OperatorEvaluatorAdd<Vector3, Vector3, Vector3>>(Variant::OP_ADD, Variant::VECTOR3, Variant::VECTOR3);
register_op<OperatorEvaluatorAdd<Vector3i, Vector3i, Vector3i>>(Variant::OP_ADD, Variant::VECTOR3I, Variant::VECTOR3I);
+ register_op<OperatorEvaluatorAdd<Vector4, Vector4, Vector4>>(Variant::OP_ADD, Variant::VECTOR4, Variant::VECTOR4);
+ register_op<OperatorEvaluatorAdd<Vector4i, Vector4i, Vector4i>>(Variant::OP_ADD, Variant::VECTOR4I, Variant::VECTOR4I);
register_op<OperatorEvaluatorAdd<Quaternion, Quaternion, Quaternion>>(Variant::OP_ADD, Variant::QUATERNION, Variant::QUATERNION);
register_op<OperatorEvaluatorAdd<Color, Color, Color>>(Variant::OP_ADD, Variant::COLOR, Variant::COLOR);
register_op<OperatorEvaluatorAddArray>(Variant::OP_ADD, Variant::ARRAY, Variant::ARRAY);
@@ -203,6 +269,8 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorSub<Vector2i, Vector2i, Vector2i>>(Variant::OP_SUBTRACT, Variant::VECTOR2I, Variant::VECTOR2I);
register_op<OperatorEvaluatorSub<Vector3, Vector3, Vector3>>(Variant::OP_SUBTRACT, Variant::VECTOR3, Variant::VECTOR3);
register_op<OperatorEvaluatorSub<Vector3i, Vector3i, Vector3i>>(Variant::OP_SUBTRACT, Variant::VECTOR3I, Variant::VECTOR3I);
+ register_op<OperatorEvaluatorSub<Vector4, Vector4, Vector4>>(Variant::OP_SUBTRACT, Variant::VECTOR4, Variant::VECTOR4);
+ register_op<OperatorEvaluatorSub<Vector4i, Vector4i, Vector4i>>(Variant::OP_SUBTRACT, Variant::VECTOR4I, Variant::VECTOR4I);
register_op<OperatorEvaluatorSub<Quaternion, Quaternion, Quaternion>>(Variant::OP_SUBTRACT, Variant::QUATERNION, Variant::QUATERNION);
register_op<OperatorEvaluatorSub<Color, Color, Color>>(Variant::OP_SUBTRACT, Variant::COLOR, Variant::COLOR);
@@ -212,6 +280,8 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorMul<Vector2i, int64_t, Vector2i>>(Variant::OP_MULTIPLY, Variant::INT, Variant::VECTOR2I);
register_op<OperatorEvaluatorMul<Vector3, int64_t, Vector3>>(Variant::OP_MULTIPLY, Variant::INT, Variant::VECTOR3);
register_op<OperatorEvaluatorMul<Vector3i, int64_t, Vector3i>>(Variant::OP_MULTIPLY, Variant::INT, Variant::VECTOR3I);
+ register_op<OperatorEvaluatorMul<Vector4, int64_t, Vector4>>(Variant::OP_MULTIPLY, Variant::INT, Variant::VECTOR4);
+ register_op<OperatorEvaluatorMul<Vector4i, int64_t, Vector4i>>(Variant::OP_MULTIPLY, Variant::INT, Variant::VECTOR4I);
register_op<OperatorEvaluatorMul<double, double, double>>(Variant::OP_MULTIPLY, Variant::FLOAT, Variant::FLOAT);
register_op<OperatorEvaluatorMul<double, double, int64_t>>(Variant::OP_MULTIPLY, Variant::FLOAT, Variant::INT);
@@ -219,6 +289,8 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorMul<Vector2, double, Vector2i>>(Variant::OP_MULTIPLY, Variant::FLOAT, Variant::VECTOR2I);
register_op<OperatorEvaluatorMul<Vector3, double, Vector3>>(Variant::OP_MULTIPLY, Variant::FLOAT, Variant::VECTOR3);
register_op<OperatorEvaluatorMul<Vector3, double, Vector3i>>(Variant::OP_MULTIPLY, Variant::FLOAT, Variant::VECTOR3I);
+ register_op<OperatorEvaluatorMul<Vector4, double, Vector4>>(Variant::OP_MULTIPLY, Variant::FLOAT, Variant::VECTOR4);
+ register_op<OperatorEvaluatorMul<Vector4, double, Vector4i>>(Variant::OP_MULTIPLY, Variant::FLOAT, Variant::VECTOR4I);
register_op<OperatorEvaluatorMul<Vector2, Vector2, Vector2>>(Variant::OP_MULTIPLY, Variant::VECTOR2, Variant::VECTOR2);
register_op<OperatorEvaluatorMul<Vector2, Vector2, int64_t>>(Variant::OP_MULTIPLY, Variant::VECTOR2, Variant::INT);
@@ -236,6 +308,14 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorMul<Vector3i, Vector3i, int64_t>>(Variant::OP_MULTIPLY, Variant::VECTOR3I, Variant::INT);
register_op<OperatorEvaluatorMul<Vector3, Vector3i, double>>(Variant::OP_MULTIPLY, Variant::VECTOR3I, Variant::FLOAT);
+ register_op<OperatorEvaluatorMul<Vector4, Vector4, Vector4>>(Variant::OP_MULTIPLY, Variant::VECTOR4, Variant::VECTOR4);
+ register_op<OperatorEvaluatorMul<Vector4, Vector4, int64_t>>(Variant::OP_MULTIPLY, Variant::VECTOR4, Variant::INT);
+ register_op<OperatorEvaluatorMul<Vector4, Vector4, double>>(Variant::OP_MULTIPLY, Variant::VECTOR4, Variant::FLOAT);
+
+ register_op<OperatorEvaluatorMul<Vector4i, Vector4i, Vector4i>>(Variant::OP_MULTIPLY, Variant::VECTOR4I, Variant::VECTOR4I);
+ register_op<OperatorEvaluatorMul<Vector4i, Vector4i, int64_t>>(Variant::OP_MULTIPLY, Variant::VECTOR4I, Variant::INT);
+ register_op<OperatorEvaluatorMul<Vector4, Vector4i, double>>(Variant::OP_MULTIPLY, Variant::VECTOR4I, Variant::FLOAT);
+
register_op<OperatorEvaluatorMul<Quaternion, Quaternion, Quaternion>>(Variant::OP_MULTIPLY, Variant::QUATERNION, Variant::QUATERNION);
register_op<OperatorEvaluatorMul<Quaternion, Quaternion, int64_t>>(Variant::OP_MULTIPLY, Variant::QUATERNION, Variant::INT);
register_op<OperatorEvaluatorMul<Quaternion, Quaternion, double>>(Variant::OP_MULTIPLY, Variant::QUATERNION, Variant::FLOAT);
@@ -261,9 +341,16 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorXFormInv<Vector3, Vector3, Transform3D>>(Variant::OP_MULTIPLY, Variant::VECTOR3, Variant::TRANSFORM3D);
register_op<OperatorEvaluatorXForm<::AABB, Transform3D, ::AABB>>(Variant::OP_MULTIPLY, Variant::TRANSFORM3D, Variant::AABB);
register_op<OperatorEvaluatorXFormInv<::AABB, ::AABB, Transform3D>>(Variant::OP_MULTIPLY, Variant::AABB, Variant::TRANSFORM3D);
+ register_op<OperatorEvaluatorXForm<Plane, Transform3D, Plane>>(Variant::OP_MULTIPLY, Variant::TRANSFORM3D, Variant::PLANE);
+ register_op<OperatorEvaluatorXFormInv<Plane, Plane, Transform3D>>(Variant::OP_MULTIPLY, Variant::PLANE, Variant::TRANSFORM3D);
register_op<OperatorEvaluatorXForm<Vector<Vector3>, Transform3D, Vector<Vector3>>>(Variant::OP_MULTIPLY, Variant::TRANSFORM3D, Variant::PACKED_VECTOR3_ARRAY);
register_op<OperatorEvaluatorXFormInv<Vector<Vector3>, Vector<Vector3>, Transform3D>>(Variant::OP_MULTIPLY, Variant::PACKED_VECTOR3_ARRAY, Variant::TRANSFORM3D);
+ register_op<OperatorEvaluatorXForm<Vector4, Projection, Vector4>>(Variant::OP_MULTIPLY, Variant::PROJECTION, Variant::VECTOR4);
+ register_op<OperatorEvaluatorXFormInv<Vector4, Vector4, Projection>>(Variant::OP_MULTIPLY, Variant::VECTOR4, Variant::PROJECTION);
+
+ register_op<OperatorEvaluatorMul<Projection, Projection, Projection>>(Variant::OP_MULTIPLY, Variant::PROJECTION, Variant::PROJECTION);
+
register_op<OperatorEvaluatorMul<Basis, Basis, Basis>>(Variant::OP_MULTIPLY, Variant::BASIS, Variant::BASIS);
register_op<OperatorEvaluatorMul<Basis, Basis, int64_t>>(Variant::OP_MULTIPLY, Variant::BASIS, Variant::INT);
register_op<OperatorEvaluatorMul<Basis, Basis, double>>(Variant::OP_MULTIPLY, Variant::BASIS, Variant::FLOAT);
@@ -309,6 +396,14 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorDivNZ<Vector3, Vector3i, double>>(Variant::OP_DIVIDE, Variant::VECTOR3I, Variant::FLOAT);
register_op<OperatorEvaluatorDivNZ<Vector3i, Vector3i, int64_t>>(Variant::OP_DIVIDE, Variant::VECTOR3I, Variant::INT);
+ register_op<OperatorEvaluatorDiv<Vector4, Vector4, Vector4>>(Variant::OP_DIVIDE, Variant::VECTOR4, Variant::VECTOR4);
+ register_op<OperatorEvaluatorDiv<Vector4, Vector4, double>>(Variant::OP_DIVIDE, Variant::VECTOR4, Variant::FLOAT);
+ register_op<OperatorEvaluatorDiv<Vector4, Vector4, int64_t>>(Variant::OP_DIVIDE, Variant::VECTOR4, Variant::INT);
+
+ register_op<OperatorEvaluatorDivNZ<Vector4i, Vector4i, Vector4i>>(Variant::OP_DIVIDE, Variant::VECTOR4I, Variant::VECTOR4I);
+ register_op<OperatorEvaluatorDivNZ<Vector4, Vector4i, double>>(Variant::OP_DIVIDE, Variant::VECTOR4I, Variant::FLOAT);
+ register_op<OperatorEvaluatorDivNZ<Vector4i, Vector4i, int64_t>>(Variant::OP_DIVIDE, Variant::VECTOR4I, Variant::INT);
+
register_op<OperatorEvaluatorDiv<Quaternion, Quaternion, double>>(Variant::OP_DIVIDE, Variant::QUATERNION, Variant::FLOAT);
register_op<OperatorEvaluatorDiv<Quaternion, Quaternion, int64_t>>(Variant::OP_DIVIDE, Variant::QUATERNION, Variant::INT);
@@ -323,6 +418,9 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorModNZ<Vector3i, Vector3i, Vector3i>>(Variant::OP_MODULE, Variant::VECTOR3I, Variant::VECTOR3I);
register_op<OperatorEvaluatorModNZ<Vector3i, Vector3i, int64_t>>(Variant::OP_MODULE, Variant::VECTOR3I, Variant::INT);
+ register_op<OperatorEvaluatorModNZ<Vector4i, Vector4i, Vector4i>>(Variant::OP_MODULE, Variant::VECTOR4I, Variant::VECTOR4I);
+ register_op<OperatorEvaluatorModNZ<Vector4i, Vector4i, int64_t>>(Variant::OP_MODULE, Variant::VECTOR4I, Variant::INT);
+
register_op<OperatorEvaluatorStringModNil>(Variant::OP_MODULE, Variant::STRING, Variant::NIL);
register_op<OperatorEvaluatorStringModT<bool>>(Variant::OP_MODULE, Variant::STRING, Variant::BOOL);
@@ -335,12 +433,15 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorStringModT<Rect2i>>(Variant::OP_MODULE, Variant::STRING, Variant::RECT2I);
register_op<OperatorEvaluatorStringModT<Vector3>>(Variant::OP_MODULE, Variant::STRING, Variant::VECTOR3);
register_op<OperatorEvaluatorStringModT<Vector3i>>(Variant::OP_MODULE, Variant::STRING, Variant::VECTOR3I);
+ register_op<OperatorEvaluatorStringModT<Vector4>>(Variant::OP_MODULE, Variant::STRING, Variant::VECTOR4);
+ register_op<OperatorEvaluatorStringModT<Vector4i>>(Variant::OP_MODULE, Variant::STRING, Variant::VECTOR4I);
register_op<OperatorEvaluatorStringModT<Transform2D>>(Variant::OP_MODULE, Variant::STRING, Variant::TRANSFORM2D);
register_op<OperatorEvaluatorStringModT<Plane>>(Variant::OP_MODULE, Variant::STRING, Variant::PLANE);
register_op<OperatorEvaluatorStringModT<Quaternion>>(Variant::OP_MODULE, Variant::STRING, Variant::QUATERNION);
register_op<OperatorEvaluatorStringModT<::AABB>>(Variant::OP_MODULE, Variant::STRING, Variant::AABB);
register_op<OperatorEvaluatorStringModT<Basis>>(Variant::OP_MODULE, Variant::STRING, Variant::BASIS);
register_op<OperatorEvaluatorStringModT<Transform3D>>(Variant::OP_MODULE, Variant::STRING, Variant::TRANSFORM3D);
+ register_op<OperatorEvaluatorStringModT<Projection>>(Variant::OP_MODULE, Variant::STRING, Variant::PROJECTION);
register_op<OperatorEvaluatorStringModT<Color>>(Variant::OP_MODULE, Variant::STRING, Variant::COLOR);
register_op<OperatorEvaluatorStringModT<StringName>>(Variant::OP_MODULE, Variant::STRING, Variant::STRING_NAME);
@@ -372,6 +473,8 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorNeg<Vector2i, Vector2i>>(Variant::OP_NEGATE, Variant::VECTOR2I, Variant::NIL);
register_op<OperatorEvaluatorNeg<Vector3, Vector3>>(Variant::OP_NEGATE, Variant::VECTOR3, Variant::NIL);
register_op<OperatorEvaluatorNeg<Vector3i, Vector3i>>(Variant::OP_NEGATE, Variant::VECTOR3I, Variant::NIL);
+ register_op<OperatorEvaluatorNeg<Vector4, Vector4>>(Variant::OP_NEGATE, Variant::VECTOR4, Variant::NIL);
+ register_op<OperatorEvaluatorNeg<Vector4i, Vector4i>>(Variant::OP_NEGATE, Variant::VECTOR4I, Variant::NIL);
register_op<OperatorEvaluatorNeg<Quaternion, Quaternion>>(Variant::OP_NEGATE, Variant::QUATERNION, Variant::NIL);
register_op<OperatorEvaluatorNeg<Plane, Plane>>(Variant::OP_NEGATE, Variant::PLANE, Variant::NIL);
register_op<OperatorEvaluatorNeg<Color, Color>>(Variant::OP_NEGATE, Variant::COLOR, Variant::NIL);
@@ -382,6 +485,8 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorPos<Vector2i, Vector2i>>(Variant::OP_POSITIVE, Variant::VECTOR2I, Variant::NIL);
register_op<OperatorEvaluatorPos<Vector3, Vector3>>(Variant::OP_POSITIVE, Variant::VECTOR3, Variant::NIL);
register_op<OperatorEvaluatorPos<Vector3i, Vector3i>>(Variant::OP_POSITIVE, Variant::VECTOR3I, Variant::NIL);
+ register_op<OperatorEvaluatorPos<Vector4, Vector4>>(Variant::OP_POSITIVE, Variant::VECTOR4, Variant::NIL);
+ register_op<OperatorEvaluatorPos<Vector4i, Vector4i>>(Variant::OP_POSITIVE, Variant::VECTOR4I, Variant::NIL);
register_op<OperatorEvaluatorPos<Quaternion, Quaternion>>(Variant::OP_POSITIVE, Variant::QUATERNION, Variant::NIL);
register_op<OperatorEvaluatorPos<Plane, Plane>>(Variant::OP_POSITIVE, Variant::PLANE, Variant::NIL);
register_op<OperatorEvaluatorPos<Color, Color>>(Variant::OP_POSITIVE, Variant::COLOR, Variant::NIL);
@@ -409,11 +514,14 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorEqual<Vector3, Vector3>>(Variant::OP_EQUAL, Variant::VECTOR3, Variant::VECTOR3);
register_op<OperatorEvaluatorEqual<Vector3i, Vector3i>>(Variant::OP_EQUAL, Variant::VECTOR3I, Variant::VECTOR3I);
register_op<OperatorEvaluatorEqual<Transform2D, Transform2D>>(Variant::OP_EQUAL, Variant::TRANSFORM2D, Variant::TRANSFORM2D);
+ register_op<OperatorEvaluatorEqual<Vector4, Vector4>>(Variant::OP_EQUAL, Variant::VECTOR4, Variant::VECTOR4);
+ register_op<OperatorEvaluatorEqual<Vector4i, Vector4i>>(Variant::OP_EQUAL, Variant::VECTOR4I, Variant::VECTOR4I);
register_op<OperatorEvaluatorEqual<Plane, Plane>>(Variant::OP_EQUAL, Variant::PLANE, Variant::PLANE);
register_op<OperatorEvaluatorEqual<Quaternion, Quaternion>>(Variant::OP_EQUAL, Variant::QUATERNION, Variant::QUATERNION);
register_op<OperatorEvaluatorEqual<::AABB, ::AABB>>(Variant::OP_EQUAL, Variant::AABB, Variant::AABB);
register_op<OperatorEvaluatorEqual<Basis, Basis>>(Variant::OP_EQUAL, Variant::BASIS, Variant::BASIS);
register_op<OperatorEvaluatorEqual<Transform3D, Transform3D>>(Variant::OP_EQUAL, Variant::TRANSFORM3D, Variant::TRANSFORM3D);
+ register_op<OperatorEvaluatorEqual<Projection, Projection>>(Variant::OP_EQUAL, Variant::PROJECTION, Variant::PROJECTION);
register_op<OperatorEvaluatorEqual<Color, Color>>(Variant::OP_EQUAL, Variant::COLOR, Variant::COLOR);
register_op<OperatorEvaluatorEqual<StringName, String>>(Variant::OP_EQUAL, Variant::STRING_NAME, Variant::STRING);
@@ -451,6 +559,8 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::RECT2I, Variant::NIL>>(Variant::OP_EQUAL, Variant::RECT2I, Variant::NIL);
register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::VECTOR3, Variant::NIL>>(Variant::OP_EQUAL, Variant::VECTOR3, Variant::NIL);
register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::VECTOR3I, Variant::NIL>>(Variant::OP_EQUAL, Variant::VECTOR3I, Variant::NIL);
+ register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::VECTOR4, Variant::NIL>>(Variant::OP_EQUAL, Variant::VECTOR4, Variant::NIL);
+ register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::VECTOR4I, Variant::NIL>>(Variant::OP_EQUAL, Variant::VECTOR4I, Variant::NIL);
register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::TRANSFORM2D, Variant::NIL>>(Variant::OP_EQUAL, Variant::TRANSFORM2D, Variant::NIL);
register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::PLANE, Variant::NIL>>(Variant::OP_EQUAL, Variant::PLANE, Variant::NIL);
register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::QUATERNION, Variant::NIL>>(Variant::OP_EQUAL, Variant::QUATERNION, Variant::NIL);
@@ -485,6 +595,8 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::NIL, Variant::RECT2I>>(Variant::OP_EQUAL, Variant::NIL, Variant::RECT2I);
register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::NIL, Variant::VECTOR3>>(Variant::OP_EQUAL, Variant::NIL, Variant::VECTOR3);
register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::NIL, Variant::VECTOR3I>>(Variant::OP_EQUAL, Variant::NIL, Variant::VECTOR3I);
+ register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::NIL, Variant::VECTOR4>>(Variant::OP_EQUAL, Variant::NIL, Variant::VECTOR4);
+ register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::NIL, Variant::VECTOR4I>>(Variant::OP_EQUAL, Variant::NIL, Variant::VECTOR4I);
register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::NIL, Variant::TRANSFORM2D>>(Variant::OP_EQUAL, Variant::NIL, Variant::TRANSFORM2D);
register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::NIL, Variant::PLANE>>(Variant::OP_EQUAL, Variant::NIL, Variant::PLANE);
register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::NIL, Variant::QUATERNION>>(Variant::OP_EQUAL, Variant::NIL, Variant::QUATERNION);
@@ -522,12 +634,15 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorNotEqual<Rect2i, Rect2i>>(Variant::OP_NOT_EQUAL, Variant::RECT2I, Variant::RECT2I);
register_op<OperatorEvaluatorNotEqual<Vector3, Vector3>>(Variant::OP_NOT_EQUAL, Variant::VECTOR3, Variant::VECTOR3);
register_op<OperatorEvaluatorNotEqual<Vector3i, Vector3i>>(Variant::OP_NOT_EQUAL, Variant::VECTOR3I, Variant::VECTOR3I);
+ register_op<OperatorEvaluatorNotEqual<Vector4, Vector4>>(Variant::OP_NOT_EQUAL, Variant::VECTOR4, Variant::VECTOR4);
+ register_op<OperatorEvaluatorNotEqual<Vector4i, Vector4i>>(Variant::OP_NOT_EQUAL, Variant::VECTOR4I, Variant::VECTOR4I);
register_op<OperatorEvaluatorNotEqual<Transform2D, Transform2D>>(Variant::OP_NOT_EQUAL, Variant::TRANSFORM2D, Variant::TRANSFORM2D);
register_op<OperatorEvaluatorNotEqual<Plane, Plane>>(Variant::OP_NOT_EQUAL, Variant::PLANE, Variant::PLANE);
register_op<OperatorEvaluatorNotEqual<Quaternion, Quaternion>>(Variant::OP_NOT_EQUAL, Variant::QUATERNION, Variant::QUATERNION);
register_op<OperatorEvaluatorNotEqual<::AABB, ::AABB>>(Variant::OP_NOT_EQUAL, Variant::AABB, Variant::AABB);
register_op<OperatorEvaluatorNotEqual<Basis, Basis>>(Variant::OP_NOT_EQUAL, Variant::BASIS, Variant::BASIS);
register_op<OperatorEvaluatorNotEqual<Transform3D, Transform3D>>(Variant::OP_NOT_EQUAL, Variant::TRANSFORM3D, Variant::TRANSFORM3D);
+ register_op<OperatorEvaluatorNotEqual<Projection, Projection>>(Variant::OP_NOT_EQUAL, Variant::PROJECTION, Variant::PROJECTION);
register_op<OperatorEvaluatorNotEqual<Color, Color>>(Variant::OP_NOT_EQUAL, Variant::COLOR, Variant::COLOR);
register_op<OperatorEvaluatorNotEqual<StringName, String>>(Variant::OP_NOT_EQUAL, Variant::STRING_NAME, Variant::STRING);
@@ -566,6 +681,8 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::VECTOR3, Variant::NIL>>(Variant::OP_NOT_EQUAL, Variant::VECTOR3, Variant::NIL);
register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::VECTOR3I, Variant::NIL>>(Variant::OP_NOT_EQUAL, Variant::VECTOR3I, Variant::NIL);
register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::TRANSFORM2D, Variant::NIL>>(Variant::OP_NOT_EQUAL, Variant::TRANSFORM2D, Variant::NIL);
+ register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::VECTOR4, Variant::NIL>>(Variant::OP_NOT_EQUAL, Variant::VECTOR4, Variant::NIL);
+ register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::VECTOR4I, Variant::NIL>>(Variant::OP_NOT_EQUAL, Variant::VECTOR4I, Variant::NIL);
register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::PLANE, Variant::NIL>>(Variant::OP_NOT_EQUAL, Variant::PLANE, Variant::NIL);
register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::QUATERNION, Variant::NIL>>(Variant::OP_NOT_EQUAL, Variant::QUATERNION, Variant::NIL);
register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::AABB, Variant::NIL>>(Variant::OP_NOT_EQUAL, Variant::AABB, Variant::NIL);
@@ -599,6 +716,8 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::NIL, Variant::RECT2I>>(Variant::OP_NOT_EQUAL, Variant::NIL, Variant::RECT2I);
register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::NIL, Variant::VECTOR3>>(Variant::OP_NOT_EQUAL, Variant::NIL, Variant::VECTOR3);
register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::NIL, Variant::VECTOR3I>>(Variant::OP_NOT_EQUAL, Variant::NIL, Variant::VECTOR3I);
+ register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::NIL, Variant::VECTOR4>>(Variant::OP_NOT_EQUAL, Variant::NIL, Variant::VECTOR4);
+ register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::NIL, Variant::VECTOR4I>>(Variant::OP_NOT_EQUAL, Variant::NIL, Variant::VECTOR4I);
register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::NIL, Variant::TRANSFORM2D>>(Variant::OP_NOT_EQUAL, Variant::NIL, Variant::TRANSFORM2D);
register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::NIL, Variant::PLANE>>(Variant::OP_NOT_EQUAL, Variant::NIL, Variant::PLANE);
register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::NIL, Variant::QUATERNION>>(Variant::OP_NOT_EQUAL, Variant::NIL, Variant::QUATERNION);
@@ -634,6 +753,8 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorLess<Vector2i, Vector2i>>(Variant::OP_LESS, Variant::VECTOR2I, Variant::VECTOR2I);
register_op<OperatorEvaluatorLess<Vector3, Vector3>>(Variant::OP_LESS, Variant::VECTOR3, Variant::VECTOR3);
register_op<OperatorEvaluatorLess<Vector3i, Vector3i>>(Variant::OP_LESS, Variant::VECTOR3I, Variant::VECTOR3I);
+ register_op<OperatorEvaluatorLess<Vector4, Vector4>>(Variant::OP_LESS, Variant::VECTOR4, Variant::VECTOR4);
+ register_op<OperatorEvaluatorLess<Vector4i, Vector4i>>(Variant::OP_LESS, Variant::VECTOR4I, Variant::VECTOR4I);
register_op<OperatorEvaluatorLess<::RID, ::RID>>(Variant::OP_LESS, Variant::RID, Variant::RID);
register_op<OperatorEvaluatorLess<Array, Array>>(Variant::OP_LESS, Variant::ARRAY, Variant::ARRAY);
@@ -647,6 +768,8 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorLessEqual<Vector2i, Vector2i>>(Variant::OP_LESS_EQUAL, Variant::VECTOR2I, Variant::VECTOR2I);
register_op<OperatorEvaluatorLessEqual<Vector3, Vector3>>(Variant::OP_LESS_EQUAL, Variant::VECTOR3, Variant::VECTOR3);
register_op<OperatorEvaluatorLessEqual<Vector3i, Vector3i>>(Variant::OP_LESS_EQUAL, Variant::VECTOR3I, Variant::VECTOR3I);
+ register_op<OperatorEvaluatorLessEqual<Vector4, Vector4>>(Variant::OP_LESS_EQUAL, Variant::VECTOR4, Variant::VECTOR4);
+ register_op<OperatorEvaluatorLessEqual<Vector4i, Vector4i>>(Variant::OP_LESS_EQUAL, Variant::VECTOR4I, Variant::VECTOR4I);
register_op<OperatorEvaluatorLessEqual<::RID, ::RID>>(Variant::OP_LESS_EQUAL, Variant::RID, Variant::RID);
register_op<OperatorEvaluatorLessEqual<Array, Array>>(Variant::OP_LESS_EQUAL, Variant::ARRAY, Variant::ARRAY);
@@ -661,6 +784,8 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorGreater<Vector2i, Vector2i>>(Variant::OP_GREATER, Variant::VECTOR2I, Variant::VECTOR2I);
register_op<OperatorEvaluatorGreater<Vector3, Vector3>>(Variant::OP_GREATER, Variant::VECTOR3, Variant::VECTOR3);
register_op<OperatorEvaluatorGreater<Vector3i, Vector3i>>(Variant::OP_GREATER, Variant::VECTOR3I, Variant::VECTOR3I);
+ register_op<OperatorEvaluatorGreater<Vector4, Vector4>>(Variant::OP_GREATER, Variant::VECTOR4, Variant::VECTOR4);
+ register_op<OperatorEvaluatorGreater<Vector4i, Vector4i>>(Variant::OP_GREATER, Variant::VECTOR4I, Variant::VECTOR4I);
register_op<OperatorEvaluatorGreater<::RID, ::RID>>(Variant::OP_GREATER, Variant::RID, Variant::RID);
register_op<OperatorEvaluatorGreater<Array, Array>>(Variant::OP_GREATER, Variant::ARRAY, Variant::ARRAY);
@@ -674,6 +799,8 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorGreaterEqual<Vector2i, Vector2i>>(Variant::OP_GREATER_EQUAL, Variant::VECTOR2I, Variant::VECTOR2I);
register_op<OperatorEvaluatorGreaterEqual<Vector3, Vector3>>(Variant::OP_GREATER_EQUAL, Variant::VECTOR3, Variant::VECTOR3);
register_op<OperatorEvaluatorGreaterEqual<Vector3i, Vector3i>>(Variant::OP_GREATER_EQUAL, Variant::VECTOR3I, Variant::VECTOR3I);
+ register_op<OperatorEvaluatorGreaterEqual<Vector4, Vector4>>(Variant::OP_GREATER_EQUAL, Variant::VECTOR4, Variant::VECTOR4);
+ register_op<OperatorEvaluatorGreaterEqual<Vector4i, Vector4i>>(Variant::OP_GREATER_EQUAL, Variant::VECTOR4I, Variant::VECTOR4I);
register_op<OperatorEvaluatorGreaterEqual<::RID, ::RID>>(Variant::OP_GREATER_EQUAL, Variant::RID, Variant::RID);
register_op<OperatorEvaluatorGreaterEqual<Array, Array>>(Variant::OP_GREATER_EQUAL, Variant::ARRAY, Variant::ARRAY);
@@ -788,12 +915,15 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorInDictionaryHas<Rect2i>>(Variant::OP_IN, Variant::RECT2I, Variant::DICTIONARY);
register_op<OperatorEvaluatorInDictionaryHas<Vector3>>(Variant::OP_IN, Variant::VECTOR3, Variant::DICTIONARY);
register_op<OperatorEvaluatorInDictionaryHas<Vector3i>>(Variant::OP_IN, Variant::VECTOR3I, Variant::DICTIONARY);
+ register_op<OperatorEvaluatorInDictionaryHas<Vector4>>(Variant::OP_IN, Variant::VECTOR4, Variant::DICTIONARY);
+ register_op<OperatorEvaluatorInDictionaryHas<Vector4i>>(Variant::OP_IN, Variant::VECTOR4I, Variant::DICTIONARY);
register_op<OperatorEvaluatorInDictionaryHas<Transform2D>>(Variant::OP_IN, Variant::TRANSFORM2D, Variant::DICTIONARY);
register_op<OperatorEvaluatorInDictionaryHas<Plane>>(Variant::OP_IN, Variant::PLANE, Variant::DICTIONARY);
register_op<OperatorEvaluatorInDictionaryHas<Quaternion>>(Variant::OP_IN, Variant::QUATERNION, Variant::DICTIONARY);
register_op<OperatorEvaluatorInDictionaryHas<::AABB>>(Variant::OP_IN, Variant::AABB, Variant::DICTIONARY);
register_op<OperatorEvaluatorInDictionaryHas<Basis>>(Variant::OP_IN, Variant::BASIS, Variant::DICTIONARY);
register_op<OperatorEvaluatorInDictionaryHas<Transform3D>>(Variant::OP_IN, Variant::TRANSFORM3D, Variant::DICTIONARY);
+ register_op<OperatorEvaluatorInDictionaryHas<Projection>>(Variant::OP_IN, Variant::PROJECTION, Variant::DICTIONARY);
register_op<OperatorEvaluatorInDictionaryHas<Color>>(Variant::OP_IN, Variant::COLOR, Variant::DICTIONARY);
register_op<OperatorEvaluatorInDictionaryHas<StringName>>(Variant::OP_IN, Variant::STRING_NAME, Variant::DICTIONARY);
@@ -825,12 +955,15 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorInArrayFind<Rect2i, Array>>(Variant::OP_IN, Variant::RECT2I, Variant::ARRAY);
register_op<OperatorEvaluatorInArrayFind<Vector3, Array>>(Variant::OP_IN, Variant::VECTOR3, Variant::ARRAY);
register_op<OperatorEvaluatorInArrayFind<Vector3i, Array>>(Variant::OP_IN, Variant::VECTOR3I, Variant::ARRAY);
+ register_op<OperatorEvaluatorInArrayFind<Vector4, Array>>(Variant::OP_IN, Variant::VECTOR4, Variant::ARRAY);
+ register_op<OperatorEvaluatorInArrayFind<Vector4i, Array>>(Variant::OP_IN, Variant::VECTOR4I, Variant::ARRAY);
register_op<OperatorEvaluatorInArrayFind<Transform2D, Array>>(Variant::OP_IN, Variant::TRANSFORM2D, Variant::ARRAY);
register_op<OperatorEvaluatorInArrayFind<Plane, Array>>(Variant::OP_IN, Variant::PLANE, Variant::ARRAY);
register_op<OperatorEvaluatorInArrayFind<Quaternion, Array>>(Variant::OP_IN, Variant::QUATERNION, Variant::ARRAY);
register_op<OperatorEvaluatorInArrayFind<::AABB, Array>>(Variant::OP_IN, Variant::AABB, Variant::ARRAY);
register_op<OperatorEvaluatorInArrayFind<Basis, Array>>(Variant::OP_IN, Variant::BASIS, Variant::ARRAY);
register_op<OperatorEvaluatorInArrayFind<Transform3D, Array>>(Variant::OP_IN, Variant::TRANSFORM3D, Variant::ARRAY);
+ register_op<OperatorEvaluatorInArrayFind<Projection, Array>>(Variant::OP_IN, Variant::PROJECTION, Variant::ARRAY);
register_op<OperatorEvaluatorInArrayFind<Color, Array>>(Variant::OP_IN, Variant::COLOR, Variant::ARRAY);
register_op<OperatorEvaluatorInArrayFind<StringName, Array>>(Variant::OP_IN, Variant::STRING_NAME, Variant::ARRAY);
diff --git a/core/variant/variant_op.h b/core/variant/variant_op.h
index 3e9bae1078..ec1ce67445 100644
--- a/core/variant/variant_op.h
+++ b/core/variant/variant_op.h
@@ -234,6 +234,30 @@ public:
static Variant::Type get_return_type() { return GetTypeInfo<Vector3i>::VARIANT_TYPE; }
};
+template <>
+class OperatorEvaluatorDivNZ<Vector4i, Vector4i, Vector4i> {
+public:
+ static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
+ const Vector4i &a = *VariantGetInternalPtr<Vector4i>::get_ptr(&p_left);
+ const Vector4i &b = *VariantGetInternalPtr<Vector4i>::get_ptr(&p_right);
+ if (unlikely(b.x == 0 || b.y == 0 || b.z == 0 || b.w == 0)) {
+ r_valid = false;
+ *r_ret = "Division by zero error";
+ return;
+ }
+ *r_ret = a / b;
+ r_valid = true;
+ }
+ static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
+ VariantTypeChanger<Vector4i>::change(r_ret);
+ *VariantGetInternalPtr<Vector4i>::get_ptr(r_ret) = *VariantGetInternalPtr<Vector4i>::get_ptr(left) / *VariantGetInternalPtr<Vector4i>::get_ptr(right);
+ }
+ static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
+ PtrToArg<Vector4i>::encode(PtrToArg<Vector4i>::convert(left) / PtrToArg<Vector4i>::convert(right), r_ret);
+ }
+ static Variant::Type get_return_type() { return GetTypeInfo<Vector4i>::VARIANT_TYPE; }
+};
+
template <class R, class A, class B>
class OperatorEvaluatorMod {
public:
@@ -323,6 +347,30 @@ public:
static Variant::Type get_return_type() { return GetTypeInfo<Vector3i>::VARIANT_TYPE; }
};
+template <>
+class OperatorEvaluatorModNZ<Vector4i, Vector4i, Vector4i> {
+public:
+ static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
+ const Vector4i &a = *VariantGetInternalPtr<Vector4i>::get_ptr(&p_left);
+ const Vector4i &b = *VariantGetInternalPtr<Vector4i>::get_ptr(&p_right);
+ if (unlikely(b.x == 0 || b.y == 0 || b.z == 0 || b.w == 0)) {
+ r_valid = false;
+ *r_ret = "Module by zero error";
+ return;
+ }
+ *r_ret = a % b;
+ r_valid = true;
+ }
+ static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
+ VariantTypeChanger<Vector4i>::change(r_ret);
+ *VariantGetInternalPtr<Vector4i>::get_ptr(r_ret) = *VariantGetInternalPtr<Vector4i>::get_ptr(left) % *VariantGetInternalPtr<Vector4i>::get_ptr(right);
+ }
+ static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
+ PtrToArg<Vector4i>::encode(PtrToArg<Vector4i>::convert(left) % PtrToArg<Vector4i>::convert(right), r_ret);
+ }
+ static Variant::Type get_return_type() { return GetTypeInfo<Vector4i>::VARIANT_TYPE; }
+};
+
template <class R, class A>
class OperatorEvaluatorNeg {
public:
diff --git a/core/variant/variant_parser.cpp b/core/variant/variant_parser.cpp
index 259ca8a60d..34653310b1 100644
--- a/core/variant/variant_parser.cpp
+++ b/core/variant/variant_parser.cpp
@@ -649,6 +649,32 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
}
value = Vector3i(args[0], args[1], args[2]);
+ } else if (id == "Vector4") {
+ Vector<real_t> args;
+ Error err = _parse_construct<real_t>(p_stream, args, line, r_err_str);
+ if (err) {
+ return err;
+ }
+
+ if (args.size() != 4) {
+ r_err_str = "Expected 4 arguments for constructor";
+ return ERR_PARSE_ERROR;
+ }
+
+ value = Vector4(args[0], args[1], args[2], args[3]);
+ } else if (id == "Vector4i") {
+ Vector<int32_t> args;
+ Error err = _parse_construct<int32_t>(p_stream, args, line, r_err_str);
+ if (err) {
+ return err;
+ }
+
+ if (args.size() != 4) {
+ r_err_str = "Expected 4 arguments for constructor";
+ return ERR_PARSE_ERROR;
+ }
+
+ value = Vector4i(args[0], args[1], args[2], args[3]);
} else if (id == "Transform2D" || id == "Matrix32") { //compatibility
Vector<real_t> args;
Error err = _parse_construct<real_t>(p_stream, args, line, r_err_str);
@@ -731,6 +757,19 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
}
value = Transform3D(Basis(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]), Vector3(args[9], args[10], args[11]));
+ } else if (id == "Projection") { // "Transform" kept for compatibility with Godot <4.
+ Vector<real_t> args;
+ Error err = _parse_construct<real_t>(p_stream, args, line, r_err_str);
+ if (err) {
+ return err;
+ }
+
+ if (args.size() != 16) {
+ r_err_str = "Expected 16 arguments for constructor";
+ return ERR_PARSE_ERROR;
+ }
+
+ value = Projection(Vector4(args[0], args[1], args[2], args[3]), Vector4(args[4], args[5], args[6], args[7]), Vector4(args[8], args[9], args[10], args[11]), Vector4(args[12], args[13], args[14], args[15]));
} else if (id == "Color") {
Vector<float> args;
Error err = _parse_construct<float>(p_stream, args, line, r_err_str);
@@ -1534,6 +1573,14 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
Vector3i v = p_variant;
p_store_string_func(p_store_string_ud, "Vector3i(" + itos(v.x) + ", " + itos(v.y) + ", " + itos(v.z) + ")");
} break;
+ case Variant::VECTOR4: {
+ Vector4 v = p_variant;
+ p_store_string_func(p_store_string_ud, "Vector4(" + rtos_fix(v.x) + ", " + rtos_fix(v.y) + ", " + rtos_fix(v.z) + ", " + rtos_fix(v.w) + ")");
+ } break;
+ case Variant::VECTOR4I: {
+ Vector4i v = p_variant;
+ p_store_string_func(p_store_string_ud, "Vector4i(" + itos(v.x) + ", " + itos(v.y) + ", " + itos(v.z) + ", " + itos(v.w) + ")");
+ } break;
case Variant::PLANE: {
Plane p = p_variant;
p_store_string_func(p_store_string_ud, "Plane(" + rtos_fix(p.normal.x) + ", " + rtos_fix(p.normal.y) + ", " + rtos_fix(p.normal.z) + ", " + rtos_fix(p.d) + ")");
@@ -1596,6 +1643,20 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
p_store_string_func(p_store_string_ud, s + ")");
} break;
+ case Variant::PROJECTION: {
+ String s = "Projection(";
+ Projection t = p_variant;
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ if (i != 0 || j != 0) {
+ s += ", ";
+ }
+ s += rtos_fix(t.matrix[i][j]);
+ }
+ }
+
+ p_store_string_func(p_store_string_ud, s + ")");
+ } break;
// misc types
case Variant::COLOR: {
diff --git a/core/variant/variant_setget.cpp b/core/variant/variant_setget.cpp
index 3839da495f..57b953f7f0 100644
--- a/core/variant/variant_setget.cpp
+++ b/core/variant/variant_setget.cpp
@@ -77,6 +77,16 @@ void register_named_setters_getters() {
REGISTER_MEMBER(Vector3i, y);
REGISTER_MEMBER(Vector3i, z);
+ REGISTER_MEMBER(Vector4, x);
+ REGISTER_MEMBER(Vector4, y);
+ REGISTER_MEMBER(Vector4, z);
+ REGISTER_MEMBER(Vector4, w);
+
+ REGISTER_MEMBER(Vector4i, x);
+ REGISTER_MEMBER(Vector4i, y);
+ REGISTER_MEMBER(Vector4i, z);
+ REGISTER_MEMBER(Vector4i, w);
+
REGISTER_MEMBER(Rect2, position);
REGISTER_MEMBER(Rect2, size);
REGISTER_MEMBER(Rect2, end);
@@ -111,6 +121,11 @@ void register_named_setters_getters() {
REGISTER_MEMBER(Transform3D, basis);
REGISTER_MEMBER(Transform3D, origin);
+ REGISTER_MEMBER(Projection, x);
+ REGISTER_MEMBER(Projection, y);
+ REGISTER_MEMBER(Projection, z);
+ REGISTER_MEMBER(Projection, w);
+
REGISTER_MEMBER(Color, r);
REGISTER_MEMBER(Color, g);
REGISTER_MEMBER(Color, b);
@@ -804,11 +819,14 @@ INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Vector2, double, real_t, 2)
INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Vector2i, int64_t, int32_t, 2)
INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Vector3, double, real_t, 3)
INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Vector3i, int64_t, int32_t, 3)
+INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Vector4, double, real_t, 4)
+INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Vector4i, int64_t, int32_t, 4)
INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Quaternion, double, real_t, 4)
INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Color, double, float, 4)
INDEXED_SETGET_STRUCT_BULTIN_ACCESSOR(Transform2D, Vector2, .columns, 3)
INDEXED_SETGET_STRUCT_BULTIN_FUNC(Basis, Vector3, set_column, get_column, 3)
+INDEXED_SETGET_STRUCT_BULTIN_ACCESSOR(Projection, Vector4, .matrix, 4)
INDEXED_SETGET_STRUCT_TYPED_NUMERIC(PackedByteArray, int64_t, uint8_t)
INDEXED_SETGET_STRUCT_TYPED_NUMERIC(PackedInt32Array, int64_t, int32_t)
@@ -867,10 +885,13 @@ void register_indexed_setters_getters() {
REGISTER_INDEXED_MEMBER(Vector2i);
REGISTER_INDEXED_MEMBER(Vector3);
REGISTER_INDEXED_MEMBER(Vector3i);
+ REGISTER_INDEXED_MEMBER(Vector4);
+ REGISTER_INDEXED_MEMBER(Vector4i);
REGISTER_INDEXED_MEMBER(Quaternion);
REGISTER_INDEXED_MEMBER(Color);
REGISTER_INDEXED_MEMBER(Transform2D);
REGISTER_INDEXED_MEMBER(Basis);
+ REGISTER_INDEXED_MEMBER(Projection);
REGISTER_INDEXED_MEMBER(PackedByteArray);
REGISTER_INDEXED_MEMBER(PackedInt32Array);
diff --git a/core/variant/variant_setget.h b/core/variant/variant_setget.h
index bc4dc4b408..570277dc7a 100644
--- a/core/variant/variant_setget.h
+++ b/core/variant/variant_setget.h
@@ -281,6 +281,16 @@ SETGET_NUMBER_STRUCT(Vector3i, int64_t, x)
SETGET_NUMBER_STRUCT(Vector3i, int64_t, y)
SETGET_NUMBER_STRUCT(Vector3i, int64_t, z)
+SETGET_NUMBER_STRUCT(Vector4, double, x)
+SETGET_NUMBER_STRUCT(Vector4, double, y)
+SETGET_NUMBER_STRUCT(Vector4, double, z)
+SETGET_NUMBER_STRUCT(Vector4, double, w)
+
+SETGET_NUMBER_STRUCT(Vector4i, int64_t, x)
+SETGET_NUMBER_STRUCT(Vector4i, int64_t, y)
+SETGET_NUMBER_STRUCT(Vector4i, int64_t, z)
+SETGET_NUMBER_STRUCT(Vector4i, int64_t, w)
+
SETGET_STRUCT(Rect2, Vector2, position)
SETGET_STRUCT(Rect2, Vector2, size)
SETGET_STRUCT_FUNC(Rect2, Vector2, end, set_end, get_end)
@@ -315,6 +325,11 @@ SETGET_STRUCT_FUNC_INDEX(Basis, Vector3, z, set_column, get_column, 2)
SETGET_STRUCT(Transform3D, Basis, basis)
SETGET_STRUCT(Transform3D, Vector3, origin)
+SETGET_STRUCT_CUSTOM(Projection, Vector4, x, matrix[0])
+SETGET_STRUCT_CUSTOM(Projection, Vector4, y, matrix[1])
+SETGET_STRUCT_CUSTOM(Projection, Vector4, z, matrix[2])
+SETGET_STRUCT_CUSTOM(Projection, Vector4, w, matrix[3])
+
SETGET_NUMBER_STRUCT(Color, double, r)
SETGET_NUMBER_STRUCT(Color, double, g)
SETGET_NUMBER_STRUCT(Color, double, b)
diff --git a/core/variant/variant_utility.cpp b/core/variant/variant_utility.cpp
index 2bca5f8284..1f1439ab24 100644
--- a/core/variant/variant_utility.cpp
+++ b/core/variant/variant_utility.cpp
@@ -99,18 +99,105 @@ struct VariantUtilityFunctions {
return Math::posmod(b, r);
}
- static inline double floor(double x) {
+ static inline Variant floor(Variant x, Callable::CallError &r_error) {
+ r_error.error = Callable::CallError::CALL_OK;
+ switch (x.get_type()) {
+ case Variant::INT: {
+ return VariantInternalAccessor<int64_t>::get(&x);
+ } break;
+ case Variant::FLOAT: {
+ return Math::floor(VariantInternalAccessor<double>::get(&x));
+ } break;
+ case Variant::VECTOR2: {
+ return VariantInternalAccessor<Vector2>::get(&x).floor();
+ } break;
+ case Variant::VECTOR3: {
+ return VariantInternalAccessor<Vector3>::get(&x).floor();
+ } break;
+ case Variant::VECTOR4: {
+ return VariantInternalAccessor<Vector4>::get(&x).floor();
+ } break;
+ default: {
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
+ return Variant();
+ }
+ }
+ }
+
+ static inline double floorf(double x) {
return Math::floor(x);
}
- static inline double ceil(double x) {
+ static inline int floori(double x) {
+ return int(x);
+ }
+
+ static inline Variant ceil(Variant x, Callable::CallError &r_error) {
+ r_error.error = Callable::CallError::CALL_OK;
+ switch (x.get_type()) {
+ case Variant::INT: {
+ return VariantInternalAccessor<int64_t>::get(&x);
+ } break;
+ case Variant::FLOAT: {
+ return Math::ceil(VariantInternalAccessor<double>::get(&x));
+ } break;
+ case Variant::VECTOR2: {
+ return VariantInternalAccessor<Vector2>::get(&x).ceil();
+ } break;
+ case Variant::VECTOR3: {
+ return VariantInternalAccessor<Vector3>::get(&x).ceil();
+ } break;
+ case Variant::VECTOR4: {
+ return VariantInternalAccessor<Vector4>::get(&x).ceil();
+ } break;
+ default: {
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
+ return Variant();
+ }
+ }
+ }
+
+ static inline double ceilf(double x) {
return Math::ceil(x);
}
- static inline double round(double x) {
+ static inline int ceili(double x) {
+ return int(Math::ceil(x));
+ }
+
+ static inline Variant round(Variant x, Callable::CallError &r_error) {
+ r_error.error = Callable::CallError::CALL_OK;
+ switch (x.get_type()) {
+ case Variant::INT: {
+ return VariantInternalAccessor<int64_t>::get(&x);
+ } break;
+ case Variant::FLOAT: {
+ return Math::round(VariantInternalAccessor<double>::get(&x));
+ } break;
+ case Variant::VECTOR2: {
+ return VariantInternalAccessor<Vector2>::get(&x).round();
+ } break;
+ case Variant::VECTOR3: {
+ return VariantInternalAccessor<Vector3>::get(&x).round();
+ } break;
+ case Variant::VECTOR4: {
+ return VariantInternalAccessor<Vector4>::get(&x).round();
+ } break;
+ default: {
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
+ return Variant();
+ }
+ }
+ }
+
+ static inline double roundf(double x) {
return Math::round(x);
}
+ static inline int roundi(double x) {
+ return int(Math::round(x));
+ }
+
static inline Variant abs(const Variant &x, Callable::CallError &r_error) {
r_error.error = Callable::CallError::CALL_OK;
switch (x.get_type()) {
@@ -132,6 +219,12 @@ struct VariantUtilityFunctions {
case Variant::VECTOR3I: {
return VariantInternalAccessor<Vector3i>::get(&x).abs();
} break;
+ case Variant::VECTOR4: {
+ return VariantInternalAccessor<Vector4>::get(&x).abs();
+ } break;
+ case Variant::VECTOR4I: {
+ return VariantInternalAccessor<Vector4i>::get(&x).abs();
+ } break;
default: {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
return Variant();
@@ -168,6 +261,12 @@ struct VariantUtilityFunctions {
case Variant::VECTOR3I: {
return VariantInternalAccessor<Vector3i>::get(&x).sign();
} break;
+ case Variant::VECTOR4: {
+ return VariantInternalAccessor<Vector4>::get(&x).sign();
+ } break;
+ case Variant::VECTOR4I: {
+ return VariantInternalAccessor<Vector4i>::get(&x).sign();
+ } break;
default: {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
return Variant();
@@ -223,7 +322,44 @@ struct VariantUtilityFunctions {
return Math::snapped(value, step);
}
- static inline double lerp(double from, double to, double weight) {
+ static inline Variant lerp(const Variant &from, const Variant &to, double weight, Callable::CallError &r_error) {
+ r_error.error = Callable::CallError::CALL_OK;
+ if (from.get_type() != to.get_type()) {
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.argument = 1;
+ return Variant();
+ }
+
+ switch (from.get_type()) {
+ case Variant::FLOAT: {
+ return lerpf(VariantInternalAccessor<double>::get(&from), to, weight);
+ } break;
+ case Variant::VECTOR2: {
+ return VariantInternalAccessor<Vector2>::get(&from).lerp(VariantInternalAccessor<Vector2>::get(&to), weight);
+ } break;
+ case Variant::VECTOR3: {
+ return VariantInternalAccessor<Vector3>::get(&from).lerp(VariantInternalAccessor<Vector3>::get(&to), weight);
+ } break;
+ case Variant::VECTOR4: {
+ return VariantInternalAccessor<Vector4>::get(&from).lerp(VariantInternalAccessor<Vector4>::get(&to), weight);
+ } break;
+ case Variant::QUATERNION: {
+ return VariantInternalAccessor<Quaternion>::get(&from).slerp(VariantInternalAccessor<Quaternion>::get(&to), weight);
+ } break;
+ case Variant::BASIS: {
+ return VariantInternalAccessor<Basis>::get(&from).slerp(VariantInternalAccessor<Basis>::get(&to), weight);
+ } break;
+ case Variant::COLOR: {
+ return VariantInternalAccessor<Color>::get(&from).lerp(VariantInternalAccessor<Color>::get(&to), weight);
+ } break;
+ default: {
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
+ return Variant();
+ }
+ }
+ }
+
+ static inline double lerpf(double from, double to, double weight) {
return Math::lerp(from, to, weight);
}
@@ -1240,17 +1376,24 @@ void Variant::_register_variant_utility_functions() {
FUNCBINDR(fmod, sarray("x", "y"), Variant::UTILITY_FUNC_TYPE_MATH);
FUNCBINDR(fposmod, sarray("x", "y"), Variant::UTILITY_FUNC_TYPE_MATH);
FUNCBINDR(posmod, sarray("x", "y"), Variant::UTILITY_FUNC_TYPE_MATH);
- FUNCBINDR(floor, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH);
- FUNCBINDR(ceil, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH);
- FUNCBINDR(round, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH);
- FUNCBINDVR(abs, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH);
+ FUNCBINDVR(floor, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH);
+ FUNCBINDR(floorf, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH);
+ FUNCBINDR(floori, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH);
+
+ FUNCBINDVR(ceil, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH);
+ FUNCBINDR(ceilf, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH);
+ FUNCBINDR(ceili, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH);
+ FUNCBINDVR(round, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH);
+ FUNCBINDR(roundf, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH);
+ FUNCBINDR(roundi, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH);
+
+ FUNCBINDVR(abs, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH);
FUNCBINDR(absf, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH);
FUNCBINDR(absi, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH);
FUNCBINDVR(sign, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH);
-
FUNCBINDR(signf, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH);
FUNCBINDR(signi, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH);
@@ -1268,7 +1411,8 @@ void Variant::_register_variant_utility_functions() {
FUNCBINDR(step_decimals, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH);
FUNCBINDR(snapped, sarray("x", "step"), Variant::UTILITY_FUNC_TYPE_MATH);
- FUNCBINDR(lerp, sarray("from", "to", "weight"), Variant::UTILITY_FUNC_TYPE_MATH);
+ FUNCBINDVR3(lerp, sarray("from", "to", "weight"), Variant::UTILITY_FUNC_TYPE_MATH);
+ FUNCBINDR(lerpf, sarray("from", "to", "weight"), Variant::UTILITY_FUNC_TYPE_MATH);
FUNCBINDR(cubic_interpolate, sarray("from", "to", "pre", "post", "weight"), Variant::UTILITY_FUNC_TYPE_MATH);
FUNCBINDR(bezier_interpolate, sarray("start", "control_1", "control_2", "end", "t"), Variant::UTILITY_FUNC_TYPE_MATH);
FUNCBINDR(lerp_angle, sarray("from", "to", "weight"), Variant::UTILITY_FUNC_TYPE_MATH);
@@ -1288,12 +1432,10 @@ void Variant::_register_variant_utility_functions() {
FUNCBINDR(wrapf, sarray("value", "min", "max"), Variant::UTILITY_FUNC_TYPE_MATH);
FUNCBINDVARARG(max, sarray(), Variant::UTILITY_FUNC_TYPE_MATH);
-
FUNCBINDR(maxi, sarray("a", "b"), Variant::UTILITY_FUNC_TYPE_MATH);
FUNCBINDR(maxf, sarray("a", "b"), Variant::UTILITY_FUNC_TYPE_MATH);
FUNCBINDVARARG(min, sarray(), Variant::UTILITY_FUNC_TYPE_MATH);
-
FUNCBINDR(mini, sarray("a", "b"), Variant::UTILITY_FUNC_TYPE_MATH);
FUNCBINDR(minf, sarray("a", "b"), Variant::UTILITY_FUNC_TYPE_MATH);