-
-
Notifications
You must be signed in to change notification settings - Fork 17
Expand file tree
/
Copy pathShape.cs
More file actions
111 lines (95 loc) · 4.4 KB
/
Copy pathShape.cs
File metadata and controls
111 lines (95 loc) · 4.4 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
using System;
namespace Box3D
{
/// <summary>A collision shape attached to a body. Thin value wrapper over a shape id.</summary>
public partial struct Shape : IEquatable<Shape>
{
public ShapeId Id;
/// <summary>Wraps a shape id — the way back into the wrapper API from ids delivered by
/// events (e.g. <see cref="ContactBeginTouchEvent.ShapeIdA"/>) or query results. Cheap and
/// unchecked; test <see cref="IsValid"/>, or use <see cref="World.TryGetShape"/> for the
/// validated form.</summary>
public Shape(ShapeId id) => Id = id;
public bool IsValid => UnsafeBindings.b3Shape_IsValid(Id);
public void Destroy(bool updateBodyMass = true)
{
if (Id.IsNull) return; // double-destroy would pass a null id into unvalidated native paths
UnsafeBindings.b3DestroyShape(Id, updateBodyMass);
Id = default;
}
/// <summary>Application-specific data attached to the shape.</summary>
public unsafe IntPtr UserData
{
get => (IntPtr)UnsafeBindings.b3Shape_GetUserData(Id);
set => UnsafeBindings.b3Shape_SetUserData(Id, (void*)value);
}
/// <summary>The body-local bounding box of a hull shape's vertices. Only valid for
/// <see cref="ShapeType.Hull"/> shapes; box hulls are exactly this box. Useful for building
/// an oriented-box approximation of the hull in world space (bounds × body transform).</summary>
public unsafe B3Aabb GetHullLocalBounds() => UnsafeBindings.b3Shape_GetHull(Id)->Aabb;
/// <summary>Replaces the sphere geometry of a sphere shape.</summary>
public unsafe void SetSphere(in Sphere sphere)
{
Sphere local = sphere;
UnsafeBindings.b3Shape_SetSphere(Id, &local);
}
/// <summary>Replaces the capsule geometry of a capsule shape.</summary>
public unsafe void SetCapsule(in Capsule capsule)
{
Capsule local = capsule;
UnsafeBindings.b3Shape_SetCapsule(Id, &local);
}
/// <summary>Snapshots every contact currently on this shape — the touching shapes and their
/// manifold(s) (points, normal, separation, impulses), as of the last <c>World.Step</c>.
///
/// <para>Each native b3ContactData reaches its manifolds through internal engine memory that
/// may become invalid — that pointer must never be stored. This copies the manifold data into
/// managed memory here, so every returned <see cref="ContactData"/> is a safe snapshot.
/// Querying contacts needs no opt-in (unlike the contact <i>event</i> stream, which requires
/// <c>ShapeDef.EnableContactEvents</c>).</para>
///
/// <para>Because box3d uses speculative collision, some points may be separated (positive
/// <see cref="ManifoldPoint.Separation"/>) — near but not yet touching. Filter on
/// <c>Separation <= 0</c> if you only want points in contact. (<see cref="Body.GetContacts"/>
/// returns only touching contacts.)</para></summary>
public unsafe ContactData[] GetContacts()
{
int capacity = UnsafeBindings.b3Shape_GetContactCapacity(Id);
if (capacity == 0) return Array.Empty<ContactData>();
Span<b3ContactData> buffer = capacity <= 32
? stackalloc b3ContactData[capacity]
: new b3ContactData[capacity];
int count;
fixed (b3ContactData* p = buffer)
{
count = UnsafeBindings.b3Shape_GetContactData(Id, p, capacity);
}
var result = new ContactData[count];
for (int i = 0; i < count; i++)
{
result[i] = ContactData.FromNative(buffer[i]);
}
return result;
}
public bool Equals(Shape other)
{
return Id.Equals(other.Id);
}
public override bool Equals(object obj)
{
return obj is Shape other && Equals(other);
}
public override int GetHashCode()
{
return Id.GetHashCode();
}
public static bool operator ==(Shape left, Shape right)
{
return left.Equals(right);
}
public static bool operator !=(Shape left, Shape right)
{
return !left.Equals(right);
}
}
}