diff --git a/Source/Engine/Core/Math/Math.h b/Source/Engine/Core/Math/Math.h index 84ecd4599..f5baa53ee 100644 --- a/Source/Engine/Core/Math/Math.h +++ b/Source/Engine/Core/Math/Math.h @@ -17,6 +17,7 @@ // The value for which all absolute numbers smaller than are considered equal to zero. #define ZeroTolerance 1e-6f +#define ZeroToleranceDouble 1e-16 // Converts radians to degrees. #define RadiansToDegrees (180.0f / PI) diff --git a/Source/Engine/Core/Math/Mathd.h b/Source/Engine/Core/Math/Mathd.h index 128e0a3d9..79be4cf65 100644 --- a/Source/Engine/Core/Math/Mathd.h +++ b/Source/Engine/Core/Math/Mathd.h @@ -227,7 +227,7 @@ namespace Math /// False if a almost equal to b, otherwise true static bool NotNearEqual(double a, double b) { - return Abs(a - b) >= 2 * 2.2204460492503131e-016; + return Abs(a - b) >= ZeroToleranceDouble; } /// @@ -238,7 +238,7 @@ namespace Math /// True if a almost equal to b, otherwise false static bool NearEqual(double a, double b) { - return Abs(a - b) < 2 * 2.2204460492503131e-016; + return Abs(a - b) < ZeroToleranceDouble; } /// diff --git a/Source/Engine/Core/Types/BaseTypes.h b/Source/Engine/Core/Types/BaseTypes.h index a6a6ec630..7011b9920 100644 --- a/Source/Engine/Core/Types/BaseTypes.h +++ b/Source/Engine/Core/Types/BaseTypes.h @@ -72,6 +72,9 @@ struct TimeSpan; struct Vector2; struct Vector3; struct Vector4; +struct Double2; +struct Double3; +struct Double4; struct Int2; struct Int3; struct Int4; diff --git a/Source/Engine/Serialization/JsonWriter.cpp b/Source/Engine/Serialization/JsonWriter.cpp index bcced9d30..693dfe67f 100644 --- a/Source/Engine/Serialization/JsonWriter.cpp +++ b/Source/Engine/Serialization/JsonWriter.cpp @@ -4,6 +4,9 @@ #include "Engine/Core/Log.h" #include "Engine/Core/Types/CommonValue.h" #include "Engine/Content/Content.h" +#include "Engine/Core/Math/Double2.h" +#include "Engine/Core/Math/Double3.h" +#include "Engine/Core/Math/Double4.h" #include "Engine/Core/Math/Int2.h" #include "Engine/Core/Math/Int3.h" #include "Engine/Core/Math/Int4.h" @@ -63,6 +66,42 @@ void JsonWriter::Vector4(const ::Vector4& value) EndObject(); } +void JsonWriter::Double2(const ::Double2& value) +{ + StartObject(); + JKEY("X"); + Double(value.X); + JKEY("Y"); + Double(value.Y); + EndObject(); +} + +void JsonWriter::Double3(const ::Double3& value) +{ + StartObject(); + JKEY("X"); + Double(value.X); + JKEY("Y"); + Double(value.Y); + JKEY("Z"); + Double(value.Z); + EndObject(); +} + +void JsonWriter::Double4(const ::Double4& value) +{ + StartObject(); + JKEY("X"); + Double(value.X); + JKEY("Y"); + Double(value.Y); + JKEY("Z"); + Double(value.Z); + JKEY("W"); + Double(value.W); + EndObject(); +} + void JsonWriter::Int2(const ::Int2& value) { StartObject(); diff --git a/Source/Engine/Serialization/JsonWriter.h b/Source/Engine/Serialization/JsonWriter.h index d8a0acb8d..b6c564bd0 100644 --- a/Source/Engine/Serialization/JsonWriter.h +++ b/Source/Engine/Serialization/JsonWriter.h @@ -110,6 +110,9 @@ public: void Vector2(const Vector2& value); void Vector3(const Vector3& value); void Vector4(const Vector4& value); + void Double2(const Double2& value); + void Double3(const Double3& value); + void Double4(const Double4& value); void Int2(const Int2& value); void Int3(const Int3& value); void Int4(const Int4& value); diff --git a/Source/Engine/Serialization/Serialization.cpp b/Source/Engine/Serialization/Serialization.cpp index 447871f1d..b8070b14a 100644 --- a/Source/Engine/Serialization/Serialization.cpp +++ b/Source/Engine/Serialization/Serialization.cpp @@ -10,6 +10,9 @@ #include "Engine/Core/Math/Vector2.h" #include "Engine/Core/Math/Vector3.h" #include "Engine/Core/Math/Vector4.h" +#include "Engine/Core/Math/Double2.h" +#include "Engine/Core/Math/Double3.h" +#include "Engine/Core/Math/Double4.h" #include "Engine/Core/Math/Quaternion.h" #include "Engine/Core/Math/BoundingBox.h" #include "Engine/Core/Math/BoundingSphere.h" @@ -528,6 +531,51 @@ void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Vector v.W = mW != stream.MemberEnd() ? mW->value.GetFloat() : 0.0f; } +bool Serialization::ShouldSerialize(const Double2& v, const void* otherObj) +{ + return !otherObj || !Double2::NearEqual(v, *(Double2*)otherObj, SERIALIZE_EPSILON_DOUBLE); +} + +void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Double2& v, ISerializeModifier* modifier) +{ + const auto mX = SERIALIZE_FIND_MEMBER(stream, "X"); + const auto mY = SERIALIZE_FIND_MEMBER(stream, "Y"); + v.X = mX != stream.MemberEnd() ? mX->value.GetFloat() : 0.0f; + v.Y = mY != stream.MemberEnd() ? mY->value.GetFloat() : 0.0f; +} + +bool Serialization::ShouldSerialize(const Double3& v, const void* otherObj) +{ + return !otherObj || !Double3::NearEqual(v, *(Double3*)otherObj, SERIALIZE_EPSILON_DOUBLE); +} + +void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Double3& v, ISerializeModifier* modifier) +{ + const auto mX = SERIALIZE_FIND_MEMBER(stream, "X"); + const auto mY = SERIALIZE_FIND_MEMBER(stream, "Y"); + const auto mZ = SERIALIZE_FIND_MEMBER(stream, "Z"); + v.X = mX != stream.MemberEnd() ? mX->value.GetFloat() : 0.0f; + v.Y = mY != stream.MemberEnd() ? mY->value.GetFloat() : 0.0f; + v.Z = mZ != stream.MemberEnd() ? mZ->value.GetFloat() : 0.0f; +} + +bool Serialization::ShouldSerialize(const Double4& v, const void* otherObj) +{ + return !otherObj || !Double4::NearEqual(v, *(Double4*)otherObj, SERIALIZE_EPSILON_DOUBLE); +} + +void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Double4& v, ISerializeModifier* modifier) +{ + const auto mX = SERIALIZE_FIND_MEMBER(stream, "X"); + const auto mY = SERIALIZE_FIND_MEMBER(stream, "Y"); + const auto mZ = SERIALIZE_FIND_MEMBER(stream, "Z"); + const auto mW = SERIALIZE_FIND_MEMBER(stream, "W"); + v.X = mX != stream.MemberEnd() ? mX->value.GetFloat() : 0.0f; + v.Y = mY != stream.MemberEnd() ? mY->value.GetFloat() : 0.0f; + v.Z = mZ != stream.MemberEnd() ? mZ->value.GetFloat() : 0.0f; + v.W = mW != stream.MemberEnd() ? mW->value.GetFloat() : 0.0f; +} + bool Serialization::ShouldSerialize(const Int2& v, const void* otherObj) { return !otherObj || !(v == *(Int2*)otherObj); diff --git a/Source/Engine/Serialization/Serialization.h b/Source/Engine/Serialization/Serialization.h index 6db037ac8..14e61831a 100644 --- a/Source/Engine/Serialization/Serialization.h +++ b/Source/Engine/Serialization/Serialization.h @@ -184,7 +184,7 @@ namespace Serialization inline bool ShouldSerialize(const float& v, const void* otherObj) { - return !otherObj || abs(v - *(float*)otherObj) > SERIALIZE_EPSILON; + return !otherObj || fabsf(v - *(float*)otherObj) > SERIALIZE_EPSILON; } inline void Serialize(ISerializable::SerializeStream& stream, const float& v, const void* otherObj) { @@ -197,7 +197,7 @@ namespace Serialization inline bool ShouldSerialize(const double& v, const void* otherObj) { - return !otherObj || v != *(double*)otherObj; + return !otherObj || fabs(v - *(double*)otherObj) > SERIALIZE_EPSILON_DOUBLE; } inline void Serialize(ISerializable::SerializeStream& stream, const double& v, const void* otherObj) { @@ -301,6 +301,27 @@ namespace Serialization } FLAXENGINE_API void Deserialize(ISerializable::DeserializeStream& stream, Vector4& v, ISerializeModifier* modifier); + FLAXENGINE_API bool ShouldSerialize(const Double2& v, const void* otherObj); + inline void Serialize(ISerializable::SerializeStream& stream, const Double2& v, const void* otherObj) + { + stream.Double2(v); + } + FLAXENGINE_API void Deserialize(ISerializable::DeserializeStream& stream, Double2& v, ISerializeModifier* modifier); + + FLAXENGINE_API bool ShouldSerialize(const Double3& v, const void* otherObj); + inline void Serialize(ISerializable::SerializeStream& stream, const Double3& v, const void* otherObj) + { + stream.Double3(v); + } + FLAXENGINE_API void Deserialize(ISerializable::DeserializeStream& stream, Double3& v, ISerializeModifier* modifier); + + FLAXENGINE_API bool ShouldSerialize(const Double4& v, const void* otherObj); + inline void Serialize(ISerializable::SerializeStream& stream, const Double4& v, const void* otherObj) + { + stream.Double4(v); + } + FLAXENGINE_API void Deserialize(ISerializable::DeserializeStream& stream, Double4& v, ISerializeModifier* modifier); + FLAXENGINE_API bool ShouldSerialize(const Int2& v, const void* otherObj); inline void Serialize(ISerializable::SerializeStream& stream, const Int2& v, const void* otherObj) { diff --git a/Source/Engine/Serialization/SerializationFwd.h b/Source/Engine/Serialization/SerializationFwd.h index d679f2746..d9ef2600f 100644 --- a/Source/Engine/Serialization/SerializationFwd.h +++ b/Source/Engine/Serialization/SerializationFwd.h @@ -8,7 +8,8 @@ #include "JsonWriter.h" // The floating-point values serialization epsilon for equality checks precision -#define SERIALIZE_EPSILON 0.0000001f +#define SERIALIZE_EPSILON 1e-7f +#define SERIALIZE_EPSILON_DOUBLE 1e-17 // Helper macro to cast object on diff serialization #define SERIALIZE_GET_OTHER_OBJ(type) const auto other = static_cast(otherObj)