using GarmentButton.VerletIntegration.Interaction; using Unity.Burst; using Unity.Entities; using Unity.Mathematics; namespace GarmentButton.VerletIntegration.Tear { [UpdateInGroup(typeof(VerletIntegrationPhysicsGroupSystems))] [UpdateAfter(typeof(SimulateInteractionSystem))] [BurstCompile] public partial struct CheckStretchesSystem : ISystem { public void OnCreate(ref SystemState state) { state.RequireForUpdate(); state.RequireForUpdate(); state.RequireForUpdate(); state.RequireForUpdate(); state.RequireForUpdate(); } [BurstCompile] public void OnUpdate(ref SystemState state) { var ecb = SystemAPI.GetSingleton() .CreateCommandBuffer(state.WorldUnmanaged).AsParallelWriter(); state.Dependency = new CheckStretchesJob { ECB = ecb, }.ScheduleParallel(state.Dependency); } [BurstCompile] [WithAll(typeof(TearLenght))] public partial struct CheckStretchesJob : IJobEntity { public EntityCommandBuffer.ParallelWriter ECB; public void Execute( Entity entity, [ChunkIndexInQuery] int sortKey, in TearLenght tearLenght, in DynamicBuffer points, ref DynamicBuffer sticks, ref DynamicBuffer tringles) { if (sticks.Length == 0 || tringles.Length == 0) return; var hasChanged = false; for (var i = 0; i < sticks.Length; i++) { var stick = sticks[i]; if (!stick.Active) continue; var delta = points[stick.PointA].Position - points[stick.PointB].Position; var maxLength = stick.Lenght * Stick.CONVERTION_RATE + tearLenght.Value; if (math.lengthsq(delta) <= maxLength * maxLength) continue; stick.Active = false; sticks[i] = stick; RemoveConnectedTringles(stick.PointA, stick.PointB, ref tringles, ref hasChanged); } if (hasChanged) ECB.AddComponent(sortKey, entity); } private static void RemoveConnectedTringles( short pointA, short pointB, ref DynamicBuffer tringles, ref bool hasChanged) { for (var i = 0; i < tringles.Length; i += 3) { var tringleEdge = tringles[i]; var tringleEdge2 = tringles[i + 1]; var tringleEdge3 = tringles[i + 2]; if (tringleEdge.Index == 0 && tringleEdge2.Index == 0 && tringleEdge3.Index == 0) continue; var hasPointA = IsOneOfThem(pointA, tringleEdge, tringleEdge2, tringleEdge3); var hasPointB = IsOneOfThem(pointB, tringleEdge, tringleEdge2, tringleEdge3); if (!hasPointA || !hasPointB) continue; tringleEdge.Index = 0; tringles[i] = tringleEdge; tringles[i + 1] = tringleEdge; tringles[i + 2] = tringleEdge; hasChanged = true; } } private static bool IsOneOfThem(short point, Tringle tringleEdge, Tringle tringleEdge2, Tringle tringleEdge3) { return tringleEdge.Index == point || tringleEdge2.Index == point || tringleEdge3.Index == point; } } } public struct UpdatedTringlesTag : IComponentData { } }