forked from Unity-Technologies/EntityComponentSystemSamples
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPhysicsSamplesExtensions.cs
More file actions
166 lines (156 loc) · 9.41 KB
/
Copy pathPhysicsSamplesExtensions.cs
File metadata and controls
166 lines (156 loc) · 9.41 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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
using Unity.Assertions;
using Unity.Collections;
using Unity.Entities;
using Unity.Mathematics;
namespace Unity.Physics.Extensions
{
/// <summary>
/// Utility functions acting on physics components.
/// </summary>
public static class PhysicsSamplesExtensions
{
/// <summary>
/// Given the root Collider of a hierarchy and a ColliderKey referencing a child in that hierarchy,
/// this function returns the ColliderKey referencing the parent Collider.
/// </summary>
/// <param name="rootColliderPtr">A <see cref="Collider"/> at the root of a Collider hierarchy.</param>
/// <param name="childColliderKey">A <see cref="ColliderKey"/> referencing a child Collider somewhere in the hierarchy below rootColliderPtr.</param>
/// <param name="parentColliderKey">A <see cref="ColliderKey"/> referencing the parent of the child Collider. Will be ColliderKey.Empty if the parameters where invalid.</param>
/// <returns>Whether the parent was successfully found in the hierarchy.</returns>
public static unsafe bool TryGetParentColliderKey(Collider* rootColliderPtr, ColliderKey childColliderKey, out ColliderKey parentColliderKey)
{
var childColliderPtr = rootColliderPtr;
var childColliderKeyNumBits = childColliderPtr->NumColliderKeyBits;
// Start with an Empty collider key and push sub keys onto it as we traverse down the compound hierarchy.
var parentColliderKeyPath = ColliderKeyPath.Empty;
// On the way down, the childColliderKey pops of sub keys and pushes them onto the parentColliderKeyPath
do
{
childColliderKey.PopSubKey(childColliderKeyNumBits, out var childIndex);
switch (childColliderPtr->Type)
{
case ColliderType.Compound:
// Get the next child down and loop again
parentColliderKeyPath.PushChildKey(new ColliderKeyPath(new ColliderKey(childColliderKeyNumBits, childIndex), childColliderKeyNumBits));
childColliderPtr = ((CompoundCollider*)childColliderPtr)->Children[(int)childIndex].Collider;
childColliderKeyNumBits = childColliderPtr->NumColliderKeyBits;
break;
case ColliderType.Mesh:
case ColliderType.Terrain:
// We've hit a Terrain or Mesh collider so there should only be PolygonColliders below this.
// At this point the childColliderKey should be Empty and childIndex should be the index of the polygon.
if (!childColliderKey.Equals(ColliderKey.Empty))
{
// We've reached the bottom without popping all the child keys.
// The given childColliderKey doesn't fit this hierarchy!
parentColliderKey = ColliderKey.Empty;
return false;
}
break;
default:
// We've hit a Convex collider, so rootColliderPtr must not have been
// the root of a hierarchy in the first place and so there is no parent!
parentColliderKey = ColliderKey.Empty;
return false;
}
}
while (!childColliderKey.Equals(ColliderKey.Empty)
&& !childColliderPtr->CollisionType.Equals(CollisionType.Convex));
parentColliderKey = parentColliderKeyPath.Key;
// childColliderKey should be Empty at this point.
// However, if it isn't then we reached a leaf without finding the child collider!
return childColliderKey.Equals(ColliderKey.Empty);
}
/// <summary>
/// Given the root Collider of a hierarchy and a ColliderKey referencing a child in that hierarchy,
/// this function returns the ChildCollider requested.
/// </summary>
/// <param name="rootColliderPtr">A <see cref="Collider"/> at the root of a Collider hierarchy.</param>
/// <param name="childColliderKey">A <see cref="ColliderKey"/> referencing a child Collider somewhere in the hierarchy below rootColliderPtr.</param>
/// <param name="childCollider">A valid <see cref="ChildCollider"/> returned from the hierarchy, if found.</param>
/// <returns>Whether a specified ColliderKey was successfully found in the hierarchy.</returns>
public static unsafe bool TryGetChildInHierarchy(Collider* rootColliderPtr, ColliderKey childColliderKey, out ChildCollider childCollider)
{
//public static unsafe bool GetLeafCollider(Collider* root, RigidTransform rootTransform, ColliderKey key, out ChildCollider leaf)
childCollider = new ChildCollider(rootColliderPtr, RigidTransform.identity);
while (!childColliderKey.Equals(ColliderKey.Empty))
{
if (!childCollider.Collider->GetChild(ref childColliderKey, out ChildCollider child))
{
break;
}
childCollider = new ChildCollider(childCollider, child);
}
return (childCollider.Collider != null);
}
/// <summary>
/// Remaps the Entity references baked into a CompoundCollider from one hierarchy to a new one.
/// </summary>
/// <param name="compoundColliderPtr">A <see cref="CompoundCollider"/> with old Entity references, e.g. a new instance.</param>
/// <param name="keyEntityPairs">An array of <see cref="ColliderKey"/> and <see cref="Entity"/> pairs.</param>
public static unsafe void RemapColliderEntityReferences(
CompoundCollider* compoundColliderPtr, in NativeArray<PhysicsColliderKeyEntityPair> keyEntityPairs) =>
RemapCompoundColliderEntityReferences(compoundColliderPtr, keyEntityPairs, ColliderKey.Empty);
/// <summary>
/// Remaps the Entity references baked into a CompoundCollider from one hierarchy to a new one, via the LinkedEntityGroup arrays.
/// </summary>
/// <param name="compoundColliderPtr">A <see cref="CompoundCollider"/> with old Entity references, e.g. a new instance.</param>
/// <param name="oldLinkedEntityGroup">An array of <see cref="LinkedEntityGroup"/> from an original hierarchy e.g. a prefab.</param>
/// <param name="newLinkedEntityGroup">An array of <see cref="LinkedEntityGroup"/> from a new hierarchy e.g. an instance.</param>
public static unsafe void RemapCompoundColliderEntityReferences(
CompoundCollider* compoundColliderPtr,
in NativeArray<LinkedEntityGroup> oldLinkedEntityGroup,
in NativeArray<LinkedEntityGroup> newLinkedEntityGroup) =>
RemapCompoundColliderEntityReferences(compoundColliderPtr, oldLinkedEntityGroup, newLinkedEntityGroup, ColliderKey.Empty);
internal static unsafe void RemapCompoundColliderEntityReferences(
CompoundCollider* compoundColliderPtr,
in NativeArray<PhysicsColliderKeyEntityPair> keyEntityPairs,
in ColliderKey key)
{
for (int childIndex = 0; childIndex < compoundColliderPtr->Children.Length; childIndex++)
{
ref CompoundCollider.Child child = ref compoundColliderPtr->Children[childIndex];
var childKey = key; childKey.PushSubKey(compoundColliderPtr->NumColliderKeyBits, (uint)childIndex);
for (int i = 0; i < keyEntityPairs.Length; i++)
{
if (childKey.Equals(keyEntityPairs[i].Key))
{
child.Entity = keyEntityPairs[i].Entity;
break;
}
}
if (child.Collider->Type == ColliderType.Compound)
{
RemapCompoundColliderEntityReferences((CompoundCollider*)child.Collider, keyEntityPairs, childKey);
}
}
}
internal static unsafe void RemapCompoundColliderEntityReferences(
CompoundCollider* compoundColliderPtr,
in NativeArray<LinkedEntityGroup> oldLinkedEntityGroup,
in NativeArray<LinkedEntityGroup> newLinkedEntityGroup,
in ColliderKey key)
{
Assert.IsTrue(oldLinkedEntityGroup.Length == newLinkedEntityGroup.Length);
for (int childIndex = 0; childIndex < compoundColliderPtr->Children.Length; childIndex++)
{
ref CompoundCollider.Child child = ref compoundColliderPtr->Children[childIndex];
var childKey = key; childKey.PushSubKey(compoundColliderPtr->NumColliderKeyBits, (uint)childIndex);
for (int i = 0; i < oldLinkedEntityGroup.Length; i++)
{
if (child.Entity.Equals(childKey.Equals(oldLinkedEntityGroup[i].Value)))
{
child.Entity = newLinkedEntityGroup[i].Value;
break;
}
}
if (child.Collider->Type == ColliderType.Compound)
{
RemapCompoundColliderEntityReferences(
(CompoundCollider*)child.Collider,
oldLinkedEntityGroup, newLinkedEntityGroup, childKey);
}
}
}
}
}