The code for anyone wondering, or wanting to roast/suggest improvements to the impl :)
using Unity.Burst;
using Unity.Collections;
using Unity.Entities;
using Unity.Physics;
using Unity.Physics.Systems;
public struct PhysicsDominance : IComponentData
{
public byte Value;
}
[UpdateInGroup(typeof(PhysicsSimulationGroup))]
[UpdateAfter(typeof(PhysicsCreateContactsGroup))]
[UpdateBefore(typeof(PhysicsCreateJacobiansGroup))]
[BurstCompile]
public partial struct DominanceEnableMassFactorsSystem : ISystem
{
[BurstCompile]
private struct EnableMassFactorsJob : IContactsJob
{
public void Execute(ref ModifiableContactHeader manifold, ref ModifiableContactPoint contact)
{
manifold.JacobianFlags |= JacobianFlags.EnableMassFactors;
}
}
[BurstCompile]
public void OnUpdate(ref SystemState state)
{
var simulationSingleton = SystemAPI.GetSingletonRW<SimulationSingleton>();
var physicsWorldSingleton = SystemAPI.GetSingletonRW<PhysicsWorldSingleton>();
state.Dependency = new EnableMassFactorsJob()
.Schedule(simulationSingleton.ValueRW,
ref physicsWorldSingleton.ValueRW.PhysicsWorld,
state.Dependency);
}
}
[UpdateInGroup(typeof(PhysicsSimulationGroup))]
[UpdateAfter(typeof(PhysicsCreateJacobiansGroup))]
[UpdateBefore(typeof(PhysicsSolveAndIntegrateGroup))]
[BurstCompile]
public partial struct DominanceMassFactorSystem : ISystem
{
[BurstCompile]
public void OnUpdate(ref SystemState state)
{
var dominanceLookup = state.GetComponentLookup<PhysicsDominance>();
var simulationSingleton = SystemAPI.GetSingletonRW<SimulationSingleton>();
var physicsWorldSingleton = SystemAPI.GetSingletonRW<PhysicsWorldSingleton>();
state.Dependency = new DominanceJob
{
DominanceLookup = dominanceLookup
}
.Schedule(simulationSingleton.ValueRW,
ref physicsWorldSingleton.ValueRW.PhysicsWorld,
state.Dependency);
}
[BurstCompile]
private struct DominanceJob : IJacobiansJob
{
[ReadOnly] public ComponentLookup<PhysicsDominance> DominanceLookup;
public void Execute(ref ModifiableJacobianHeader h, ref ModifiableTriggerJacobian j)
{
}
[BurstCompile]
public void Execute(ref ModifiableJacobianHeader jacHeader, ref ModifiableContactJacobian contactJacobian)
{
DominanceLookup.TryGetComponent(jacHeader.EntityA, out var dominanceA);
DominanceLookup.TryGetComponent(jacHeader.EntityB, out var dominanceB);
if (dominanceA.Value > dominanceB.Value)
{
var massFactors = new MassFactors
{
InverseMassFactorA = 0,
InverseInertiaFactorA = 0,
InverseMassFactorB = jacHeader.MassFactors.InverseMassFactorB,
InverseInertiaFactorB = jacHeader.MassFactors.InverseInertiaFactorB
};
jacHeader.MassFactors = massFactors;
}
else if (dominanceB.Value > dominanceA.Value)
{
var massFactors = new MassFactors
{
InverseMassFactorA = jacHeader.MassFactors.InverseMassFactorA,
InverseInertiaFactorA = jacHeader.MassFactors.InverseInertiaFactorA,
InverseMassFactorB = 0,
InverseInertiaFactorB = 0
};
jacHeader.MassFactors = massFactors;
}
}
}
}