diff options
-rw-r--r-- | modules/mono/csharp_script.cpp | 3 | ||||
-rw-r--r-- | modules/mono/editor/bindings_generator.cpp | 9 | ||||
-rw-r--r-- | modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs | 262 | ||||
-rw-r--r-- | modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs | 26 | ||||
-rw-r--r-- | modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs | 380 | ||||
-rw-r--r-- | modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs | 18 | ||||
-rw-r--r-- | modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs | 402 | ||||
-rw-r--r-- | modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj | 3 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_cache.cpp | 6 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_cache.h | 3 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_field.cpp | 24 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_marshal.cpp | 45 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_marshal.h | 62 |
13 files changed, 1220 insertions, 23 deletions
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index cb17defc4a..c1302109a5 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -461,8 +461,11 @@ static String variant_type_to_managed_name(const String &p_var_type_name) { Variant::BOOL, Variant::INT, Variant::VECTOR2, + Variant::VECTOR2I, Variant::RECT2, + Variant::RECT2I, Variant::VECTOR3, + Variant::VECTOR3I, Variant::TRANSFORM2D, Variant::PLANE, Variant::QUAT, diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index c8430234d6..9a5de6db16 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -2810,8 +2810,11 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; break; case Variant::VECTOR2: + case Variant::VECTOR2I: case Variant::RECT2: + case Variant::RECT2I: case Variant::VECTOR3: + case Variant::VECTOR3I: r_iarg.default_argument = "new %s" + r_iarg.default_argument; r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; break; @@ -2891,9 +2894,12 @@ void BindingsGenerator::_populate_builtin_type_interfaces() { } INSERT_STRUCT_TYPE(Vector2) + INSERT_STRUCT_TYPE(Vector2i) INSERT_STRUCT_TYPE(Rect2) + INSERT_STRUCT_TYPE(Rect2i) INSERT_STRUCT_TYPE(Transform2D) INSERT_STRUCT_TYPE(Vector3) + INSERT_STRUCT_TYPE(Vector3i) INSERT_STRUCT_TYPE(Basis) INSERT_STRUCT_TYPE(Quat) INSERT_STRUCT_TYPE(Transform) @@ -3314,7 +3320,10 @@ void BindingsGenerator::_populate_global_constants() { // HARDCODED List<StringName> hardcoded_enums; + hardcoded_enums.push_back("Vector2.Axis"); + hardcoded_enums.push_back("Vector2i.Axis"); hardcoded_enums.push_back("Vector3.Axis"); + hardcoded_enums.push_back("Vector3i.Axis"); for (List<StringName>::Element *E = hardcoded_enums.front(); E; E = E->next()) { // These enums are not generated and must be written manually (e.g.: Vector3.Axis) // Here, we assume core types do not begin with underscore diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs new file mode 100644 index 0000000000..bc2cad8713 --- /dev/null +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs @@ -0,0 +1,262 @@ +using System; +using System.Runtime.InteropServices; + +namespace Godot +{ + [Serializable] + [StructLayout(LayoutKind.Sequential)] + public struct Rect2i : IEquatable<Rect2i> + { + private Vector2i _position; + private Vector2i _size; + + public Vector2i Position + { + get { return _position; } + set { _position = value; } + } + + public Vector2i Size + { + get { return _size; } + set { _size = value; } + } + + public Vector2i End + { + get { return _position + _size; } + set { _size = value - _position; } + } + + public int Area + { + get { return GetArea(); } + } + + public Rect2i Abs() + { + Vector2i end = End; + Vector2i topLeft = new Vector2i(Mathf.Min(_position.x, end.x), Mathf.Min(_position.y, end.y)); + return new Rect2i(topLeft, _size.Abs()); + } + + public Rect2i Clip(Rect2i b) + { + var newRect = b; + + if (!Intersects(newRect)) + return new Rect2i(); + + newRect._position.x = Mathf.Max(b._position.x, _position.x); + newRect._position.y = Mathf.Max(b._position.y, _position.y); + + Vector2i bEnd = b._position + b._size; + Vector2i end = _position + _size; + + newRect._size.x = Mathf.Min(bEnd.x, end.x) - newRect._position.x; + newRect._size.y = Mathf.Min(bEnd.y, end.y) - newRect._position.y; + + return newRect; + } + + public bool Encloses(Rect2i b) + { + return b._position.x >= _position.x && b._position.y >= _position.y && + b._position.x + b._size.x < _position.x + _size.x && + b._position.y + b._size.y < _position.y + _size.y; + } + + public Rect2i Expand(Vector2i to) + { + var expanded = this; + + Vector2i begin = expanded._position; + Vector2i end = expanded._position + expanded._size; + + if (to.x < begin.x) + begin.x = to.x; + if (to.y < begin.y) + begin.y = to.y; + + if (to.x > end.x) + end.x = to.x; + if (to.y > end.y) + end.y = to.y; + + expanded._position = begin; + expanded._size = end - begin; + + return expanded; + } + + public int GetArea() + { + return _size.x * _size.y; + } + + public Rect2i Grow(int by) + { + var g = this; + + g._position.x -= by; + g._position.y -= by; + g._size.x += by * 2; + g._size.y += by * 2; + + return g; + } + + public Rect2i GrowIndividual(int left, int top, int right, int bottom) + { + var g = this; + + g._position.x -= left; + g._position.y -= top; + g._size.x += left + right; + g._size.y += top + bottom; + + return g; + } + + public Rect2i GrowMargin(Margin margin, int by) + { + var g = this; + + g.GrowIndividual(Margin.Left == margin ? by : 0, + Margin.Top == margin ? by : 0, + Margin.Right == margin ? by : 0, + Margin.Bottom == margin ? by : 0); + + return g; + } + + public bool HasNoArea() + { + return _size.x <= 0 || _size.y <= 0; + } + + public bool HasPoint(Vector2i point) + { + if (point.x < _position.x) + return false; + if (point.y < _position.y) + return false; + + if (point.x >= _position.x + _size.x) + return false; + if (point.y >= _position.y + _size.y) + return false; + + return true; + } + + public bool Intersects(Rect2i b) + { + if (_position.x >= b._position.x + b._size.x) + return false; + if (_position.x + _size.x <= b._position.x) + return false; + if (_position.y >= b._position.y + b._size.y) + return false; + if (_position.y + _size.y <= b._position.y) + return false; + + return true; + } + + public Rect2i Merge(Rect2i b) + { + Rect2i newRect; + + newRect._position.x = Mathf.Min(b._position.x, _position.x); + newRect._position.y = Mathf.Min(b._position.y, _position.y); + + newRect._size.x = Mathf.Max(b._position.x + b._size.x, _position.x + _size.x); + newRect._size.y = Mathf.Max(b._position.y + b._size.y, _position.y + _size.y); + + newRect._size = newRect._size - newRect._position; // Make relative again + + return newRect; + } + + // Constructors + public Rect2i(Vector2i position, Vector2i size) + { + _position = position; + _size = size; + } + public Rect2i(Vector2i position, int width, int height) + { + _position = position; + _size = new Vector2i(width, height); + } + public Rect2i(int x, int y, Vector2i size) + { + _position = new Vector2i(x, y); + _size = size; + } + public Rect2i(int x, int y, int width, int height) + { + _position = new Vector2i(x, y); + _size = new Vector2i(width, height); + } + + public static bool operator ==(Rect2i left, Rect2i right) + { + return left.Equals(right); + } + + public static bool operator !=(Rect2i left, Rect2i right) + { + return !left.Equals(right); + } + + public static implicit operator Rect2(Rect2i value) + { + return new Rect2(value._position, value._size); + } + + public static explicit operator Rect2i(Rect2 value) + { + return new Rect2i((Vector2i)value.Position, (Vector2i)value.Size); + } + + public override bool Equals(object obj) + { + if (obj is Rect2i) + { + return Equals((Rect2i)obj); + } + + return false; + } + + public bool Equals(Rect2i other) + { + return _position.Equals(other._position) && _size.Equals(other._size); + } + + public override int GetHashCode() + { + return _position.GetHashCode() ^ _size.GetHashCode(); + } + + public override string ToString() + { + return String.Format("{0}, {1}", new object[] + { + _position.ToString(), + _size.ToString() + }); + } + + public string ToString(string format) + { + return String.Format("{0}, {1}", new object[] + { + _position.ToString(format), + _size.ToString(format) + }); + } + } +} diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs index 385bfed122..f7b13198f8 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs @@ -76,11 +76,6 @@ namespace Godot } } - public real_t Cross(Vector2 b) - { - return x * b.y - y * b.x; - } - public Vector2 Abs() { return new Vector2(Mathf.Abs(x), Mathf.Abs(y)); @@ -130,6 +125,11 @@ namespace Godot return v; } + public real_t Cross(Vector2 b) + { + return x * b.y - y * b.x; + } + public Vector2 CubicInterpolate(Vector2 b, Vector2 preA, Vector2 postB, real_t t) { var p0 = preA; @@ -234,7 +234,7 @@ namespace Godot public Vector2 Reflect(Vector2 n) { - return 2.0f * n * Dot(n) - this; + return 2 * Dot(n) * n - this; } public Vector2 Rotated(real_t phi) @@ -352,18 +352,18 @@ namespace Godot return left; } - public static Vector2 operator /(Vector2 vec, real_t scale) + public static Vector2 operator /(Vector2 vec, real_t divisor) { - vec.x /= scale; - vec.y /= scale; + vec.x /= divisor; + vec.y /= divisor; return vec; } - public static Vector2 operator /(Vector2 left, Vector2 right) + public static Vector2 operator /(Vector2 vec, Vector2 divisorv) { - left.x /= right.x; - left.y /= right.y; - return left; + vec.x /= divisorv.x; + vec.y /= divisorv.y; + return vec; } public static Vector2 operator %(Vector2 vec, real_t divisor) diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs new file mode 100644 index 0000000000..7dc22d7918 --- /dev/null +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs @@ -0,0 +1,380 @@ +using System; +using System.Runtime.InteropServices; + +#if REAL_T_IS_DOUBLE +using real_t = System.Double; +#else +using real_t = System.Single; +#endif + +namespace Godot +{ + /// <summary> + /// 2-element structure that can be used to represent 2D grid coordinates or pairs of integers. + /// </summary> + [Serializable] + [StructLayout(LayoutKind.Sequential)] + public struct Vector2i : IEquatable<Vector2i> + { + public enum Axis + { + X = 0, + Y + } + + public int x; + public int y; + + public int this[int index] + { + get + { + switch (index) + { + case 0: + return x; + case 1: + return y; + default: + throw new IndexOutOfRangeException(); + } + } + set + { + switch (index) + { + case 0: + x = value; + return; + case 1: + y = value; + return; + default: + throw new IndexOutOfRangeException(); + } + } + } + + public Vector2i Abs() + { + return new Vector2i(Mathf.Abs(x), Mathf.Abs(y)); + } + + public real_t Angle() + { + return Mathf.Atan2(y, x); + } + + public real_t AngleTo(Vector2i to) + { + return Mathf.Atan2(Cross(to), Dot(to)); + } + + public real_t AngleToPoint(Vector2i to) + { + return Mathf.Atan2(y - to.y, x - to.x); + } + + public real_t Aspect() + { + return x / (real_t)y; + } + + public Vector2i Bounce(Vector2i n) + { + return -Reflect(n); + } + + public int Cross(Vector2i b) + { + return x * b.y - y * b.x; + } + + public int DistanceSquaredTo(Vector2i b) + { + return (b - this).LengthSquared(); + } + + public real_t DistanceTo(Vector2i b) + { + return (b - this).Length(); + } + + public int Dot(Vector2i b) + { + return x * b.x + y * b.y; + } + + public real_t Length() + { + int x2 = x * x; + int y2 = y * y; + + return Mathf.Sqrt(x2 + y2); + } + + public int LengthSquared() + { + int x2 = x * x; + int y2 = y * y; + + return x2 + y2; + } + + public Axis MaxAxis() + { + return x < y ? Axis.Y : Axis.X; + } + + public Axis MinAxis() + { + return x > y ? Axis.Y : Axis.X; + } + + public Vector2i PosMod(int mod) + { + Vector2i v = this; + v.x = Mathf.PosMod(v.x, mod); + v.y = Mathf.PosMod(v.y, mod); + return v; + } + + public Vector2i PosMod(Vector2i modv) + { + Vector2i v = this; + v.x = Mathf.PosMod(v.x, modv.x); + v.y = Mathf.PosMod(v.y, modv.y); + return v; + } + + public Vector2i Reflect(Vector2i n) + { + return 2 * Dot(n) * n - this; + } + + public Vector2i Sign() + { + Vector2i v = this; + v.x = Mathf.Sign(v.x); + v.y = Mathf.Sign(v.y); + return v; + } + + public Vector2i Tangent() + { + return new Vector2i(y, -x); + } + + // Constants + private static readonly Vector2i _zero = new Vector2i(0, 0); + private static readonly Vector2i _one = new Vector2i(1, 1); + + private static readonly Vector2i _up = new Vector2i(0, -1); + private static readonly Vector2i _down = new Vector2i(0, 1); + private static readonly Vector2i _right = new Vector2i(1, 0); + private static readonly Vector2i _left = new Vector2i(-1, 0); + + public static Vector2i Zero { get { return _zero; } } + public static Vector2i One { get { return _one; } } + + public static Vector2i Up { get { return _up; } } + public static Vector2i Down { get { return _down; } } + public static Vector2i Right { get { return _right; } } + public static Vector2i Left { get { return _left; } } + + // Constructors + public Vector2i(int x, int y) + { + this.x = x; + this.y = y; + } + public Vector2i(Vector2i vi) + { + this.x = vi.x; + this.y = vi.y; + } + public Vector2i(Vector2 v) + { + this.x = Mathf.RoundToInt(v.x); + this.y = Mathf.RoundToInt(v.y); + } + + public static Vector2i operator +(Vector2i left, Vector2i right) + { + left.x += right.x; + left.y += right.y; + return left; + } + + public static Vector2i operator -(Vector2i left, Vector2i right) + { + left.x -= right.x; + left.y -= right.y; + return left; + } + + public static Vector2i operator -(Vector2i vec) + { + vec.x = -vec.x; + vec.y = -vec.y; + return vec; + } + + public static Vector2i operator *(Vector2i vec, int scale) + { + vec.x *= scale; + vec.y *= scale; + return vec; + } + + public static Vector2i operator *(int scale, Vector2i vec) + { + vec.x *= scale; + vec.y *= scale; + return vec; + } + + public static Vector2i operator *(Vector2i left, Vector2i right) + { + left.x *= right.x; + left.y *= right.y; + return left; + } + + public static Vector2i operator /(Vector2i vec, int divisor) + { + vec.x /= divisor; + vec.y /= divisor; + return vec; + } + + public static Vector2i operator /(Vector2i vec, Vector2i divisorv) + { + vec.x /= divisorv.x; + vec.y /= divisorv.y; + return vec; + } + + public static Vector2i operator %(Vector2i vec, int divisor) + { + vec.x %= divisor; + vec.y %= divisor; + return vec; + } + + public static Vector2i operator %(Vector2i vec, Vector2i divisorv) + { + vec.x %= divisorv.x; + vec.y %= divisorv.y; + return vec; + } + + public static Vector2i operator &(Vector2i vec, int and) + { + vec.x &= and; + vec.y &= and; + return vec; + } + + public static Vector2i operator &(Vector2i vec, Vector2i andv) + { + vec.x &= andv.x; + vec.y &= andv.y; + return vec; + } + + public static bool operator ==(Vector2i left, Vector2i right) + { + return left.Equals(right); + } + + public static bool operator !=(Vector2i left, Vector2i right) + { + return !left.Equals(right); + } + + public static bool operator <(Vector2i left, Vector2i right) + { + if (left.x.Equals(right.x)) + { + return left.y < right.y; + } + return left.x < right.x; + } + + public static bool operator >(Vector2i left, Vector2i right) + { + if (left.x.Equals(right.x)) + { + return left.y > right.y; + } + return left.x > right.x; + } + + public static bool operator <=(Vector2i left, Vector2i right) + { + if (left.x.Equals(right.x)) + { + return left.y <= right.y; + } + return left.x <= right.x; + } + + public static bool operator >=(Vector2i left, Vector2i right) + { + if (left.x.Equals(right.x)) + { + return left.y >= right.y; + } + return left.x >= right.x; + } + + public static implicit operator Vector2(Vector2i value) + { + return new Vector2(value.x, value.y); + } + + public static explicit operator Vector2i(Vector2 value) + { + return new Vector2i(value); + } + + public override bool Equals(object obj) + { + if (obj is Vector2i) + { + return Equals((Vector2i)obj); + } + + return false; + } + + public bool Equals(Vector2i other) + { + return x == other.x && y == other.y; + } + + public override int GetHashCode() + { + return y.GetHashCode() ^ x.GetHashCode(); + } + + public override string ToString() + { + return String.Format("({0}, {1})", new object[] + { + this.x.ToString(), + this.y.ToString() + }); + } + + public string ToString(string format) + { + return String.Format("({0}, {1})", new object[] + { + this.x.ToString(format), + this.y.ToString(format) + }); + } + } +} diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs index 390036c654..a43836e985 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs @@ -400,20 +400,20 @@ namespace Godot return left; } - public static Vector3 operator /(Vector3 vec, real_t scale) + public static Vector3 operator /(Vector3 vec, real_t divisor) { - vec.x /= scale; - vec.y /= scale; - vec.z /= scale; + vec.x /= divisor; + vec.y /= divisor; + vec.z /= divisor; return vec; } - public static Vector3 operator /(Vector3 left, Vector3 right) + public static Vector3 operator /(Vector3 vec, Vector3 divisorv) { - left.x /= right.x; - left.y /= right.y; - left.z /= right.z; - return left; + vec.x /= divisorv.x; + vec.y /= divisorv.y; + vec.z /= divisorv.z; + return vec; } public static Vector3 operator %(Vector3 vec, real_t divisor) diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs new file mode 100644 index 0000000000..c17f900131 --- /dev/null +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs @@ -0,0 +1,402 @@ +using System; +using System.Runtime.InteropServices; + +#if REAL_T_IS_DOUBLE +using real_t = System.Double; +#else +using real_t = System.Single; +#endif + +namespace Godot +{ + /// <summary> + /// 3-element structure that can be used to represent 3D grid coordinates or sets of integers. + /// </summary> + [Serializable] + [StructLayout(LayoutKind.Sequential)] + public struct Vector3i : IEquatable<Vector3i> + { + public enum Axis + { + X = 0, + Y, + Z + } + + public int x; + public int y; + public int z; + + public int this[int index] + { + get + { + switch (index) + { + case 0: + return x; + case 1: + return y; + case 2: + return z; + default: + throw new IndexOutOfRangeException(); + } + } + set + { + switch (index) + { + case 0: + x = value; + return; + case 1: + y = value; + return; + case 2: + z = value; + return; + default: + throw new IndexOutOfRangeException(); + } + } + } + + public Vector3i Abs() + { + Vector3i v = this; + if (v.x < 0) + { + v.x = -v.x; + } + if (v.y < 0) + { + v.y = -v.y; + } + if (v.z < 0) + { + v.z = -v.z; + } + return v; + } + + public int DistanceSquaredTo(Vector3i b) + { + return (b - this).LengthSquared(); + } + + public real_t DistanceTo(Vector3i b) + { + return (b - this).Length(); + } + + public int Dot(Vector3i b) + { + return x * b.x + y * b.y + z * b.z; + } + + public real_t Length() + { + int x2 = x * x; + int y2 = y * y; + int z2 = z * z; + + return Mathf.Sqrt(x2 + y2 + z2); + } + + public int LengthSquared() + { + int x2 = x * x; + int y2 = y * y; + int z2 = z * z; + + return x2 + y2 + z2; + } + + public Axis MaxAxis() + { + return x < y ? (y < z ? Axis.Z : Axis.Y) : (x < z ? Axis.Z : Axis.X); + } + + public Axis MinAxis() + { + return x < y ? (x < z ? Axis.X : Axis.Z) : (y < z ? Axis.Y : Axis.Z); + } + + public Vector3i PosMod(int mod) + { + Vector3i v = this; + v.x = Mathf.PosMod(v.x, mod); + v.y = Mathf.PosMod(v.y, mod); + v.z = Mathf.PosMod(v.z, mod); + return v; + } + + public Vector3i PosMod(Vector3i modv) + { + Vector3i v = this; + v.x = Mathf.PosMod(v.x, modv.x); + v.y = Mathf.PosMod(v.y, modv.y); + v.z = Mathf.PosMod(v.z, modv.z); + return v; + } + + public Vector3i Sign() + { + Vector3i v = this; + v.x = Mathf.Sign(v.x); + v.y = Mathf.Sign(v.y); + v.z = Mathf.Sign(v.z); + return v; + } + + // Constants + private static readonly Vector3i _zero = new Vector3i(0, 0, 0); + private static readonly Vector3i _one = new Vector3i(1, 1, 1); + + private static readonly Vector3i _up = new Vector3i(0, 1, 0); + private static readonly Vector3i _down = new Vector3i(0, -1, 0); + private static readonly Vector3i _right = new Vector3i(1, 0, 0); + private static readonly Vector3i _left = new Vector3i(-1, 0, 0); + private static readonly Vector3i _forward = new Vector3i(0, 0, -1); + private static readonly Vector3i _back = new Vector3i(0, 0, 1); + + public static Vector3i Zero { get { return _zero; } } + public static Vector3i One { get { return _one; } } + + public static Vector3i Up { get { return _up; } } + public static Vector3i Down { get { return _down; } } + public static Vector3i Right { get { return _right; } } + public static Vector3i Left { get { return _left; } } + public static Vector3i Forward { get { return _forward; } } + public static Vector3i Back { get { return _back; } } + + // Constructors + public Vector3i(int x, int y, int z) + { + this.x = x; + this.y = y; + this.z = z; + } + public Vector3i(Vector3i vi) + { + this.x = vi.x; + this.y = vi.y; + this.z = vi.z; + } + public Vector3i(Vector3 v) + { + this.x = Mathf.RoundToInt(v.x); + this.y = Mathf.RoundToInt(v.y); + this.z = Mathf.RoundToInt(v.z); + } + + public static Vector3i operator +(Vector3i left, Vector3i right) + { + left.x += right.x; + left.y += right.y; + left.z += right.z; + return left; + } + + public static Vector3i operator -(Vector3i left, Vector3i right) + { + left.x -= right.x; + left.y -= right.y; + left.z -= right.z; + return left; + } + + public static Vector3i operator -(Vector3i vec) + { + vec.x = -vec.x; + vec.y = -vec.y; + vec.z = -vec.z; + return vec; + } + + public static Vector3i operator *(Vector3i vec, int scale) + { + vec.x *= scale; + vec.y *= scale; + vec.z *= scale; + return vec; + } + + public static Vector3i operator *(int scale, Vector3i vec) + { + vec.x *= scale; + vec.y *= scale; + vec.z *= scale; + return vec; + } + + public static Vector3i operator *(Vector3i left, Vector3i right) + { + left.x *= right.x; + left.y *= right.y; + left.z *= right.z; + return left; + } + + public static Vector3i operator /(Vector3i vec, int divisor) + { + vec.x /= divisor; + vec.y /= divisor; + vec.z /= divisor; + return vec; + } + + public static Vector3i operator /(Vector3i vec, Vector3i divisorv) + { + vec.x /= divisorv.x; + vec.y /= divisorv.y; + vec.z /= divisorv.z; + return vec; + } + + public static Vector3i operator %(Vector3i vec, int divisor) + { + vec.x %= divisor; + vec.y %= divisor; + vec.z %= divisor; + return vec; + } + + public static Vector3i operator %(Vector3i vec, Vector3i divisorv) + { + vec.x %= divisorv.x; + vec.y %= divisorv.y; + vec.z %= divisorv.z; + return vec; + } + + public static Vector3i operator &(Vector3i vec, int and) + { + vec.x &= and; + vec.y &= and; + vec.z &= and; + return vec; + } + + public static Vector3i operator &(Vector3i vec, Vector3i andv) + { + vec.x &= andv.x; + vec.y &= andv.y; + vec.z &= andv.z; + return vec; + } + + public static bool operator ==(Vector3i left, Vector3i right) + { + return left.Equals(right); + } + + public static bool operator !=(Vector3i left, Vector3i right) + { + return !left.Equals(right); + } + + public static bool operator <(Vector3i left, Vector3i right) + { + if (left.x == right.x) + { + if (left.y == right.y) + return left.z < right.z; + else + return left.y < right.y; + } + + return left.x < right.x; + } + + public static bool operator >(Vector3i left, Vector3i right) + { + if (left.x == right.x) + { + if (left.y == right.y) + return left.z > right.z; + else + return left.y > right.y; + } + + return left.x > right.x; + } + + public static bool operator <=(Vector3i left, Vector3i right) + { + if (left.x == right.x) + { + if (left.y == right.y) + return left.z <= right.z; + else + return left.y < right.y; + } + + return left.x < right.x; + } + + public static bool operator >=(Vector3i left, Vector3i right) + { + if (left.x == right.x) + { + if (left.y == right.y) + return left.z >= right.z; + else + return left.y > right.y; + } + + return left.x > right.x; + } + + public static implicit operator Vector3(Vector3i value) + { + return new Vector3(value.x, value.y, value.z); + } + + public static explicit operator Vector3i(Vector3 value) + { + return new Vector3i(value); + } + + public override bool Equals(object obj) + { + if (obj is Vector3i) + { + return Equals((Vector3i)obj); + } + + return false; + } + + public bool Equals(Vector3i other) + { + return x == other.x && y == other.y && z == other.z; + } + + public override int GetHashCode() + { + return y.GetHashCode() ^ x.GetHashCode() ^ z.GetHashCode(); + } + + public override string ToString() + { + return String.Format("({0}, {1}, {2})", new object[] + { + this.x.ToString(), + this.y.ToString(), + this.z.ToString() + }); + } + + public string ToString(string format) + { + return String.Format("({0}, {1}, {2})", new object[] + { + this.x.ToString(format), + this.y.ToString(format), + this.z.ToString(format) + }); + } + } +} diff --git a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj index 799322c529..ba0bbd7630 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj +++ b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj @@ -67,6 +67,7 @@ <Compile Include="Core\Plane.cs" /> <Compile Include="Core\Quat.cs" /> <Compile Include="Core\Rect2.cs" /> + <Compile Include="Core\Rect2i.cs" /> <Compile Include="Core\RID.cs" /> <Compile Include="Core\SignalInfo.cs" /> <Compile Include="Core\SignalAwaiter.cs" /> @@ -75,7 +76,9 @@ <Compile Include="Core\Transform.cs" /> <Compile Include="Core\Transform2D.cs" /> <Compile Include="Core\Vector2.cs" /> + <Compile Include="Core\Vector2i.cs" /> <Compile Include="Core\Vector3.cs" /> + <Compile Include="Core\Vector3i.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> </ItemGroup> <!-- diff --git a/modules/mono/mono_gd/gd_mono_cache.cpp b/modules/mono/mono_gd/gd_mono_cache.cpp index 418de87b5d..be0b846702 100644 --- a/modules/mono/mono_gd/gd_mono_cache.cpp +++ b/modules/mono/mono_gd/gd_mono_cache.cpp @@ -103,9 +103,12 @@ void CachedData::clear_godot_api_cache() { rawclass_Dictionary = NULL; class_Vector2 = NULL; + class_Vector2i = NULL; class_Rect2 = NULL; + class_Rect2i = NULL; class_Transform2D = NULL; class_Vector3 = NULL; + class_Vector3i = NULL; class_Basis = NULL; class_Quat = NULL; class_Transform = NULL; @@ -229,9 +232,12 @@ void update_corlib_cache() { void update_godot_api_cache() { CACHE_CLASS_AND_CHECK(Vector2, GODOT_API_CLASS(Vector2)); + CACHE_CLASS_AND_CHECK(Vector2i, GODOT_API_CLASS(Vector2i)); CACHE_CLASS_AND_CHECK(Rect2, GODOT_API_CLASS(Rect2)); + CACHE_CLASS_AND_CHECK(Rect2i, GODOT_API_CLASS(Rect2i)); CACHE_CLASS_AND_CHECK(Transform2D, GODOT_API_CLASS(Transform2D)); CACHE_CLASS_AND_CHECK(Vector3, GODOT_API_CLASS(Vector3)); + CACHE_CLASS_AND_CHECK(Vector3i, GODOT_API_CLASS(Vector3i)); CACHE_CLASS_AND_CHECK(Basis, GODOT_API_CLASS(Basis)); CACHE_CLASS_AND_CHECK(Quat, GODOT_API_CLASS(Quat)); CACHE_CLASS_AND_CHECK(Transform, GODOT_API_CLASS(Transform)); diff --git a/modules/mono/mono_gd/gd_mono_cache.h b/modules/mono/mono_gd/gd_mono_cache.h index a0e1879c5a..b2dacee67c 100644 --- a/modules/mono/mono_gd/gd_mono_cache.h +++ b/modules/mono/mono_gd/gd_mono_cache.h @@ -73,9 +73,12 @@ struct CachedData { // ----------------------------------------------- GDMonoClass *class_Vector2; + GDMonoClass *class_Vector2i; GDMonoClass *class_Rect2; + GDMonoClass *class_Rect2i; GDMonoClass *class_Transform2D; GDMonoClass *class_Vector3; + GDMonoClass *class_Vector3i; GDMonoClass *class_Basis; GDMonoClass *class_Quat; GDMonoClass *class_Transform; diff --git a/modules/mono/mono_gd/gd_mono_field.cpp b/modules/mono/mono_gd/gd_mono_field.cpp index 76d781cc4d..11942c47d9 100644 --- a/modules/mono/mono_gd/gd_mono_field.cpp +++ b/modules/mono/mono_gd/gd_mono_field.cpp @@ -132,11 +132,21 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ break; } + if (tclass == CACHED_CLASS(Vector2i)) { + SET_FROM_STRUCT(Vector2i); + break; + } + if (tclass == CACHED_CLASS(Rect2)) { SET_FROM_STRUCT(Rect2); break; } + if (tclass == CACHED_CLASS(Rect2i)) { + SET_FROM_STRUCT(Rect2i); + break; + } + if (tclass == CACHED_CLASS(Transform2D)) { SET_FROM_STRUCT(Transform2D); break; @@ -147,6 +157,11 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ break; } + if (tclass == CACHED_CLASS(Vector3i)) { + SET_FROM_STRUCT(Vector3i); + break; + } + if (tclass == CACHED_CLASS(Basis)) { SET_FROM_STRUCT(Basis); break; @@ -418,12 +433,21 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ case Variant::VECTOR2: { SET_FROM_STRUCT(Vector2); } break; + case Variant::VECTOR2I: { + SET_FROM_STRUCT(Vector2i); + } break; case Variant::RECT2: { SET_FROM_STRUCT(Rect2); } break; + case Variant::RECT2I: { + SET_FROM_STRUCT(Rect2i); + } break; case Variant::VECTOR3: { SET_FROM_STRUCT(Vector3); } break; + case Variant::VECTOR3I: { + SET_FROM_STRUCT(Vector3i); + } break; case Variant::TRANSFORM2D: { SET_FROM_STRUCT(Transform2D); } break; diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp index f937e09eaf..0de5352752 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.cpp +++ b/modules/mono/mono_gd/gd_mono_marshal.cpp @@ -75,15 +75,24 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_ if (vtclass == CACHED_CLASS(Vector2)) return Variant::VECTOR2; + if (vtclass == CACHED_CLASS(Vector2i)) + return Variant::VECTOR2I; + if (vtclass == CACHED_CLASS(Rect2)) return Variant::RECT2; + if (vtclass == CACHED_CLASS(Rect2i)) + return Variant::RECT2I; + if (vtclass == CACHED_CLASS(Transform2D)) return Variant::TRANSFORM2D; if (vtclass == CACHED_CLASS(Vector3)) return Variant::VECTOR3; + if (vtclass == CACHED_CLASS(Vector3i)) + return Variant::VECTOR3I; + if (vtclass == CACHED_CLASS(Basis)) return Variant::BASIS; @@ -413,11 +422,21 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector2), &from); } + if (vtclass == CACHED_CLASS(Vector2i)) { + GDMonoMarshal::M_Vector2i from = MARSHALLED_OUT(Vector2i, p_var->operator ::Vector2i()); + return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector2i), &from); + } + if (vtclass == CACHED_CLASS(Rect2)) { GDMonoMarshal::M_Rect2 from = MARSHALLED_OUT(Rect2, p_var->operator ::Rect2()); return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Rect2), &from); } + if (vtclass == CACHED_CLASS(Rect2i)) { + GDMonoMarshal::M_Rect2i from = MARSHALLED_OUT(Rect2i, p_var->operator ::Rect2i()); + return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Rect2i), &from); + } + if (vtclass == CACHED_CLASS(Transform2D)) { GDMonoMarshal::M_Transform2D from = MARSHALLED_OUT(Transform2D, p_var->operator ::Transform2D()); return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Transform2D), &from); @@ -428,6 +447,11 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector3), &from); } + if (vtclass == CACHED_CLASS(Vector3i)) { + GDMonoMarshal::M_Vector3i from = MARSHALLED_OUT(Vector3i, p_var->operator ::Vector3i()); + return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector3i), &from); + } + if (vtclass == CACHED_CLASS(Basis)) { GDMonoMarshal::M_Basis from = MARSHALLED_OUT(Basis, p_var->operator ::Basis()); return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Basis), &from); @@ -638,14 +662,26 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty GDMonoMarshal::M_Vector2 from = MARSHALLED_OUT(Vector2, p_var->operator ::Vector2()); return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector2), &from); } + case Variant::VECTOR2I: { + GDMonoMarshal::M_Vector2i from = MARSHALLED_OUT(Vector2i, p_var->operator ::Vector2i()); + return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector2i), &from); + } case Variant::RECT2: { GDMonoMarshal::M_Rect2 from = MARSHALLED_OUT(Rect2, p_var->operator ::Rect2()); return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Rect2), &from); } + case Variant::RECT2I: { + GDMonoMarshal::M_Rect2i from = MARSHALLED_OUT(Rect2i, p_var->operator ::Rect2i()); + return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Rect2i), &from); + } case Variant::VECTOR3: { GDMonoMarshal::M_Vector3 from = MARSHALLED_OUT(Vector3, p_var->operator ::Vector3()); return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector3), &from); } + case Variant::VECTOR3I: { + GDMonoMarshal::M_Vector3i from = MARSHALLED_OUT(Vector3i, p_var->operator ::Vector3i()); + return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector3i), &from); + } case Variant::TRANSFORM2D: { GDMonoMarshal::M_Transform2D from = MARSHALLED_OUT(Transform2D, p_var->operator ::Transform2D()); return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Transform2D), &from); @@ -806,15 +842,24 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type if (vtclass == CACHED_CLASS(Vector2)) return MARSHALLED_IN(Vector2, unbox_addr<GDMonoMarshal::M_Vector2>(p_obj)); + if (vtclass == CACHED_CLASS(Vector2i)) + return MARSHALLED_IN(Vector2i, unbox_addr<GDMonoMarshal::M_Vector2i>(p_obj)); + if (vtclass == CACHED_CLASS(Rect2)) return MARSHALLED_IN(Rect2, unbox_addr<GDMonoMarshal::M_Rect2>(p_obj)); + if (vtclass == CACHED_CLASS(Rect2i)) + return MARSHALLED_IN(Rect2i, unbox_addr<GDMonoMarshal::M_Rect2i>(p_obj)); + if (vtclass == CACHED_CLASS(Transform2D)) return MARSHALLED_IN(Transform2D, unbox_addr<GDMonoMarshal::M_Transform2D>(p_obj)); if (vtclass == CACHED_CLASS(Vector3)) return MARSHALLED_IN(Vector3, unbox_addr<GDMonoMarshal::M_Vector3>(p_obj)); + if (vtclass == CACHED_CLASS(Vector3i)) + return MARSHALLED_IN(Vector3i, unbox_addr<GDMonoMarshal::M_Vector3i>(p_obj)); + if (vtclass == CACHED_CLASS(Basis)) return MARSHALLED_IN(Basis, unbox_addr<GDMonoMarshal::M_Basis>(p_obj)); diff --git a/modules/mono/mono_gd/gd_mono_marshal.h b/modules/mono/mono_gd/gd_mono_marshal.h index 54ce588baa..7d09f46b00 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.h +++ b/modules/mono/mono_gd/gd_mono_marshal.h @@ -201,6 +201,8 @@ M_SignalInfo signal_info_to_managed(const Signal &p_signal); namespace InteropLayout { enum { + MATCHES_int = (sizeof(int32_t) == sizeof(uint32_t)), + MATCHES_float = (sizeof(float) == sizeof(uint32_t)), MATCHES_double = (sizeof(double) == sizeof(uint64_t)), @@ -215,10 +217,18 @@ enum { offsetof(Vector2, x) == (sizeof(real_t) * 0) && offsetof(Vector2, y) == (sizeof(real_t) * 1)), + MATCHES_Vector2i = (MATCHES_int && (sizeof(Vector2i) == (sizeof(int32_t) * 2)) && + offsetof(Vector2i, x) == (sizeof(int32_t) * 0) && + offsetof(Vector2i, y) == (sizeof(int32_t) * 1)), + MATCHES_Rect2 = (MATCHES_Vector2 && (sizeof(Rect2) == (sizeof(Vector2) * 2)) && offsetof(Rect2, position) == (sizeof(Vector2) * 0) && offsetof(Rect2, size) == (sizeof(Vector2) * 1)), + MATCHES_Rect2i = (MATCHES_Vector2i && (sizeof(Rect2i) == (sizeof(Vector2i) * 2)) && + offsetof(Rect2i, position) == (sizeof(Vector2i) * 0) && + offsetof(Rect2i, size) == (sizeof(Vector2i) * 1)), + MATCHES_Transform2D = (MATCHES_Vector2 && (sizeof(Transform2D) == (sizeof(Vector2) * 3))), // No field offset required, it stores an array MATCHES_Vector3 = (MATCHES_real_t && (sizeof(Vector3) == (sizeof(real_t) * 3)) && @@ -226,6 +236,11 @@ enum { offsetof(Vector3, y) == (sizeof(real_t) * 1) && offsetof(Vector3, z) == (sizeof(real_t) * 2)), + MATCHES_Vector3i = (MATCHES_int && (sizeof(Vector3i) == (sizeof(int32_t) * 3)) && + offsetof(Vector3i, x) == (sizeof(int32_t) * 0) && + offsetof(Vector3i, y) == (sizeof(int32_t) * 1) && + offsetof(Vector3i, z) == (sizeof(int32_t) * 2)), + MATCHES_Basis = (MATCHES_Vector3 && (sizeof(Basis) == (sizeof(Vector3) * 3))), // No field offset required, it stores an array MATCHES_Quat = (MATCHES_real_t && (sizeof(Quat) == (sizeof(real_t) * 4)) && @@ -257,7 +272,8 @@ enum { #ifdef GD_MONO_FORCE_INTEROP_STRUCT_COPY /* clang-format off */ static_assert(MATCHES_Vector2 && MATCHES_Rect2 && MATCHES_Transform2D && MATCHES_Vector3 && - MATCHES_Basis && MATCHES_Quat && MATCHES_Transform && MATCHES_AABB && MATCHES_Color && MATCHES_Plane); + MATCHES_Basis && MATCHES_Quat && MATCHES_Transform && MATCHES_AABB && MATCHES_Color && + MATCHES_Plane && MATCHES_Vector2i && MATCHES_Rect2i && MATCHES_Vector3i); /* clang-format on */ #endif @@ -278,6 +294,19 @@ struct M_Vector2 { } }; +struct M_Vector2i { + int32_t x, y; + + static _FORCE_INLINE_ Vector2i convert_to(const M_Vector2i &p_from) { + return Vector2i(p_from.x, p_from.y); + } + + static _FORCE_INLINE_ M_Vector2i convert_from(const Vector2i &p_from) { + M_Vector2i ret = { p_from.x, p_from.y }; + return ret; + } +}; + struct M_Rect2 { M_Vector2 position; M_Vector2 size; @@ -293,6 +322,21 @@ struct M_Rect2 { } }; +struct M_Rect2i { + M_Vector2i position; + M_Vector2i size; + + static _FORCE_INLINE_ Rect2i convert_to(const M_Rect2i &p_from) { + return Rect2i(M_Vector2i::convert_to(p_from.position), + M_Vector2i::convert_to(p_from.size)); + } + + static _FORCE_INLINE_ M_Rect2i convert_from(const Rect2i &p_from) { + M_Rect2i ret = { M_Vector2i::convert_from(p_from.position), M_Vector2i::convert_from(p_from.size) }; + return ret; + } +}; + struct M_Transform2D { M_Vector2 elements[3]; @@ -325,6 +369,19 @@ struct M_Vector3 { } }; +struct M_Vector3i { + int32_t x, y, z; + + static _FORCE_INLINE_ Vector3i convert_to(const M_Vector3i &p_from) { + return Vector3i(p_from.x, p_from.y, p_from.z); + } + + static _FORCE_INLINE_ M_Vector3i convert_from(const Vector3i &p_from) { + M_Vector3i ret = { p_from.x, p_from.y, p_from.z }; + return ret; + } +}; + struct M_Basis { M_Vector3 elements[3]; @@ -450,9 +507,12 @@ struct M_Plane { } DECL_TYPE_MARSHAL_TEMPLATES(Vector2) +DECL_TYPE_MARSHAL_TEMPLATES(Vector2i) DECL_TYPE_MARSHAL_TEMPLATES(Rect2) +DECL_TYPE_MARSHAL_TEMPLATES(Rect2i) DECL_TYPE_MARSHAL_TEMPLATES(Transform2D) DECL_TYPE_MARSHAL_TEMPLATES(Vector3) +DECL_TYPE_MARSHAL_TEMPLATES(Vector3i) DECL_TYPE_MARSHAL_TEMPLATES(Basis) DECL_TYPE_MARSHAL_TEMPLATES(Quat) DECL_TYPE_MARSHAL_TEMPLATES(Transform) |