diff --git a/Source/Editor/Utilities/Utils.cs b/Source/Editor/Utilities/Utils.cs index b5c835d70..6c7aa86d7 100644 --- a/Source/Editor/Utilities/Utils.cs +++ b/Source/Editor/Utilities/Utils.cs @@ -67,6 +67,10 @@ namespace FlaxEditor.Utilities Dictionary, ManagedObject, Typename, + + Int2, + Int3, + Int4 } /// @@ -446,6 +450,12 @@ namespace FlaxEditor.Utilities variantType = VariantType.Vector3; else if (type == typeof(Vector4)) variantType = VariantType.Vector4; + else if (type == typeof(Int2)) + variantType = VariantType.Int2; + else if (type == typeof(Int3)) + variantType = VariantType.Int3; + else if (type == typeof(Int4)) + variantType = VariantType.Int4; else if (type == typeof(Color)) variantType = VariantType.Color; else if (type == typeof(Guid)) @@ -682,6 +692,21 @@ namespace FlaxEditor.Utilities new Vector3(stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle())); break; } + case 19: // CommonType::Int2 + { + value = stream.ReadInt2(); + break; + } + case 20: // CommonType::Int3 + { + value = stream.ReadInt3(); + break; + } + case 21: // CommonType::Int4 + { + value = stream.ReadInt4(); + break; + } default: throw new SystemException(); } } @@ -733,6 +758,9 @@ namespace FlaxEditor.Utilities case VariantType.Vector2: return new ScriptType(typeof(Vector2)); case VariantType.Vector3: return new ScriptType(typeof(Vector3)); case VariantType.Vector4: return new ScriptType(typeof(Vector4)); + case VariantType.Int2: return new ScriptType(typeof(Int2)); + case VariantType.Int3: return new ScriptType(typeof(Int3)); + case VariantType.Int4: return new ScriptType(typeof(Int4)); case VariantType.Color: return new ScriptType(typeof(Color)); case VariantType.Guid: return new ScriptType(typeof(Guid)); case VariantType.BoundingBox: return new ScriptType(typeof(BoundingBox)); @@ -797,6 +825,9 @@ namespace FlaxEditor.Utilities case VariantType.Vector2: return typeof(Vector2); case VariantType.Vector3: return typeof(Vector3); case VariantType.Vector4: return typeof(Vector4); + case VariantType.Int2: return typeof(Int2); + case VariantType.Int3: return typeof(Int3); + case VariantType.Int4: return typeof(Int4); case VariantType.Color: return typeof(Color); case VariantType.Guid: return typeof(Guid); case VariantType.BoundingBox: return typeof(BoundingBox); @@ -894,6 +925,9 @@ namespace FlaxEditor.Utilities case VariantType.Vector2: return stream.ReadVector2(); case VariantType.Vector3: return stream.ReadVector3(); case VariantType.Vector4: return stream.ReadVector4(); + case VariantType.Int2: return stream.ReadInt2(); + case VariantType.Int3: return stream.ReadInt3(); + case VariantType.Int4: return stream.ReadInt4(); case VariantType.Color: return stream.ReadColor(); case VariantType.Guid: return stream.ReadGuid(); case VariantType.BoundingBox: return stream.ReadBoundingBox(); @@ -1087,6 +1121,21 @@ namespace FlaxEditor.Utilities stream.Write(asRay.Direction.Y); stream.Write(asRay.Direction.Z); } + else if (value is Int2 asInt2) + { + stream.Write((byte)19); + stream.Write(asInt2); + } + else if (value is Int3 asInt3) + { + stream.Write((byte)20); + stream.Write(asInt3); + } + else if (value is Int4 asInt4) + { + stream.Write((byte)21); + stream.Write(asInt4); + } else { throw new NotSupportedException(string.Format("Invalid Common Value type {0}", value != null ? value.GetType().ToString() : "null")); @@ -1194,6 +1243,15 @@ namespace FlaxEditor.Utilities case VariantType.Vector4: stream.Write((Vector4)value); break; + case VariantType.Int2: + stream.Write((Int2)value); + break; + case VariantType.Int3: + stream.Write((Int3)value); + break; + case VariantType.Int4: + stream.Write((Int4)value); + break; case VariantType.Color: stream.Write((Color)value); break; @@ -1386,6 +1444,51 @@ namespace FlaxEditor.Utilities stream.WriteEndObject(); break; } + case VariantType.Int2: + { + var asInt2 = (Int2)value; + stream.WriteStartObject(); + + stream.WritePropertyName("X"); + stream.WriteValue(asInt2.X); + stream.WritePropertyName("Y"); + stream.WriteValue(asInt2.Y); + + stream.WriteEndObject(); + break; + } + case VariantType.Int3: + { + var asInt3 = (Int3)value; + stream.WriteStartObject(); + + stream.WritePropertyName("X"); + stream.WriteValue(asInt3.X); + stream.WritePropertyName("Y"); + stream.WriteValue(asInt3.Y); + stream.WritePropertyName("Z"); + stream.WriteValue(asInt3.Z); + + stream.WriteEndObject(); + break; + } + case VariantType.Int4: + { + var asInt4 = (Int4)value; + stream.WriteStartObject(); + + stream.WritePropertyName("X"); + stream.WriteValue(asInt4.X); + stream.WritePropertyName("Y"); + stream.WriteValue(asInt4.Y); + stream.WritePropertyName("Z"); + stream.WriteValue(asInt4.Z); + stream.WritePropertyName("W"); + stream.WriteValue(asInt4.W); + + stream.WriteEndObject(); + break; + } case VariantType.Color: { var asColor = (Color)value; diff --git a/Source/Engine/Core/Math/Int2.cpp b/Source/Engine/Core/Math/Int2.cpp new file mode 100644 index 000000000..1293d23ac --- /dev/null +++ b/Source/Engine/Core/Math/Int2.cpp @@ -0,0 +1,51 @@ +// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. + +#include "Int2.h" +#include "Int3.h" +#include "Int4.h" +#include "Vector2.h" +#include "Vector3.h" +#include "Vector4.h" +#include "Engine/Core/Types/String.h" + +static_assert(sizeof(Int2) == 8, "Invalid Int2 type size."); + +const Int2 Int2::Zero(0); +const Int2 Int2::One(1); +const Int2 Int2::Minimum(MIN_int32); +const Int2 Int2::Maximum(MAX_int32); + +Int2::Int2(const Int3& xyz) + : X(xyz.X) + , Y(xyz.Y) +{ +} + +Int2::Int2(const Int4& xyzw) + : X(xyzw.X) + , Y(xyzw.Y) +{ +} + +Int2::Int2(const Vector2& xy) + : X(static_cast(xy.X)) + , Y(static_cast(xy.Y)) +{ +} + +Int2::Int2(const Vector3& xyz) + : X(static_cast(xyz.X)) + , Y(static_cast(xyz.Y)) +{ +} + +Int2::Int2(const Vector4& xyzw) + : X(static_cast(xyzw.X)) + , Y(static_cast(xyzw.Y)) +{ +} + +String Int2::ToString() const +{ + return String::Format(TEXT("{}"), *this); +} diff --git a/Source/Engine/Core/Math/Int2.cs b/Source/Engine/Core/Math/Int2.cs index 0bf38e95f..a063e1bbf 100644 --- a/Source/Engine/Core/Math/Int2.cs +++ b/Source/Engine/Core/Math/Int2.cs @@ -12,9 +12,8 @@ namespace FlaxEngine /// Represents a two dimensional mathematical vector (signed integers). /// [Serializable] - [StructLayout(LayoutKind.Sequential, Pack = 4)] [TypeConverter(typeof(TypeConverters.Int2Converter))] - public struct Int2 : IEquatable, IFormattable + partial struct Int2 : IEquatable, IFormattable { private static readonly string _formatString = "X:{0} Y:{1}"; @@ -53,16 +52,6 @@ namespace FlaxEngine /// public static readonly Int2 Maximum = new Int2(int.MaxValue); - /// - /// The X component of the vector. - /// - public int X; - - /// - /// The Y component of the vector. - /// - public int Y; - /// /// Initializes a new instance of the struct. /// diff --git a/Source/Engine/Core/Math/Int2.h b/Source/Engine/Core/Math/Int2.h index a6038d1b0..236768254 100644 --- a/Source/Engine/Core/Math/Int2.h +++ b/Source/Engine/Core/Math/Int2.h @@ -6,26 +6,27 @@ #include "Engine/Core/Formatting.h" #include "Engine/Core/Templates.h" -struct Vector2; -struct Vector3; -struct Vector4; - /// /// Two-components vector (32 bit integer type). /// -API_STRUCT(InBuild) struct FLAXENGINE_API Int2 +API_STRUCT() struct FLAXENGINE_API Int2 { +DECLARE_SCRIPTING_TYPE_MINIMAL(Int2); public: union { struct { - // X component - int32 X; + /// + /// The X component. + /// + API_FIELD() int32 X; - // Y component - int32 Y; + /// + /// The Y component. + /// + API_FIELD() int32 Y; }; // Raw values @@ -40,6 +41,12 @@ public: // Vector with all components equal 1 static const Int2 One; + // A minimum Int2 + static const Int2 Minimum; + + // A maximum Int2 + static const Int2 Maximum; + public: /// @@ -67,9 +74,25 @@ public: } // Init - // @param v Vector to use X and Y components - explicit Int2(const Vector2& v); + // @param xyz Int3 to use X and Y components + Int2(const Int3& xyz); + // Init + // @param xyzw Int4 to use X and Y components + Int2(const Int4& xyzw); + + // Init + // @param xy Vector2 to use X and Y components + explicit Int2(const Vector2& xy); + + // Init + // @param xyz Vector3 to use X and Y components + explicit Int2(const Vector3& xyz); + + // Init + // @param xyzw Vector4 to use X and Y components + explicit Int2(const Vector4& xyzw); + public: String ToString() const; @@ -211,29 +234,29 @@ public: public: - static void Add(const Int2& a, const Int2& b, Int2* result) + static void Add(const Int2& a, const Int2& b, Int2& result) { - result->X = a.X + b.X; - result->Y = a.Y + b.Y; + result.X = a.X + b.X; + result.Y = a.Y + b.Y; } static Int2 Add(const Int2& a, const Int2& b) { Int2 result; - Add(a, b, &result); + Add(a, b, result); return result; } - static void Subtract(const Int2& a, const Int2& b, Int2* result) + static void Subtract(const Int2& a, const Int2& b, Int2& result) { - result->X = a.X - b.X; - result->Y = a.Y - b.Y; + result.X = a.X - b.X; + result.Y = a.Y - b.Y; } static Int2 Subtract(const Int2& a, const Int2& b) { Int2 result; - Subtract(a, b, &result); + Subtract(a, b, result); return result; } @@ -257,17 +280,112 @@ public: return Int2(a.X / b, a.Y / b); } - // Creates vector from minimum components of two vectors + /// + /// Gets a value indicting whether this vector is zero. + /// + /// True if the vector is zero, otherwise false. + bool IsZero() const + { + return X == 0 && Y == 0; + } + + /// + /// Gets a value indicting whether any vector component is zero. + /// + /// True if a component is zero, otherwise false. + bool IsAnyZero() const + { + return X == 0 || Y == 0; + } + + /// + /// Gets a value indicting whether this vector is one. + /// + /// True if the vector is one, otherwise false. + bool IsOne() const + { + return X == 1 && Y == 1; + } + + /// + /// Calculates a vector with values being opposite to values of that vector + /// + /// Negative vector + Int2 GetNegative() const + { + return Int2(-X, -Y); + } + + /// + /// Returns average arithmetic of all the components + /// + /// Average arithmetic of all the components + float AverageArithmetic() const + { + return (X + Y) * 0.5f; + } + + /// + /// Gets sum of all vector components values + /// + /// Sum of X, Y, Z and W + int32 SumValues() const + { + return X + Y; + } + + /// + /// Returns minimum value of all the components + /// + /// Minimum value + int32 MinValue() const + { + return Math::Min(X, Y); + } + + /// + /// Returns maximum value of all the components + /// + /// Maximum value + int32 MaxValue() const + { + return Math::Max(X, Y); + } + + + // Returns a vector containing the smallest components of the specified vectors + // @param a The first source vector + // @param b The second source vector static Int2 Min(const Int2& a, const Int2& b) { return Int2(a.X < b.X ? a.X : b.X, a.Y < b.Y ? a.Y : b.Y); } - // Creates vector from maximum components of two vectors + // Returns a vector containing the largest components of the specified vectors + // @param a The first source vector + // @param b The second source vector static Int2 Max(const Int2& a, const Int2& b) { return Int2(a.X > b.X ? a.X : b.X, a.Y > b.Y ? a.Y : b.Y); } + + // Returns a vector containing the smallest components of the specified vectors + // @param a The first source vector + // @param b The second source vector + // @param result When the method completes, contains an new vector composed of the smallest components of the source vectors + static void Min(const Int2& a, const Int2& b, Int2& result) + { + result = Int2(a.X < b.X ? a.X : b.X, a.Y < b.Y ? a.Y : b.Y); + } + + // Returns a vector containing the largest components of the specified vectors + // @param a The first source vector + // @param b The second source vector + // @param result When the method completes, contains an new vector composed of the largest components of the source vectors + static void Max(const Int2& a, const Int2& b, Int2& result) + { + result = Int2(a.X > b.X ? a.X : b.X, a.Y > b.Y ? a.Y : b.Y); + } }; template<> diff --git a/Source/Engine/Core/Math/Int3.cpp b/Source/Engine/Core/Math/Int3.cpp new file mode 100644 index 000000000..327437d70 --- /dev/null +++ b/Source/Engine/Core/Math/Int3.cpp @@ -0,0 +1,56 @@ +// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. + +#include "Int2.h" +#include "Int3.h" +#include "Int4.h" +#include "Vector2.h" +#include "Vector3.h" +#include "Vector4.h" +#include "Engine/Core/Types/String.h" + +static_assert(sizeof(Int3) == 12, "Invalid Int3 type size."); + +const Int3 Int3::Zero(0); +const Int3 Int3::One(1); +const Int3 Int3::Minimum(MIN_int32); +const Int3 Int3::Maximum(MAX_int32); + +Int3::Int3(const Int2& xy, int32 z) + : X(xy.X) + , Y(xy.Y) + , Z(z) +{ +} + +Int3::Int3(const Int4& xyzw) + : X(xyzw.X) + , Y(xyzw.Y) + , Z(xyzw.Z) +{ +} + +Int3::Int3(const Vector2& xy, int32 z) + : X(static_cast(xy.X)) + , Y(static_cast(xy.Y)) + , Z(z) +{ +} + +Int3::Int3(const Vector3& xyz) + : X(static_cast(xyz.X)) + , Y(static_cast(xyz.Y)) + , Z(static_cast(xyz.Z)) +{ +} + +Int3::Int3(const Vector4& xyzw) + : X(static_cast(xyzw.X)) + , Y(static_cast(xyzw.Y)) + , Z(static_cast(xyzw.Z)) +{ +} + +String Int3::ToString() const +{ + return String::Format(TEXT("{}"), *this); +} diff --git a/Source/Engine/Core/Math/Int3.cs b/Source/Engine/Core/Math/Int3.cs index 93193881a..e0c67bd33 100644 --- a/Source/Engine/Core/Math/Int3.cs +++ b/Source/Engine/Core/Math/Int3.cs @@ -12,9 +12,8 @@ namespace FlaxEngine /// Represents a three dimensional mathematical vector (signed integers). /// [Serializable] - [StructLayout(LayoutKind.Sequential, Pack = 4)] [TypeConverter(typeof(TypeConverters.Int3Converter))] - public struct Int3 : IEquatable, IFormattable + partial struct Int3 : IEquatable, IFormattable { private static readonly string _formatString = "X:{0} Y:{1} Z:{2}"; @@ -58,21 +57,6 @@ namespace FlaxEngine /// public static readonly Int3 Maximum = new Int3(int.MaxValue); - /// - /// The X component of the vector. - /// - public int X; - - /// - /// The Y component of the vector. - /// - public int Y; - - /// - /// The Z component of the vector. - /// - public int Z; - /// /// Initializes a new instance of the struct. /// diff --git a/Source/Engine/Core/Math/Int3.h b/Source/Engine/Core/Math/Int3.h index 6886acc6b..92311e2b1 100644 --- a/Source/Engine/Core/Math/Int3.h +++ b/Source/Engine/Core/Math/Int3.h @@ -6,29 +6,33 @@ #include "Engine/Core/Formatting.h" #include "Engine/Core/Templates.h" -struct Vector2; -struct Vector3; -struct Vector4; /// /// Three-components vector (32 bit integer type). /// -API_STRUCT(InBuild) struct FLAXENGINE_API Int3 +API_STRUCT() struct FLAXENGINE_API Int3 { +DECLARE_SCRIPTING_TYPE_MINIMAL(Int3); public: union { struct { - // X component - int32 X; + /// + /// The X component. + /// + API_FIELD() int32 X; - // Y component - int32 Y; + /// + /// The Y component. + /// + API_FIELD() int32 Y; - // Y component - int32 Z; + /// + /// The Z component. + /// + API_FIELD() int32 Z; }; // Raw values @@ -43,6 +47,12 @@ public: // Vector with all components equal 1 static const Int3 One; + // A minimum Int3 + static const Int3 Minimum; + + // A maximum Int3 + static const Int3 Maximum; + public: /// @@ -73,19 +83,293 @@ public: } // Init - // @param v Vector to use X, Y and Z components - explicit Int3(const Vector3& v); + // @param v Int2 to use X and Y components + // @param z Z component value + Int3(const Int2& xy, int32 z); + // Init + // @param v Int4 to use X and Y components + Int3(const Int4& xyzw); + + // Init + // @param v Vector2 to use X and Y components + // @param z Z component value + explicit Int3(const Vector2& xy, int32 z); + + // Init + // @param v Vector3 to use X, Y and Z components + explicit Int3(const Vector3& xyz); + + // Init + // @param v Vector4 to use X and Y components + explicit Int3(const Vector4& xyzw); + public: String ToString() const; public: + // Arithmetic operators with Int2 + + Int3 operator+(const Int3& b) const + { + return Add(*this, b); + } + + Int3 operator-(const Int3& b) const + { + return Subtract(*this, b); + } + + Int3 operator*(const Int3& b) const + { + return Multiply(*this, b); + } + + Int3 operator/(const Int3& b) const + { + return Divide(*this, b); + } + + Int3 operator-() const + { + return Int3(-X, -Y, -Z); + } + + // op= operators with Int2 + + Int3& operator+=(const Int3& b) + { + *this = Add(*this, b); + return *this; + } + + Int3& operator-=(const Int3& b) + { + *this = Subtract(*this, b); + return *this; + } + + Int3& operator*=(const Int3& b) + { + *this = Multiply(*this, b); + return *this; + } + + Int3& operator/=(const Int3& b) + { + *this = Divide(*this, b); + return *this; + } + + // Arithmetic operators with int32 + + Int3 operator+(int32 b) const + { + return Add(*this, b); + } + + Int3 operator-(int32 b) const + { + return Subtract(*this, b); + } + + Int3 operator*(int32 b) const + { + return Multiply(*this, b); + } + + Int3 operator/(int32 b) const + { + return Divide(*this, b); + } + + // op= operators with int32 + + Int3& operator+=(int32 b) + { + *this = Add(*this, b); + return *this; + } + + Int3& operator-=(int32 b) + { + *this = Subtract(*this, b); + return *this; + } + + Int3& operator*=(int32 b) + { + *this = Multiply(*this, b); + return *this; + } + + Int3& operator/=(int32 b) + { + *this = Divide(*this, b); + return *this; + } + + // Comparison operators + + bool operator==(const Int3& b) const + { + return X == b.X && Y == b.Y; + } + + bool operator!=(const Int3& b) const + { + return X != b.X || Y != b.Y; + } + + bool operator>(const Int3& b) const + { + return X > b.X && Y > b.Y; + } + + bool operator>=(const Int3& b) const + { + return X >= b.X && Y >= b.Y; + } + + bool operator<(const Int3& b) const + { + return X < b.X && Y < b.Y; + } + + bool operator<=(const Int3& b) const + { + return X <= b.X && Y <= b.Y; + } + +public: + + static void Add(const Int3& a, const Int3& b, Int3& result) + { + result.X = a.X + b.X; + result.Y = a.Y + b.Y; + result.Z = a.Z + b.Z; + } + + static Int3 Add(const Int3& a, const Int3& b) + { + Int3 result; + Add(a, b, result); + return result; + } + + static void Subtract(const Int3& a, const Int3& b, Int3& result) + { + result.X = a.X - b.X; + result.Y = a.Y - b.Y; + result.Z = a.Z - b.Z; + } + + static Int3 Subtract(const Int3& a, const Int3& b) + { + Int3 result; + Subtract(a, b, result); + return result; + } + + static Int3 Multiply(const Int3& a, const Int3& b) + { + return Int3(a.X * b.X, a.Y * b.Y, a.Z * b.Z); + } + + static Int3 Multiply(const Int3& a, int32 b) + { + return Int3(a.X * b, a.Y * b, a.Z * b); + } + + static Int3 Divide(const Int3& a, const Int3& b) + { + return Int3(a.X / b.X, a.Y / b.Y, a.Z / b.Z); + } + + static Int3 Divide(const Int3& a, int32 b) + { + return Int3(a.X / b, a.Y / b, a.Z / b); + } + +public: + + /// + /// Gets a value indicting whether this vector is zero. + /// + /// True if the vector is zero, otherwise false. + bool IsZero() const + { + return X == 0 && Y == 0 && Z == 0; + } + + /// + /// Gets a value indicting whether any vector component is zero. + /// + /// True if a component is zero, otherwise false. + bool IsAnyZero() const + { + return X == 0 || Y == 0 || Z == 0; + } + + /// + /// Gets a value indicting whether this vector is one. + /// + /// True if the vector is one, otherwise false. + bool IsOne() const + { + return X == 1 && Y == 1 && Z == 1; + } + + /// + /// Calculates a vector with values being opposite to values of that vector + /// + /// Negative vector + Int3 GetNegative() const + { + return Int3(-X, -Y, -Z); + } + + /// + /// Returns average arithmetic of all the components + /// + /// Average arithmetic of all the components + float AverageArithmetic() const + { + return (X + Y + Z) / 3.0f; + } + + /// + /// Gets sum of all vector components values + /// + /// Sum of X, Y, Z and W + int32 SumValues() const + { + return X + Y + Z; + } + + /// + /// Returns minimum value of all the components + /// + /// Minimum value + int32 MinValue() const + { + return Math::Min(X, Y, Z); + } + + /// + /// Returns maximum value of all the components + /// + /// Maximum value + int32 MaxValue() const + { + return Math::Max(X, Y, Z); + } + // Returns a vector containing the largest components of the specified vectors // @param a The first source vector // @param b The second source vector - // @param result When the method completes, contains an new vector composed of the largest components of the source vectors static Int3 Max(const Int3& a, const Int3& b) { return Int3(a.X > b.X ? a.X : b.X, a.Y > b.Y ? a.Y : b.Y, a.Z > b.Z ? a.Z : b.Z); @@ -94,7 +378,6 @@ public: // Returns a vector containing the smallest components of the specified vectors // @param a The first source vector // @param b The second source vector - // @param result When the method completes, contains an new vector composed of the smallest components of the source vectors static Int3 Min(const Int3& a, const Int3& b) { return Int3(a.X < b.X ? a.X : b.X, a.Y < b.Y ? a.Y : b.Y, a.Z < b.Z ? a.Z : b.Z); @@ -104,18 +387,18 @@ public: // @param a The first source vector // @param b The second source vector // @param result When the method completes, contains an new vector composed of the largest components of the source vectors - static void Max(const Int3& a, const Int3& b, Int3* result) + static void Max(const Int3& a, const Int3& b, Int3& result) { - *result = Int3(a.X > b.X ? a.X : b.X, a.Y > b.Y ? a.Y : b.Y, a.Z > b.Z ? a.Z : b.Z); + result = Int3(a.X > b.X ? a.X : b.X, a.Y > b.Y ? a.Y : b.Y, a.Z > b.Z ? a.Z : b.Z); } // Returns a vector containing the smallest components of the specified vectors // @param a The first source vector // @param b The second source vector // @param result When the method completes, contains an new vector composed of the smallest components of the source vectors - static void Min(const Int3& a, const Int3& b, Int3* result) + static void Min(const Int3& a, const Int3& b, Int3 result) { - *result = Int3(a.X < b.X ? a.X : b.X, a.Y < b.Y ? a.Y : b.Y, a.Z < b.Z ? a.Z : b.Z); + result = Int3(a.X < b.X ? a.X : b.X, a.Y < b.Y ? a.Y : b.Y, a.Z < b.Z ? a.Z : b.Z); } }; diff --git a/Source/Engine/Core/Math/VectorInt.cpp b/Source/Engine/Core/Math/Int4.cpp similarity index 56% rename from Source/Engine/Core/Math/VectorInt.cpp rename to Source/Engine/Core/Math/Int4.cpp index 300343da5..a8f6be236 100644 --- a/Source/Engine/Core/Math/VectorInt.cpp +++ b/Source/Engine/Core/Math/Int4.cpp @@ -1,42 +1,51 @@ // Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. -#include "VectorInt.h" +#include "Int2.h" +#include "Int3.h" +#include "Int4.h" #include "Vector2.h" #include "Vector3.h" #include "Vector4.h" #include "Engine/Core/Types/String.h" -const Int2 Int2::Zero(0); -const Int2 Int2::One(1); - -Int2::Int2(const Vector2& v) - : X(static_cast(v.X)) - , Y(static_cast(v.Y)) -{ -} - -String Int2::ToString() const -{ - return String::Format(TEXT("{}"), *this); -} - -const Int3 Int3::Zero(0); -const Int3 Int3::One(1); - -Int3::Int3(const Vector3& v) - : X(static_cast(v.X)) - , Y(static_cast(v.Y)) - , Z(static_cast(v.Z)) -{ -} - -String Int3::ToString() const -{ - return String::Format(TEXT("{}"), *this); -} +static_assert(sizeof(Int4) == 16, "Invalid Int4 type size."); const Int4 Int4::Zero(0); const Int4 Int4::One(1); +const Int4 Int4::Minimum(MIN_int32); +const Int4 Int4::Maximum(MAX_int32); + +Int4::Int4(const Int2& xy, int32 z, int32 w) + : X(xy.X) + , Y(xy.Y) + , Z(z) + , W(w) +{ +} + +Int4::Int4(const Int3& xyz, int32 w) + : X(xyz.X) + , Y(xyz.Y) + , Z(xyz.Z) + , W(w) +{ +} + +Int4::Int4(const Vector2& v, int32 z, int32 w) + : X(static_cast(v.X)) + , Y(static_cast(v.Y)) + , Z(z) + , W(w) +{ +} + +Int4::Int4(const Vector3& v, int32 w) + : X(static_cast(v.X)) + , Y(static_cast(v.Y)) + , Z(static_cast(v.Z)) + , W(w) +{ +} Int4::Int4(const Vector4& v) : X(static_cast(v.X)) diff --git a/Source/Engine/Core/Math/Int4.cs b/Source/Engine/Core/Math/Int4.cs index 0617f7b71..5328dcc73 100644 --- a/Source/Engine/Core/Math/Int4.cs +++ b/Source/Engine/Core/Math/Int4.cs @@ -12,9 +12,8 @@ namespace FlaxEngine /// Represents a four dimensional mathematical vector (signed integers). /// [Serializable] - [StructLayout(LayoutKind.Sequential, Pack = 4)] [TypeConverter(typeof(TypeConverters.Int4Converter))] - public struct Int4 : IEquatable, IFormattable + partial struct Int4 : IEquatable, IFormattable { private static readonly string _formatString = "X:{0} Y:{1} Z:{2} W:{3}"; @@ -63,26 +62,6 @@ namespace FlaxEngine /// public static readonly Int4 Maximum = new Int4(int.MaxValue); - /// - /// The X component of the vector. - /// - public int X; - - /// - /// The Y component of the vector. - /// - public int Y; - - /// - /// The Z component of the vector. - /// - public int Z; - - /// - /// The W component of the vector. - /// - public int W; - /// /// Initializes a new instance of the struct. /// diff --git a/Source/Engine/Core/Math/Int4.h b/Source/Engine/Core/Math/Int4.h index c8e9eebd8..8c7f148be 100644 --- a/Source/Engine/Core/Math/Int4.h +++ b/Source/Engine/Core/Math/Int4.h @@ -6,32 +6,37 @@ #include "Engine/Core/Formatting.h" #include "Engine/Core/Templates.h" -struct Vector2; -struct Vector3; -struct Vector4; - /// /// Four-components vector (32 bit integer type). /// -API_STRUCT(InBuild) struct FLAXENGINE_API Int4 +API_STRUCT() struct FLAXENGINE_API Int4 { +DECLARE_SCRIPTING_TYPE_MINIMAL(Int4); public: union { struct { - // X component - int32 X; + /// + /// The X component. + /// + API_FIELD() int32 X; - // Y component - int32 Y; + /// + /// The Y component. + /// + API_FIELD() int32 Y; - // Z component - int32 Z; + /// + /// The Z component. + /// + API_FIELD() int32 Z; - // W component - int32 W; + /// + /// The W component. + /// + API_FIELD() int32 W; }; // Raw values @@ -46,6 +51,12 @@ public: // Vector with all components equal 1 static const Int4 One; + // A minimum Int4 + static const Int4 Minimum; + + // A maximum Int4 + static const Int4 Maximum; + public: /// @@ -78,9 +89,31 @@ public: { } + // Init + // @param v Int2 to use X and Y components + // @param z Z component value + // @param w W component value + Int4(const Int2& xy, int32 z, int32 w); + + // Init + // @param v Int3 to use X , Y and Z components + // @param w W component value + Int4(const Int3& xyz, int32 w); + + // Init + // @param v Vector2 to use X and Y components + // @param z Z component value + // @param w W component value + explicit Int4(const Vector2& xy, int32 z, int32 w); + + // Init + // @param v Vector3 to use X , Y and Z components + // @param w W component value + explicit Int4(const Vector3& xyz, int32 w); + // Init // @param v Vector to use X, Y, Z and W components - explicit Int4(const Vector4& v); + explicit Int4(const Vector4& xyzw); public: @@ -88,6 +121,229 @@ public: public: + // Arithmetic operators with Int2 + + Int4 operator+(const Int4& b) const + { + return Add(*this, b); + } + + Int4 operator-(const Int4& b) const + { + return Subtract(*this, b); + } + + Int4 operator*(const Int4& b) const + { + return Multiply(*this, b); + } + + Int4 operator/(const Int4& b) const + { + return Divide(*this, b); + } + + Int4 operator-() const + { + return Int4(-X, -Y, -Z, -W); + } + + // op= operators with Int2 + + Int4& operator+=(const Int4& b) + { + *this = Add(*this, b); + return *this; + } + + Int4& operator-=(const Int4& b) + { + *this = Subtract(*this, b); + return *this; + } + + Int4& operator*=(const Int4& b) + { + *this = Multiply(*this, b); + return *this; + } + + Int4& operator/=(const Int4& b) + { + *this = Divide(*this, b); + return *this; + } + + // Arithmetic operators with int32 + + Int4 operator+(int32 b) const + { + return Add(*this, b); + } + + Int4 operator-(int32 b) const + { + return Subtract(*this, b); + } + + Int4 operator*(int32 b) const + { + return Multiply(*this, b); + } + + Int4 operator/(int32 b) const + { + return Divide(*this, b); + } + + // op= operators with int32 + + Int4& operator+=(int32 b) + { + *this = Add(*this, b); + return *this; + } + + Int4& operator-=(int32 b) + { + *this = Subtract(*this, b); + return *this; + } + + Int4& operator*=(int32 b) + { + *this = Multiply(*this, b); + return *this; + } + + Int4& operator/=(int32 b) + { + *this = Divide(*this, b); + return *this; + } + + // Comparison operators + + bool operator==(const Int4& b) const + { + return X == b.X && Y == b.Y; + } + + bool operator!=(const Int4& b) const + { + return X != b.X || Y != b.Y; + } + + bool operator>(const Int4& b) const + { + return X > b.X && Y > b.Y; + } + + bool operator>=(const Int4& b) const + { + return X >= b.X && Y >= b.Y; + } + + bool operator<(const Int4& b) const + { + return X < b.X && Y < b.Y; + } + + bool operator<=(const Int4& b) const + { + return X <= b.X && Y <= b.Y; + } + +public: + + static void Add(const Int4& a, const Int4& b, Int4& result) + { + result.X = a.X + b.X; + result.Y = a.Y + b.Y; + result.Z = a.Z + b.Z; + result.W = a.W + b.W; + } + + static Int4 Add(const Int4& a, const Int4& b) + { + Int4 result; + Add(a, b, result); + return result; + } + + static void Subtract(const Int4& a, const Int4& b, Int4& result) + { + result.X = a.X - b.X; + result.Y = a.Y - b.Y; + result.Z = a.Z - b.Z; + result.W = a.W - b.W; + } + + static Int4 Subtract(const Int4& a, const Int4& b) + { + Int4 result; + Subtract(a, b, result); + return result; + } + + static Int4 Multiply(const Int4& a, const Int4& b) + { + return Int4(a.X * b.X, a.Y * b.Y, a.Z * b.Z, a.W * b.W); + } + + static Int4 Multiply(const Int4& a, int32 b) + { + return Int4(a.X * b, a.Y * b, a.Z * b, a.W * b); + } + + static Int4 Divide(const Int4& a, const Int4& b) + { + return Int4(a.X / b.X, a.Y / b.Y, a.Z / b.Z, a.W / b.W); + } + + static Int4 Divide(const Int4& a, int32 b) + { + return Int4(a.X / b, a.Y / b, a.Z / b, a.Y / b); + } + +public: + + /// + /// Gets a value indicting whether this vector is zero. + /// + /// True if the vector is zero, otherwise false. + bool IsZero() const + { + return X == 0 && Y == 0 && Z == 0 && W == 0; + } + + /// + /// Gets a value indicting whether any vector component is zero. + /// + /// True if a component is zero, otherwise false. + bool IsAnyZero() const + { + return X == 0 || Y == 0 || Z == 0 || W == 0; + } + + /// + /// Gets a value indicting whether this vector is one. + /// + /// True if the vector is one, otherwise false. + bool IsOne() const + { + return X == 1 && Y == 1 && Z == 1 && W == 1; + } + + /// + /// Calculates a vector with values being opposite to values of that vector + /// + /// Negative vector + Int4 GetNegative() const + { + return Int4(-X, -Y, -Z, -W); + } + /// /// Returns average arithmetic of all the components /// @@ -123,6 +379,40 @@ public: { return Math::Max(X, Y, Z, W); } + + // Returns a vector containing the largest components of the specified vectors + // @param a The first source vector + // @param b The second source vector + static Int4 Max(const Int4& a, const Int4& b) + { + return Int4(a.X > b.X ? a.X : b.X, a.Y > b.Y ? a.Y : b.Y, a.Z > b.Z ? a.Z : b.Z, a.W > b.W ? a.W : b.W); + } + + // Returns a vector containing the smallest components of the specified vectors + // @param a The first source vector + // @param b The second source vector + static Int4 Min(const Int4& a, const Int4& b) + { + return Int4(a.X < b.X ? a.X : b.X, a.Y < b.Y ? a.Y : b.Y, a.Z < b.Z ? a.Z : b.Z, a.W < b.W ? a.W : b.W); + } + + // Returns a vector containing the largest components of the specified vectors + // @param a The first source vector + // @param b The second source vector + // @param result When the method completes, contains an new vector composed of the largest components of the source vectors + static void Max(const Int4& a, const Int4& b, Int4& result) + { + result = Int4(a.X > b.X ? a.X : b.X, a.Y > b.Y ? a.Y : b.Y, a.Z > b.Z ? a.Z : b.Z, a.W > b.W ? a.W : b.W); + } + + // Returns a vector containing the smallest components of the specified vectors + // @param a The first source vector + // @param b The second source vector + // @param result When the method completes, contains an new vector composed of the smallest components of the source vectors + static void Min(const Int4& a, const Int4& b, Int4& result) + { + result = Int4(a.X < b.X ? a.X : b.X, a.Y < b.Y ? a.Y : b.Y, a.Z < b.Z ? a.Z : b.Z, a.W < b.W ? a.W : b.W); + } }; template<> diff --git a/Source/Engine/Core/Math/Vector2.cpp b/Source/Engine/Core/Math/Vector2.cpp index c23e79d19..2c6979575 100644 --- a/Source/Engine/Core/Math/Vector2.cpp +++ b/Source/Engine/Core/Math/Vector2.cpp @@ -5,6 +5,8 @@ #include "Vector4.h" #include "Color.h" #include "Int2.h" +#include "Int3.h" +#include "Int4.h" #include "../Types/String.h" static_assert(sizeof(Vector2) == 8, "Invalid Vector2 type size."); @@ -16,21 +18,33 @@ const Vector2 Vector2::UnitY(0, 1); const Vector2 Vector2::Minimum(MIN_float); const Vector2 Vector2::Maximum(MAX_float); -Vector2::Vector2(const Int2& v) - : X((float)v.X) - , Y((float)v.Y) +Vector2::Vector2(const Int2& xy) + : X(static_cast(xy.X)) + , Y(static_cast(xy.Y)) { } -Vector2::Vector2(const Vector3& v) - : X(v.X) - , Y(v.Y) +Vector2::Vector2(const Int3& xyz) + : X(static_cast(xyz.X)) + , Y(static_cast(xyz.Y)) { } -Vector2::Vector2(const Vector4& v) - : X(v.X) - , Y(v.Y) +Vector2::Vector2(const Int4& xyzw) + : X(static_cast(xyzw.X)) + , Y(static_cast(xyzw.Y)) +{ +} + +Vector2::Vector2(const Vector3& xyz) + : X(xyz.X) + , Y(xyz.Y) +{ +} + +Vector2::Vector2(const Vector4& xyzw) + : X(xyzw.X) + , Y(xyzw.Y) { } diff --git a/Source/Engine/Core/Math/Vector2.h b/Source/Engine/Core/Math/Vector2.h index 7a1b1519b..aaea1d73c 100644 --- a/Source/Engine/Core/Math/Vector2.h +++ b/Source/Engine/Core/Math/Vector2.h @@ -8,6 +8,9 @@ struct Vector3; struct Vector4; +struct Int2; +struct Int3; +struct Int4; struct Color; struct Matrix; @@ -85,16 +88,24 @@ public: } // Init - // @param v Vector to use X and Y components - explicit Vector2(const Int2& v); + // @param v Int2 to use X and Y components + explicit Vector2(const Int2& xy); // Init - // @param v Vector to use X and Y components - explicit Vector2(const Vector3& v); + // @param v Int3 to use X and Y components + explicit Vector2(const Int3& xyz); + + // Init + // @param v Int4 to use X and Y components + explicit Vector2(const Int4& xyzw); + + // Init + // @param v Vector3 to use X and Y components + explicit Vector2(const Vector3& xyz); // Init // @param v Vector4 to use X and Y components - explicit Vector2(const Vector4& v); + explicit Vector2(const Vector4& xyzw); // Init // @param color Color value diff --git a/Source/Engine/Core/Math/Vector3.cpp b/Source/Engine/Core/Math/Vector3.cpp index f66bbcbbd..9c8783dad 100644 --- a/Source/Engine/Core/Math/Vector3.cpp +++ b/Source/Engine/Core/Math/Vector3.cpp @@ -6,7 +6,9 @@ #include "Color.h" #include "Quaternion.h" #include "Matrix.h" +#include "Int2.h" #include "Int3.h" +#include "Int4.h" #include "../Types/String.h" static_assert(sizeof(Vector3) == 12, "Invalid Vector3 type size."); @@ -40,10 +42,24 @@ Vector3::Vector3(const Vector2& xy) { } +Vector3::Vector3(const Int2& xy, float z) + : X(static_cast(xy.X)) + , Y(static_cast(xy.Y)) + , Z(static_cast(z)) +{ +} + Vector3::Vector3(const Int3& xyz) - : X((float)xyz.X) - , Y((float)xyz.Y) - , Z((float)xyz.Z) + : X(static_cast(xyz.X)) + , Y(static_cast(xyz.Y)) + , Z(static_cast(xyz.Z)) +{ +} + +Vector3::Vector3(const Int4& xyzw) + : X(static_cast(xyzw.X)) + , Y(static_cast(xyzw.Y)) + , Z(static_cast(xyzw.Z)) { } diff --git a/Source/Engine/Core/Math/Vector3.h b/Source/Engine/Core/Math/Vector3.h index 1f4792e31..d9a1d6036 100644 --- a/Source/Engine/Core/Math/Vector3.h +++ b/Source/Engine/Core/Math/Vector3.h @@ -12,6 +12,8 @@ struct Vector2; struct Vector4; struct Color; class String; +struct Int3; +struct Int4; /// /// Represents a three dimensional mathematical vector. @@ -138,10 +140,19 @@ public: // @param xy Vector3 value explicit Vector3(const Vector2& xy); + // Init + // @param xy Int22 with X and Y components values + // @param z Z component value + explicit Vector3(const Int2& xy, float z); + // Init // @param xyz Int3 value explicit Vector3(const Int3& xyz); + // Init + // @param xyzw Int4 value + explicit Vector3(const Int4& xyzw); + // Init // @param xyz Vector4 value explicit Vector3(const Vector4& xyz); diff --git a/Source/Engine/Core/Math/Vector4.cpp b/Source/Engine/Core/Math/Vector4.cpp index 34fa27aac..5da725c20 100644 --- a/Source/Engine/Core/Math/Vector4.cpp +++ b/Source/Engine/Core/Math/Vector4.cpp @@ -3,10 +3,12 @@ #include "Vector4.h" #include "Vector2.h" #include "Vector3.h" +#include "Int2.h" +#include "Int3.h" +#include "Int4.h" #include "Color.h" #include "Matrix.h" #include "Rectangle.h" -#include "Int4.h" #include "../Types/String.h" static_assert(sizeof(Vector4) == 16, "Invalid Vector4 type size."); @@ -49,11 +51,27 @@ Vector4::Vector4(const Vector3& xyz, float w) { } +Vector4::Vector4(const Int2& xy, float z, float w) + : X(static_cast(xy.X)) + , Y(static_cast(xy.Y)) + , Z(z) + , W(w) +{ +} + +Vector4::Vector4(const Int3& xyz, float w) + : X(static_cast(xyz.X)) + , Y(static_cast(xyz.Y)) + , Z(static_cast(xyz.Z)) + , W(w) +{ +} + Vector4::Vector4(const Int4& xyzw) - : X((float)xyzw.X) - , Y((float)xyzw.Y) - , Z((float)xyzw.X) - , W((float)xyzw.Y) + : X(static_cast(xyzw.X)) + , Y(static_cast(xyzw.Y)) + , Z(static_cast(xyzw.X)) + , W(static_cast(xyzw.Y)) { } diff --git a/Source/Engine/Core/Math/Vector4.h b/Source/Engine/Core/Math/Vector4.h index c7771aa67..fe25a80bd 100644 --- a/Source/Engine/Core/Math/Vector4.h +++ b/Source/Engine/Core/Math/Vector4.h @@ -13,6 +13,9 @@ struct Color; struct Matrix; struct Rectangle; class String; +struct Int2; +struct Int3; +struct Int4; /// /// Represents a four dimensional mathematical vector. @@ -133,6 +136,17 @@ public: // @param w W component value Vector4(const Vector3& xyz, float w); + // Init + // @param xy X and Y values in the vector + // @param z Z component value + // @param w W component value + explicit Vector4(const Int2& xy, float z, float w); + + // Init + // @param xyz X, Y and Z values in the vector + // @param w W component value + explicit Vector4(const Int3& xyz, float w); + // Init // @param color Int4 value explicit Vector4(const Int4& xyzw); diff --git a/Source/Engine/Core/Math/VectorInt.h b/Source/Engine/Core/Math/VectorInt.h deleted file mode 100644 index d9611d615..000000000 --- a/Source/Engine/Core/Math/VectorInt.h +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. - -#pragma once - -#include "Int2.h" -#include "Int3.h" -#include "Int4.h" diff --git a/Source/Engine/Core/Types/Variant.cpp b/Source/Engine/Core/Types/Variant.cpp index db71c2f77..85240c8bf 100644 --- a/Source/Engine/Core/Types/Variant.cpp +++ b/Source/Engine/Core/Types/Variant.cpp @@ -11,6 +11,9 @@ #include "Engine/Core/Math/Vector2.h" #include "Engine/Core/Math/Vector3.h" #include "Engine/Core/Math/Vector4.h" +#include "Engine/Core/Math/Int2.h" +#include "Engine/Core/Math/Int3.h" +#include "Engine/Core/Math/Int4.h" #include "Engine/Core/Math/Quaternion.h" #include "Engine/Core/Math/Color.h" #include "Engine/Core/Math/Matrix.h" @@ -551,6 +554,24 @@ Variant::Variant(const Vector4& v) *(Vector4*)AsData = v; } +Variant::Variant(const Int2& v) + : Type(VariantType::Int2) +{ + *(Int2*)AsData = v; +} + +Variant::Variant(const Int3& v) + : Type(VariantType::Int3) +{ + *(Int3*)AsData = v; +} + +Variant::Variant(const Int4& v) + : Type(VariantType::Int4) +{ + *(Int4*)AsData = v; +} + Variant::Variant(const Color& v) : Type(VariantType::Color) { @@ -1504,6 +1525,132 @@ Variant::operator Vector4() const } } +Variant::operator Int2() const +{ + switch (Type.Type) + { + case VariantType::Bool: + return Int2((int32)(AsBool ? 1.0f : 0.0f)); + case VariantType::Int: + return Int2((int32)AsInt); + case VariantType::Uint: + return Int2((int32)AsUint); + case VariantType::Int64: + return Int2((int32)AsInt64); + case VariantType::Uint64: + case VariantType::Enum: + return Int2((int32)AsUint64); + case VariantType::Float: + return Int2((int32)AsFloat); + case VariantType::Double: + return Int2((int32)AsDouble); + case VariantType::Pointer: + return Int2((int32)(intptr)AsPointer); + case VariantType::Vector2: + return Int2(*(Vector2*)AsData); + case VariantType::Vector3: + return Int2(*(Vector3*)AsData); + case VariantType::Vector4: + return Int2(*(Vector4*)AsData); + case VariantType::Int2: + return Int2(*(Int2*)AsData); + case VariantType::Int3: + return Int2(*(Int3*)AsData); + case VariantType::Int4: + case VariantType::Color: + return Int2(*(Int4*)AsData); + case VariantType::Structure: + if (StringUtils::Compare(Type.TypeName, Int2::TypeInitializer.GetType().Fullname.Get()) == 0) + return *(Int2*)AsBlob.Data; + default: + return Int3::Zero; + } +} + +Variant::operator Int3() const +{ + switch (Type.Type) + { + case VariantType::Bool: + return Int3((int32)(AsBool ? 1.0f : 0.0f)); + case VariantType::Int: + return Int3((int32)AsInt); + case VariantType::Uint: + return Int3((int32)AsUint); + case VariantType::Int64: + return Int3((int32)AsInt64); + case VariantType::Uint64: + case VariantType::Enum: + return Int3((int32)AsUint64); + case VariantType::Float: + return Int3((int32)AsFloat); + case VariantType::Double: + return Int3((int32)AsDouble); + case VariantType::Pointer: + return Int3((int32)(intptr)AsPointer); + case VariantType::Vector2: + return Int3(*(Vector2*)AsData, 0.0f); + case VariantType::Vector3: + return Int3(*(Vector3*)AsData); + case VariantType::Vector4: + return Int3(*(Vector4*)AsData); + case VariantType::Int2: + return Int3(*(Int2*)AsData, 0.0f); + case VariantType::Int3: + return Int3(*(Int3*)AsData); + case VariantType::Int4: + case VariantType::Color: + return Int3(*(Int4*)AsData); + case VariantType::Structure: + if (StringUtils::Compare(Type.TypeName, Int3::TypeInitializer.GetType().Fullname.Get()) == 0) + return *(Int3*)AsBlob.Data; + default: + return Int3::Zero; + } +} + +Variant::operator Int4() const +{ + switch (Type.Type) + { + case VariantType::Bool: + return Int4((int32)(AsBool ? 1.0f : 0.0f)); + case VariantType::Int: + return Int4((int32)AsInt); + case VariantType::Uint: + return Int4((int32)AsUint); + case VariantType::Int64: + return Int4((int32)AsInt64); + case VariantType::Uint64: + case VariantType::Enum: + return Int4((int32)AsUint64); + case VariantType::Float: + return Int4((int32)AsFloat); + case VariantType::Double: + return Int4((int32)AsDouble); + case VariantType::Pointer: + return Int4((int32)(intptr)AsPointer); + case VariantType::Vector2: + return Int4(*(Vector2*)AsData, 0.0f, 0.0f); + case VariantType::Vector3: + return Int4(*(Vector3*)AsData, 0.0f); + case VariantType::Vector4: + return Int4(*(Vector4*)AsData); + case VariantType::Int2: + return Int4(*(Int2*)AsData, 0.0f, 0.0f); + case VariantType::Int3: + return Int4(*(Int3*)AsData, 0.0f); + case VariantType::Int4: + case VariantType::Color: + return *(Int4*)AsData; + case VariantType::Structure: + if (StringUtils::Compare(Type.TypeName, Int4::TypeInitializer.GetType().Fullname.Get()) == 0) + return *(Int4*)AsBlob.Data; + default: + return Int4::Zero; + } +} + Variant::operator Color() const { switch (Type.Type) @@ -1670,6 +1817,21 @@ const Vector4& Variant::AsVector4() const return *(const Vector4*)AsData; } +const Int2& Variant::AsInt2() const +{ + return *(const Int2*)AsData; +} + +const Int3& Variant::AsInt3() const +{ + return *(const Int3*)AsData; +} + +const Int4& Variant::AsInt4() const +{ + return *(const Int4*)AsData; +} + const Color& Variant::AsColor() const { return *(const Color*)AsData; diff --git a/Source/Engine/Core/Types/Variant.h b/Source/Engine/Core/Types/Variant.h index 98fd9cf24..ac9af0e79 100644 --- a/Source/Engine/Core/Types/Variant.h +++ b/Source/Engine/Core/Types/Variant.h @@ -54,6 +54,10 @@ API_STRUCT(InBuild) struct FLAXENGINE_API VariantType ManagedObject, Typename, + Int2, + Int3, + Int4, + MAX }; @@ -198,6 +202,9 @@ public: Variant(const Vector2& v); Variant(const Vector3& v); Variant(const Vector4& v); + Variant(const Int2& v); + Variant(const Int3& v); + Variant(const Int4& v); Variant(const Color& v); Variant(const Quaternion& v); Variant(const BoundingSphere& v); @@ -262,6 +269,9 @@ public: explicit operator Vector2() const; explicit operator Vector3() const; explicit operator Vector4() const; + explicit operator Int2() const; + explicit operator Int3() const; + explicit operator Int4() const; explicit operator Color() const; explicit operator Quaternion() const; explicit operator Guid() const; @@ -275,6 +285,9 @@ public: const Vector2& AsVector2() const; const Vector3& AsVector3() const; const Vector4& AsVector4() const; + const Int2& AsInt2() const; + const Int3& AsInt3() const; + const Int4& AsInt4() const; const Color& AsColor() const; const Quaternion& AsQuaternion() const; diff --git a/Source/Engine/Serialization/JsonWriter.h b/Source/Engine/Serialization/JsonWriter.h index 7182ec69a..df6cb7d2d 100644 --- a/Source/Engine/Serialization/JsonWriter.h +++ b/Source/Engine/Serialization/JsonWriter.h @@ -11,6 +11,9 @@ #include "Engine/Core/Math/Vector2.h" #include "Engine/Core/Math/Vector3.h" #include "Engine/Core/Math/Vector4.h" +#include "Engine/Core/Math/Int2.h" +#include "Engine/Core/Math/Int3.h" +#include "Engine/Core/Math/Int4.h" #include "Engine/Core/Math/Color.h" #include "Engine/Core/Math/Quaternion.h" #include "Engine/Core/Math/Ray.h" @@ -149,6 +152,42 @@ public: EndObject(); } + void Int2(const Int2& value) + { + StartObject(); + JKEY("X"); + Int(value.X); + JKEY("Y"); + Int(value.Y); + EndObject(); + } + + void Int3(const Int3& value) + { + StartObject(); + JKEY("X"); + Int(value.X); + JKEY("Y"); + Int(value.Y); + JKEY("Z"); + Int(value.Z); + EndObject(); + } + + void Int4(const Int4& value) + { + StartObject(); + JKEY("X"); + Int(value.X); + JKEY("Y"); + Int(value.Y); + JKEY("Z"); + Int(value.Z); + JKEY("W"); + Int(value.W); + EndObject(); + } + void Color(const Color& value) { StartObject(); diff --git a/Source/Engine/Serialization/Serialization.cpp b/Source/Engine/Serialization/Serialization.cpp index 7eb48a22c..30cfde962 100644 --- a/Source/Engine/Serialization/Serialization.cpp +++ b/Source/Engine/Serialization/Serialization.cpp @@ -138,6 +138,15 @@ void Serialization::Serialize(ISerializable::SerializeStream& stream, const Vari case VariantType::Vector4: stream.Vector4(*(Vector4*)v.AsData); break; + case VariantType::Int2: + stream.Int2(*(Int2*)v.AsData); + break; + case VariantType::Int3: + stream.Int3(*(Int3*)v.AsData); + break; + case VariantType::Int4: + stream.Int4(*(Int4*)v.AsData); + break; case VariantType::Color: stream.Color(*(Color*)v.AsData); break; @@ -258,6 +267,15 @@ void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Varian case VariantType::Vector4: Deserialize(value, *(Vector4*)v.AsData, modifier); break; + case VariantType::Int2: + Deserialize(value, *(Int2*)v.AsData, modifier); + break; + case VariantType::Int3: + Deserialize(value, *(Int3*)v.AsData, modifier); + break; + case VariantType::Int4: + Deserialize(value, *(Int4*)v.AsData, modifier); + break; case VariantType::Color: Deserialize(value, *(Color*)v.AsData, modifier); break; @@ -445,6 +463,51 @@ void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Vector v.W = mW != stream.MemberEnd() ? mW->value.GetFloat() : 0.0f; } +bool Serialization::ShouldSerialize(const Int2& v, const void* otherObj) +{ + return !otherObj || !(v == *(Int2*)otherObj); +} + +void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Int2& 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.GetInt() : 0; + v.Y = mY != stream.MemberEnd() ? mY->value.GetInt() : 0; +} + +bool Serialization::ShouldSerialize(const Int3& v, const void* otherObj) +{ + return !otherObj || !(v == *(Int3*)otherObj); +} + +void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Int3& 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.GetInt() : 0; + v.Y = mY != stream.MemberEnd() ? mY->value.GetInt() : 0; + v.Z = mZ != stream.MemberEnd() ? mZ->value.GetInt() : 0; +} + +bool Serialization::ShouldSerialize(const Int4& v, const void* otherObj) +{ + return !otherObj || !(v == *(Int4*)otherObj); +} + +void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Int4& 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.GetInt() : 0; + v.Y = mY != stream.MemberEnd() ? mY->value.GetInt() : 0; + v.Z = mZ != stream.MemberEnd() ? mZ->value.GetInt() : 0; + v.W = mW != stream.MemberEnd() ? mW->value.GetInt() : 0; +} + bool Serialization::ShouldSerialize(const Quaternion& v, const void* otherObj) { return !otherObj || !Quaternion::NearEqual(v, *(Quaternion*)otherObj, SERIALIZE_EPSILON); diff --git a/Source/Engine/Serialization/Serialization.h b/Source/Engine/Serialization/Serialization.h index 29642f850..cfe63c859 100644 --- a/Source/Engine/Serialization/Serialization.h +++ b/Source/Engine/Serialization/Serialization.h @@ -268,6 +268,27 @@ namespace Serialization } FLAXENGINE_API void Deserialize(ISerializable::DeserializeStream& stream, Vector4& 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) + { + stream.Int2(v); + } + FLAXENGINE_API void Deserialize(ISerializable::DeserializeStream& stream, Int2& v, ISerializeModifier* modifier); + + FLAXENGINE_API bool ShouldSerialize(const Int3& v, const void* otherObj); + inline void Serialize(ISerializable::SerializeStream& stream, const Int3& v, const void* otherObj) + { + stream.Int3(v); + } + FLAXENGINE_API void Deserialize(ISerializable::DeserializeStream& stream, Int3& v, ISerializeModifier* modifier); + + FLAXENGINE_API bool ShouldSerialize(const Int4& v, const void* otherObj); + inline void Serialize(ISerializable::SerializeStream& stream, const Int4& v, const void* otherObj) + { + stream.Int4(v); + } + FLAXENGINE_API void Deserialize(ISerializable::DeserializeStream& stream, Int4& v, ISerializeModifier* modifier); + FLAXENGINE_API bool ShouldSerialize(const Quaternion& v, const void* otherObj); inline void Serialize(ISerializable::SerializeStream& stream, const Quaternion& v, const void* otherObj) { diff --git a/Source/Engine/Utilities/Utils.cs b/Source/Engine/Utilities/Utils.cs index a72b4e676..ab4fdf17b 100644 --- a/Source/Engine/Utilities/Utils.cs +++ b/Source/Engine/Utilities/Utils.cs @@ -240,6 +240,36 @@ namespace FlaxEngine return new Vector4(stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle()); } + /// + /// Reads the Int2 from the binary stream. + /// + /// The stream. + /// The value. + public static Int2 ReadInt2(this BinaryReader stream) + { + return new Int2(stream.ReadInt32(), stream.ReadInt32()); + } + + /// + /// Reads the Int3 from the binary stream. + /// + /// The stream. + /// The value. + public static Int3 ReadInt3(this BinaryReader stream) + { + return new Int3(stream.ReadInt32(), stream.ReadInt32(), stream.ReadInt32()); + } + + /// + /// Reads the Int4 from the binary stream. + /// + /// The stream. + /// The value. + public static Int4 ReadInt4(this BinaryReader stream) + { + return new Int4(stream.ReadInt32(), stream.ReadInt32(), stream.ReadInt32(), stream.ReadInt32()); + } + /// /// Reads the Quaternion from the binary stream. /// @@ -362,6 +392,42 @@ namespace FlaxEngine stream.Write(value.W); } + /// + /// Writes the Int2 to the binary stream. + /// + /// The stream. + /// The value to write. + public static void Write(this BinaryWriter stream, Int2 value) + { + stream.Write(value.X); + stream.Write(value.Y); + } + + /// + /// Writes the Int3 to the binary stream. + /// + /// The stream. + /// The value to write. + public static void Write(this BinaryWriter stream, Int3 value) + { + stream.Write(value.X); + stream.Write(value.Y); + stream.Write(value.Z); + } + + /// + /// Writes the Int4 to the binary stream. + /// + /// The stream. + /// The value to write. + public static void Write(this BinaryWriter stream, Int4 value) + { + stream.Write(value.X); + stream.Write(value.Y); + stream.Write(value.Z); + stream.Write(value.W); + } + /// /// Writes the Quaternion to the binary stream. ///