Protfolio-Emanuel-Polsky / Assets / _Project / Code / VerletIntegration / Baker / BakePoints.cs
BakePoints.cs
Raw
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<BakePoints>
    {
        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<DebugClothTag>(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<Point> CreateBuffers(BakePoints authoring, Entity entity)
        {
            var points = AddBuffer<Point>(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<Stick>(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<Tringle>(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<Point> bufferPoints)
        {
            var relativePoints = AddBuffer<RelativeLock>(entity);
            for (var i = 0; i < bufferPoints.Length; i++)
            {
                if (!bufferPoints[i].IsLocked)
                    continue;
                    
                    

                relativePoints.Add(new RelativeLock()
                {
                    Index = (ushort)i,
                    OffSet = localPoints[i],
                });
            }
        }
    }
}