forked from Unity-Technologies/EntityComponentSystemSamples
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathModifyNarrowphaseContactsBehaviour.cs
More file actions
116 lines (96 loc) · 3.58 KB
/
Copy pathModifyNarrowphaseContactsBehaviour.cs
File metadata and controls
116 lines (96 loc) · 3.58 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
using Unity.Physics;
using Unity.Physics.Systems;
using Unity.Collections;
using Unity.Entities;
using Unity.Jobs;
using Unity.Mathematics;
using UnityEngine;
using System;
using ContactPoint = Unity.Physics.ContactPoint;
using Unity.Physics.Extensions;
using Unity.Burst;
public struct ModifyNarrowphaseContacts : IComponentData
{
public Entity surfaceEntity;
public float3 surfaceNormal;
}
public class ModifyNarrowphaseContactsBehaviour : MonoBehaviour, IConvertGameObjectToEntity
{
public GameObject surfaceMesh = null;
void OnEnable() { }
void IConvertGameObjectToEntity.Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem)
{
if (enabled)
{
dstManager.AddComponentData(entity, new ModifyNarrowphaseContacts()
{
surfaceEntity = entity,
surfaceNormal = surfaceMesh.transform.up
});
}
}
}
// A system which configures the simulation step to rotate certain contact normals
[UpdateBefore(typeof(StepPhysicsWorld))]
public class ModifyNarrowphaseContactsSystem : JobComponentSystem
{
EntityQuery m_ContactModifierGroup;
StepPhysicsWorld m_StepPhysicsWorld;
BuildPhysicsWorld m_BuildPhysicsWorld;
protected override void OnCreate()
{
m_StepPhysicsWorld = World.GetOrCreateSystem<StepPhysicsWorld>();
m_BuildPhysicsWorld = World.GetOrCreateSystem<BuildPhysicsWorld>();
m_ContactModifierGroup = GetEntityQuery(new EntityQueryDesc
{
All = new ComponentType[] { typeof(ModifyNarrowphaseContacts) }
});
}
protected override JobHandle OnUpdate(JobHandle inputDeps)
{
if (m_ContactModifierGroup.CalculateLength() == 0)
{
return inputDeps;
}
if (m_StepPhysicsWorld.Simulation.Type == SimulationType.NoPhysics)
{
return inputDeps;
}
var modifiers = m_ContactModifierGroup.ToComponentDataArray<ModifyNarrowphaseContacts>(Allocator.TempJob);
var surfaceNormal = modifiers[0].surfaceNormal;
var surfaceRBIdx = m_BuildPhysicsWorld.PhysicsWorld.GetRigidBodyIndex(modifiers[0].surfaceEntity);
SimulationCallbacks.Callback callback = (ref ISimulation simulation, ref PhysicsWorld world, JobHandle inDeps) =>
{
inDeps.Complete(); // TODO: shouldn't be needed (jobify the below)
return new ModifyNormalsJob
{
m_SurfaceRBIdx = surfaceRBIdx,
m_SurfaceNormal = surfaceNormal
}.Schedule(simulation, ref world, inDeps);
};
modifiers.Dispose();
m_StepPhysicsWorld.EnqueueCallback(SimulationCallbacks.Phase.PostCreateContacts, callback);
return inputDeps;
}
[BurstCompile]
struct ModifyNormalsJob : IContactsJob
{
public int m_SurfaceRBIdx;
public float3 m_SurfaceNormal;
float distanceScale;
public void Execute(ref ModifiableContactHeader contactHeader, ref ModifiableContactPoint contactPoint)
{
bool bUpdateNormal = (contactHeader.BodyIndexPair.BodyAIndex == m_SurfaceRBIdx) || (contactHeader.BodyIndexPair.BodyBIndex == m_SurfaceRBIdx);
if (bUpdateNormal && contactPoint.Index == 0)
{
var newNormal = m_SurfaceNormal;
distanceScale = math.dot(newNormal, contactHeader.Normal);
contactHeader.Normal = newNormal;
}
if (bUpdateNormal)
{
contactPoint.Distance *= distanceScale;
}
}
}
}