summaryrefslogtreecommitdiff
path: root/core/variant.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/variant.cpp')
-rw-r--r--core/variant.cpp187
1 files changed, 182 insertions, 5 deletions
diff --git a/core/variant.cpp b/core/variant.cpp
index 103c8f6746..132d7a1c88 100644
--- a/core/variant.cpp
+++ b/core/variant.cpp
@@ -28,6 +28,7 @@
/*************************************************************************/
#include "variant.h"
+#include "math_funcs.h"
#include "resource.h"
#include "print_string.h"
#include "scene/main/node.h"
@@ -2674,14 +2675,10 @@ uint32_t Variant::hash() const {
case INT: {
return _data._int;
-
} break;
case REAL: {
- MarshallFloat mf;
- mf.f=_data._real;
- return mf.i;
-
+ return hash_djb2_one_float(_data._real);
} break;
case STRING: {
@@ -2921,6 +2918,186 @@ uint32_t Variant::hash() const {
}
+#define hash_compare_scalar(p_lhs, p_rhs)\
+ ((p_lhs) == (p_rhs)) || (Math::is_nan(p_lhs) == Math::is_nan(p_rhs))
+
+#define hash_compare_vector2(p_lhs, p_rhs)\
+ (hash_compare_scalar((p_lhs).x, (p_rhs).x)) && \
+ (hash_compare_scalar((p_lhs).y, (p_rhs).y))
+
+#define hash_compare_vector3(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))
+
+#define hash_compare_quat(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_color(p_lhs, p_rhs)\
+ (hash_compare_scalar((p_lhs).r, (p_rhs).r)) && \
+ (hash_compare_scalar((p_lhs).g, (p_rhs).g)) && \
+ (hash_compare_scalar((p_lhs).b, (p_rhs).b)) && \
+ (hash_compare_scalar((p_lhs).a, (p_rhs).a))
+
+#define hash_compare_pool_array(p_lhs, p_rhs, p_type, p_compare_func)\
+ const PoolVector<p_type>& l = *reinterpret_cast<const PoolVector<p_type>*>(p_lhs);\
+ const PoolVector<p_type>& r = *reinterpret_cast<const PoolVector<p_type>*>(p_rhs);\
+ \
+ if(l.size() != r.size()) \
+ return false; \
+ \
+ PoolVector<p_type>::Read lr = l.read(); \
+ PoolVector<p_type>::Read rr = r.read(); \
+ \
+ for(int i = 0; i < l.size(); ++i) { \
+ if(! p_compare_func((lr[0]), (rr[0]))) \
+ return false; \
+ }\
+ \
+ return true
+
+bool Variant::hash_compare(const Variant& p_variant) const {
+ if (type != p_variant.type)
+ return false;
+
+ switch( type ) {
+ case REAL: {
+ return hash_compare_scalar(_data._real, p_variant._data._real);
+ } break;
+
+ case VECTOR2: {
+ const Vector2* l = reinterpret_cast<const Vector2*>(_data._mem);
+ const Vector2* r = reinterpret_cast<const Vector2*>(p_variant._data._mem);
+
+ return hash_compare_vector2(*l, *r);
+ } break;
+
+ case RECT2: {
+ const Rect2* l = reinterpret_cast<const Rect2*>(_data._mem);
+ const Rect2* r = reinterpret_cast<const Rect2*>(p_variant._data._mem);
+
+ return (hash_compare_vector2(l->pos, r->pos)) &&
+ (hash_compare_vector2(l->size, r->size));
+ } break;
+
+ case TRANSFORM2D: {
+ Transform2D* l = _data._transform2d;
+ Transform2D* r = p_variant._data._transform2d;
+
+ for(int i=0;i<3;i++) {
+ if (! (hash_compare_vector2(l->elements[i], r->elements[i])))
+ return false;
+ }
+
+ return true;
+ } break;
+
+ case VECTOR3: {
+ const Vector3* l = reinterpret_cast<const Vector3*>(_data._mem);
+ const Vector3* r = reinterpret_cast<const Vector3*>(p_variant._data._mem);
+
+ return hash_compare_vector3(*l, *r);
+ } break;
+
+ case PLANE: {
+ const Plane* l = reinterpret_cast<const Plane*>(_data._mem);
+ const Plane* r = reinterpret_cast<const Plane*>(p_variant._data._mem);
+
+ return (hash_compare_vector3(l->normal, r->normal)) &&
+ (hash_compare_scalar(l->d, r->d));
+ } break;
+
+ case RECT3: {
+ const Rect3* l = _data._rect3;
+ const Rect3* r = p_variant._data._rect3;
+
+ return (hash_compare_vector3(l->pos, r->pos) &&
+ (hash_compare_vector3(l->size, r->size)));
+
+ } break;
+
+ case QUAT: {
+ const Quat* l = reinterpret_cast<const Quat*>(_data._mem);
+ const Quat* r = reinterpret_cast<const Quat*>(p_variant._data._mem);
+
+ return hash_compare_quat(*l, *r);
+ } break;
+
+ case BASIS: {
+ const Basis* l = _data._basis;
+ const Basis* r = p_variant._data._basis;
+
+ for(int i=0;i<3;i++) {
+ if (! (hash_compare_vector3(l->elements[i], r->elements[i])))
+ return false;
+ }
+
+ return true;
+ } break;
+
+ case TRANSFORM: {
+ const Transform* l = _data._transform;
+ const Transform* r = p_variant._data._transform;
+
+ for(int i=0;i<3;i++) {
+ if (! (hash_compare_vector3(l->basis.elements[i], r->basis.elements[i])))
+ return false;
+ }
+
+ return hash_compare_vector3(l->origin, r->origin);
+ } break;
+
+ case COLOR: {
+ const Color* l = reinterpret_cast<const Color*>(_data._mem);
+ const Color* r = reinterpret_cast<const Color*>(p_variant._data._mem);
+
+ return hash_compare_color(*l, *r);
+ } break;
+
+ case ARRAY: {
+ const Array& l = *(reinterpret_cast<const Array*>(_data._mem));
+ const Array& r = *(reinterpret_cast<const Array*>(p_variant._data._mem));
+
+ if(l.size() != r.size())
+ return false;
+
+ for(int i = 0; i < l.size(); ++i) {
+ if(! l[0].hash_compare(r[0]))
+ return false;
+ }
+
+ return true;
+ } break;
+
+ case POOL_REAL_ARRAY: {
+ hash_compare_pool_array(_data._mem, p_variant._data._mem, real_t, hash_compare_scalar);
+ } break;
+
+ case POOL_VECTOR2_ARRAY: {
+ hash_compare_pool_array(_data._mem, p_variant._data._mem, Vector2, hash_compare_vector2);
+ } break;
+
+ case POOL_VECTOR3_ARRAY: {
+ hash_compare_pool_array(_data._mem, p_variant._data._mem, Vector3, hash_compare_vector3);
+ } break;
+
+ case POOL_COLOR_ARRAY: {
+ hash_compare_pool_array(_data._mem, p_variant._data._mem, Color, hash_compare_color);
+ } break;
+
+ default:
+ bool v;
+ Variant r;
+ evaluate(OP_EQUAL,*this,p_variant,r,v);
+ return r;
+ }
+
+ return false;
+}
+
bool Variant::is_ref() const {