using Unity.Burst; using Unity.Collections; using Unity.Entities; using Unity.Jobs; using Unity.Mathematics; using UnityEngine; using UnityEngine.Serialization; namespace GarmentButton.VerletIntegration { public class BakePoints : MonoBehaviour { public Vector2Int Grid = new Vector2Int(15, 6); public float Distance = 0.2f; [HideInInspector] public Vector3[] Points; [HideInInspector] public int[] Tringles; [HideInInspector] public bool[] IsLocked; [HideInInspector] public StickPartiallyMono[] Sticks; public Vector3 MaximumBound; public Vector3 MinmumBound; public bool FollowEntity; public bool DebugCloth; public SimulationSettings SimulationSettings; public float HandleSize = 0.25f; [HideInInspector] public Vector3 HandlePositionOffSet1; [HideInInspector] public Vector3 HandlePositionOffeset2; public Vector3 GetRelative(Vector3 position) { return transform.position + position; } } public class BakePointsBaker : Baker { public override void Bake(BakePoints authoring) { if (authoring.SimulationSettings == null) return; var entity = Entity.Null; if (authoring.FollowEntity) entity = GetEntity(TransformUsageFlags.Dynamic); else entity = GetEntity(TransformUsageFlags.None); //Buffers var points = CreateBuffers(authoring, entity); if (authoring.FollowEntity) FollowEntity(authoring.Points, entity, points); GeneralDataBake(authoring, entity); //Cache Lengths CacheLengths(authoring, entity); if (authoring.DebugCloth) AddComponent(entity); } private void CacheLengths(BakePoints authoring, Entity entity) { AddComponent(entity, new PointArrayLenght { Value = (ushort)authoring.Points.Length }); AddComponent(entity, new SticksArrayLenght() { Value = (ushort) authoring.Sticks.Length }); AddComponent(entity, new TringleArrayLenght() { Value = (ushort) authoring.Tringles.Length }); } private void GeneralDataBake(BakePoints authoring, Entity entity) { var flag = new FlagData { NumberIterations = (byte)authoring.SimulationSettings.NumberIternations, GravityForce = authoring.SimulationSettings.Gravity, Damping = authoring.SimulationSettings.Damping, }; var boundBox = new BoundBox { Min = authoring.MinmumBound, Max = authoring.MaximumBound, }; AddComponent(entity, flag); AddComponent(entity, boundBox); float3 deg = authoring.transform.eulerAngles; float3 rad = math.radians(deg); quaternion q = quaternion.EulerZXY(rad); AddComponent(entity, new RecordLastTransform() { Position = authoring.transform.position, Rotation = q, }); } private DynamicBuffer CreateBuffers(BakePoints authoring, Entity entity) { var points = AddBuffer(entity); points.Capacity = authoring.Points.Length; points.Length = authoring.Points.Length; for (var i = 0; i < points.Length; i++) { var position = authoring.GetRelative(authoring.Points[i]); points[i] = new Point { Position = position, PrevesPosition = position, State = authoring.IsLocked[i] ? PointState.Boarder : PointState.Free, IsLocked = authoring.IsLocked[i], }; } var stickBuffer = AddBuffer(entity); stickBuffer.Capacity = authoring.Sticks.Length; stickBuffer.Length = authoring.Sticks.Length; for (var i = 0; i < stickBuffer.Length; i++) { stickBuffer[i] = new Stick { PointA = authoring.Sticks[i].PointA, PointB = authoring.Sticks[i].PointB, Active = true, Lenght = (ushort)(authoring.Sticks[i].Lenght * authoring.SimulationSettings.LenghtMultiply), }; } var tringlesBuffer = AddBuffer(entity); tringlesBuffer.Capacity = authoring.Tringles.Length; tringlesBuffer.Length = authoring.Tringles.Length; for (var i = 0; i < tringlesBuffer.Length; i++) { tringlesBuffer[i] = new Tringle { Index = (short)authoring.Tringles[i], }; } return points; } private void FollowEntity(Vector3[] localPoints, Entity entity, DynamicBuffer bufferPoints) { var relativePoints = AddBuffer(entity); for (var i = 0; i < bufferPoints.Length; i++) { if (!bufferPoints[i].IsLocked) continue; relativePoints.Add(new RelativeLock() { Index = (ushort)i, OffSet = localPoints[i], }); } } } }