-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathUnityPhysics2D.cs
More file actions
113 lines (95 loc) · 3.94 KB
/
Copy pathUnityPhysics2D.cs
File metadata and controls
113 lines (95 loc) · 3.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
namespace UnityIceFebruary
{
using IceFebruary;
using IceFebruary.Collections;
using IceFebruary.Physics;
using IceFebruary.Shapes;
using IceFebruary.Space;
using UnityIceFebruary.Adaptation;
using static UnityEngine.Physics2D;
using UnityCollider2D = UnityEngine.Collider2D;
using UnityContactFilter2D = UnityEngine.ContactFilter2D;
using UnityVector2 = UnityEngine.Vector2;
/// <summary>
/// Unity realization of the main interface for controlling physics and overlapping.
/// Controls the execution of overlapping.
/// </summary>
public sealed class UnityPhysics2D : BaseEntity, IPhysics2D
{
private UnityCollider2D[] _collidersBuffer;
private IShape _shape;
private UnityVector2 _position;
private UnityContactFilter2D _contactFilter2D;
private float _angle;
private UnityVector2 _rectangleSize;
private float _circleRadius;
/// <summary>
/// Creates a new Unity realization of the main interface for controlling physics and overlapping.
/// </summary>
public UnityPhysics2D(int collidersBufferLength)
{
_collidersBuffer = new UnityCollider2D[collidersBufferLength.ClampForArray()];
}
/// <summary>
/// Scans physical objects in a certain area.
/// </summary>
public int Overlap(IShape shape, Vector2 position, Rotor2 rotor, ContactFilter2D contactFilter2D, Component<ICollider2D>[] result = null) => Overlap(shape, position, rotor.ToAngle(false), contactFilter2D, result);
/// <summary>
/// Scans physical objects in a certain area.
/// </summary>
public int Overlap(IShape shape, Vector2 position, float angle, ContactFilter2D contactFilter2D, Component<ICollider2D>[] result = null)
{
if (shape == null)
return 0;
FillData(shape, position, angle, contactFilter2D);
int count = Math.Min(result.Length, Overlap());
if (result.Exists())
FillArray(result, count);
return count;
}
private void FillArray(Component<ICollider2D>[] result, int count)
{
for (int index = 0; index < count; index++)
{
UnityCollider2D unityCollider2D = _collidersBuffer[index];
ICollider2D collider2D = UnityMethods.Upsert<UnityCollider2D, ICollider2D>(unityCollider2D);
IGameObject gameObject = UnityMethods.Upsert<UnityEngine.GameObject, IGameObject>(unityCollider2D.gameObject);
result[index] = new(collider2D, gameObject);
}
}
private void FillData(IShape shape, Vector2 position, float angle, ContactFilter2D contactFilter2D)
{
_shape = shape;
_position = position.ToUnity();
_angle = angle;
_contactFilter2D = contactFilter2D.ToUnity();
switch (shape)
{
case Circle circle:
_circleRadius = circle.Radius;
break;
case Rectangle rectangle:
_rectangleSize = rectangle.Size.ToUnity();
break;
}
}
private int Overlap()
{
int count = UnityOverlap();
if (count == _collidersBuffer.Length)
{
int power = Math.GetPower2WithReserve(count);
_collidersBuffer = new UnityCollider2D[1 << power];
return Overlap();
}
return count;
}
private int UnityOverlap() => _shape switch
{
Dot => OverlapPoint(_position, _contactFilter2D, _collidersBuffer),
Circle => OverlapCircle(_position, _circleRadius, _contactFilter2D, _collidersBuffer),
Rectangle => OverlapBox(_position, _rectangleSize, _angle, _contactFilter2D, _collidersBuffer),
_ => 0
};
}
}