| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501 | using System.Collections;using System.Collections.Generic;using GPUECSAnimationBaker.Engine.AnimatorSystem;using GpuEcsAnimationBaker.Engine.Data;using Unity.Collections;using Unity.Mathematics;using Unity.Transforms;using UnityEngine;public class GPUAnimtion{    // public GpuEcsAnimatorBehaviour GameObject;    //    // public Renderer Renderer;    public GpuEcsAnimationDataComponent gpuEcsAnimationData;    public List<GpuEcsAnimationDataBufferElement> gpuEcsAnimationDataBuffer;    public List<GpuEcsAnimationEventOccurenceBufferElement> gpuEcsAnimationEventOccurenceBuffer;    public GpuEcsAnimatorShaderDataComponent gpuEcsAnimatorShaderData;    public GpuEcsAnimatorInitializedComponent gpuEcsAnimatorInitialized;    private GpuEcsAnimatorControlComponent gpuEcsAnimatorControl;    private GpuEcsAnimatorControlStateComponent gpuEcsAnimatorControlState;    private GpuEcsAnimatorTransitionInfoComponent gpuEcsAnimatorTransitionInfo;    private GpuEcsAnimatorStateComponent gpuEcsAnimatorState;    public List<GpuEcsAttachmentAnchorDataBufferElement> gpuEcsAttachmentAnchorData;    public List<GpuEcsCurrentAttachmentAnchorBufferElement> gpuEcsCurrentAttachmentAnchors;    public GpuEcsAnimatorEventBufferElement gpuEcsAnimatorEventBuffer;    public int animtionIndex;    // private MaterialPropertyBlock _materialPropertyBlock;    // private Renderer renderer;    public void SetSpeed(float speed)    {        gpuEcsAnimatorControl.animatorInfo.speedFactor = speed;    }    [ContextMenu("adadadsa")]    public void SetAnimtionIndex(AnimatorInfo animatorInfo)    {        gpuEcsAnimatorControl.animatorInfo = animatorInfo;    }    public void SetAnimtionIndex(int animatorInfo)    {        gpuEcsAnimatorControl.animatorInfo.animationID = animatorInfo;    }    public void GetGPUAnchors(int index, out Vector3 pos, out Quaternion unityQuaternion)    {        if (gpuEcsCurrentAttachmentAnchors.Count <= index)        {            pos = Vector3.zero;            unityQuaternion = Quaternion.identity;            return;        }        GpuEcsCurrentAttachmentAnchorBufferElement gpuEcsCurrentAttachmentAnchorBufferElement =            gpuEcsCurrentAttachmentAnchors[0];        float3 pos2 = gpuEcsCurrentAttachmentAnchorBufferElement.currentTransform.TransformPoint(float3.zero);        pos = new Vector3(pos2.x, pos2.y, pos2.z);        float4 xuanzhaung = gpuEcsCurrentAttachmentAnchorBufferElement.currentTransform            .TransformRotation(quaternion.identity).value;        unityQuaternion = new Quaternion(xuanzhaung.x, xuanzhaung.y, xuanzhaung.z, xuanzhaung.w);    }    // Update is called once per frame    public void Update()    {        Execute();        // if (gpuEcsCurrentAttachmentAnchors.Count > 0)        // {        //     float3 pos2 = gpuEcsCurrentAttachmentAnchors[0].currentTransform.TransformPoint(float3.zero);        //     float3 pos = LocalTransform.FromMatrix(gpuEcsCurrentAttachmentAnchors[0].currentTransform).Position;        //     Debug.Log(pos);        //     // Matrix4x4 matrix4X4 = new Matrix4x4();        //     // float3 pos=    float3(0,0,0);        // }        // _materialPropertyBlock.SetMatrix("_AnimationState", gpuEcsAnimatorShaderData.shaderData);        // _materialPropertyBlock.SetFloat("_EnableAnimation", 1);        // renderer.SetPropertyBlock(_materialPropertyBlock);    }    public void Init(GpuEcsAnimatorBehaviour gpuEcsAnimatorBehaviour)    {        // _materialPropertyBlock = new MaterialPropertyBlock();        // GpuEcsAnimatedMeshBehaviour ecsAnimatedMeshBehaviour = gpuEcsAnimatorBehaviour.gameObject.transform        //     .GetComponentInChildren<GpuEcsAnimatedMeshBehaviour>();        // renderer = ecsAnimatedMeshBehaviour.GetComponent<Renderer>();        // renderer.GetPropertyBlock(_materialPropertyBlock);        gpuEcsAnimationData = new GpuEcsAnimationDataComponent()        {            nbrOfAttachmentAnchors = gpuEcsAnimatorBehaviour.nbrOfAttachmentAnchors,            totalNbrOfFrames = gpuEcsAnimatorBehaviour.totalNbrOfFrames        };        gpuEcsAnimationDataBuffer =            new List<GpuEcsAnimationDataBufferElement>();        for (int animationIndex = 0; animationIndex < gpuEcsAnimatorBehaviour.animations.Length; animationIndex++)        {            GpuEcsAnimationData gpuEcsAnimationData = gpuEcsAnimatorBehaviour.animations[animationIndex];            gpuEcsAnimationDataBuffer.Add(new GpuEcsAnimationDataBufferElement()            {                startFrameIndex = gpuEcsAnimationData.startFrameIndex,                nbrOfFramesPerSample = gpuEcsAnimationData.nbrOfFramesPerSample,                nbrOfInBetweenSamples = gpuEcsAnimationData.nbrOfInBetweenSamples,                blendTimeCorrection = gpuEcsAnimationData.blendTimeCorrection,                startEventOccurenceId = gpuEcsAnimationData.startEventOccurenceId,                nbrOfEventOccurenceIds = gpuEcsAnimationData.nbrOfEventOccurenceIds,                loop = gpuEcsAnimationData.loop            });        }        gpuEcsAnimationEventOccurenceBuffer = new List<GpuEcsAnimationEventOccurenceBufferElement>();        for (int animationEventOccurenceId = 0;             animationEventOccurenceId < gpuEcsAnimatorBehaviour.animationEventOccurences.Length;             animationEventOccurenceId++)        {            GpuEcsAnimationEventOccurence occurence =                gpuEcsAnimatorBehaviour.animationEventOccurences[animationEventOccurenceId];            gpuEcsAnimationEventOccurenceBuffer.Add(new GpuEcsAnimationEventOccurenceBufferElement()            {                eventNormalizedTime = occurence.eventNormalizedTime,                eventId = occurence.eventId            });        }        gpuEcsAnimatorShaderData = new GpuEcsAnimatorShaderDataComponent()        {            shaderData = new float4x4(                1f, 0, 0, 0,                0, 0, 0, 0,                0, 0, 0, 0,                0, 0, 0, 0)        };        int initialAnimationID = 0;        GpuEcsAnimatorInitializerBehaviour initializer =            gpuEcsAnimatorBehaviour.GetComponent<GpuEcsAnimatorInitializerBehaviour>();        if (initializer != null) initialAnimationID = initializer.GetInitialAnimationID();        gpuEcsAnimatorInitialized = new GpuEcsAnimatorInitializedComponent()        {            initialized = false        };        gpuEcsAnimatorControl = new GpuEcsAnimatorControlComponent()        {            animatorInfo = new AnimatorInfo()            {                animationID = initialAnimationID,                blendFactor = 0,                speedFactor = 1            },            transitionSpeed = 0,            startNormalizedTime = 0        };        gpuEcsAnimatorControlState =            new GpuEcsAnimatorControlStateComponent()            {                state = GpuEcsAnimatorControlStates.Start            };        gpuEcsAnimatorTransitionInfo =            new GpuEcsAnimatorTransitionInfoComponent();        gpuEcsAnimatorState = new GpuEcsAnimatorStateComponent();        gpuEcsAttachmentAnchorData =            new List<GpuEcsAttachmentAnchorDataBufferElement>();        gpuEcsCurrentAttachmentAnchors =            new List<GpuEcsCurrentAttachmentAnchorBufferElement>();        if (gpuEcsAnimatorBehaviour.attachmentAnchorData != null && gpuEcsAnimatorBehaviour.nbrOfAttachmentAnchors > 0)        {            int anchorDataLength = gpuEcsAnimatorBehaviour.attachmentAnchorData.anchorTransforms.Length;            NativeArray<GpuEcsAttachmentAnchorDataBufferElement> anchors =                new NativeArray<GpuEcsAttachmentAnchorDataBufferElement>(anchorDataLength, Allocator.Temp);            for (int i = 0; i < anchorDataLength; i++)                anchors[i] = new GpuEcsAttachmentAnchorDataBufferElement()                    { anchorTransform = gpuEcsAnimatorBehaviour.attachmentAnchorData.anchorTransforms[i] };            gpuEcsAttachmentAnchorData.AddRange(anchors);            anchors.Dispose();            NativeArray<GpuEcsCurrentAttachmentAnchorBufferElement> currentAnchorTransforms =                new NativeArray<GpuEcsCurrentAttachmentAnchorBufferElement>(                    gpuEcsAnimatorBehaviour.nbrOfAttachmentAnchors,                    Allocator.Temp);            gpuEcsCurrentAttachmentAnchors.AddRange(currentAnchorTransforms);            currentAnchorTransforms.Dispose();        }        gpuEcsAnimatorEventBuffer = new GpuEcsAnimatorEventBufferElement();    }    public void Execute()    {        // gpuEcsAnimatorEventBuffer.Clear();        if (!gpuEcsAnimatorInitialized.initialized)        {            // We switch immediately to the first animation, no transition            gpuEcsAnimatorTransitionInfo = new GpuEcsAnimatorTransitionInfoComponent()            {                current = gpuEcsAnimatorControl.animatorInfo,                blendPreviousToCurrent = 1f            };            gpuEcsAnimatorState = new GpuEcsAnimatorStateComponent()            {                currentNormalizedTime = gpuEcsAnimatorControl.startNormalizedTime,                stoppedPrevious = false,                stoppedCurrent = false            };            gpuEcsAnimatorInitialized.initialized = true;        }        else if (gpuEcsAnimatorControl.animatorInfo.animationID != gpuEcsAnimatorTransitionInfo.current.animationID)        {            // A new animation (or animation combination) has been started, so we need to do a transition            // from the old one to the new            gpuEcsAnimatorTransitionInfo = new GpuEcsAnimatorTransitionInfoComponent()            {                current = gpuEcsAnimatorControl.animatorInfo,                previous = gpuEcsAnimatorTransitionInfo.current,                blendPreviousToCurrent = 0f            };            gpuEcsAnimatorState = new GpuEcsAnimatorStateComponent()            {                previousNormalizedTime = gpuEcsAnimatorState.currentNormalizedTime,                stoppedPrevious = gpuEcsAnimatorState.stoppedCurrent,                currentNormalizedTime = gpuEcsAnimatorControl.startNormalizedTime,                stoppedCurrent = false,            };        }        else        {            // The same animation (or animation combination) is still running, but the parameters might have changed            // (blendPrimaryToSecondary or speedFactor)            gpuEcsAnimatorTransitionInfo.current = gpuEcsAnimatorControl.animatorInfo;        }        GpuEcsAnimatorControlStates controlState = gpuEcsAnimatorControlState.state;        if (gpuEcsAnimatorControlState.state == GpuEcsAnimatorControlStates.Start)            gpuEcsAnimatorState.stoppedCurrent = false;        else if (gpuEcsAnimatorControlState.state == GpuEcsAnimatorControlStates.Stop)            gpuEcsAnimatorState.stoppedCurrent = true;        gpuEcsAnimatorControlState.state = GpuEcsAnimatorControlStates.KeepCurrentState;        if (!gpuEcsAnimatorState.stoppedCurrent)        {            UpdateAnimatorState(ref gpuEcsAnimatorState.currentNormalizedTime, ref gpuEcsAnimatorState.stoppedCurrent,                ref gpuEcsAnimatorEventBuffer,                gpuEcsAnimatorTransitionInfo.current, controlState, gpuEcsAnimationDataBuffer,                gpuEcsAnimationEventOccurenceBuffer,                out float primaryBlendFactor, out float primaryTransitionToNextFrame, out int primaryFrameIndex,                out float secondaryBlendFactor, out float secondaryTransitionToNextFrame, out int secondaryFrameIndex,                forPrevious: false);            if (gpuEcsAnimatorTransitionInfo.blendPreviousToCurrent >= 1f)            {                gpuEcsAnimatorShaderData.shaderData = new float4x4(                    primaryBlendFactor, primaryTransitionToNextFrame, primaryFrameIndex, 0,                    secondaryBlendFactor, secondaryTransitionToNextFrame, secondaryFrameIndex, 0,                    0, 0, 0, 0,                    0, 0, 0, 0);                //Apply attachment anchor transforms                for (int attachmentAnchorIndex = 0;                     attachmentAnchorIndex < gpuEcsAnimationData.nbrOfAttachmentAnchors;                     attachmentAnchorIndex++)                {                    int baseIndex = gpuEcsAnimationData.totalNbrOfFrames * attachmentAnchorIndex;                    gpuEcsCurrentAttachmentAnchors[attachmentAnchorIndex] =                        new GpuEcsCurrentAttachmentAnchorBufferElement()                        {                            currentTransform = LerpBlend(gpuEcsAttachmentAnchorData, baseIndex,                                primaryFrameIndex, secondaryFrameIndex,                                primaryTransitionToNextFrame, secondaryTransitionToNextFrame,                                secondaryBlendFactor)                        };                }            }            else            {                if (gpuEcsAnimatorControl.transitionSpeed == 0)                    gpuEcsAnimatorTransitionInfo.blendPreviousToCurrent = 1f;                else                {                    gpuEcsAnimatorTransitionInfo.blendPreviousToCurrent +=                        Time.deltaTime / gpuEcsAnimatorControl.transitionSpeed;                    if (gpuEcsAnimatorTransitionInfo.blendPreviousToCurrent > 1f)                        gpuEcsAnimatorTransitionInfo.blendPreviousToCurrent = 1f;                }                float previousToCurrent = gpuEcsAnimatorTransitionInfo.blendPreviousToCurrent;                float currentToPrevious = 1f - previousToCurrent;                UpdateAnimatorState(ref gpuEcsAnimatorState.previousNormalizedTime,                    ref gpuEcsAnimatorState.stoppedPrevious,                    ref gpuEcsAnimatorEventBuffer,                    gpuEcsAnimatorTransitionInfo.previous, controlState, gpuEcsAnimationDataBuffer,                    gpuEcsAnimationEventOccurenceBuffer,                    out float previousPrimaryBlendFactor, out float previousPrimaryTransitionToNextFrame,                    out int previousPrimaryFrameIndex,                    out float previousSecondaryBlendFactor, out float previousSecondaryTransitionToNextFrame,                    out int previousSecondaryFrameIndex,                    forPrevious: true);                gpuEcsAnimatorShaderData.shaderData = new float4x4(                    previousToCurrent * primaryBlendFactor, primaryTransitionToNextFrame, primaryFrameIndex, 0,                    previousToCurrent * secondaryBlendFactor, secondaryTransitionToNextFrame, secondaryFrameIndex, 0,                    currentToPrevious * previousPrimaryBlendFactor, previousPrimaryTransitionToNextFrame,                    previousPrimaryFrameIndex, 0,                    currentToPrevious * previousSecondaryBlendFactor, previousSecondaryTransitionToNextFrame,                    previousSecondaryFrameIndex, 0);                for (int attachmentAnchorIndex = 0;                     attachmentAnchorIndex < gpuEcsAnimationData.nbrOfAttachmentAnchors;                     attachmentAnchorIndex++)                {                    int baseIndex = gpuEcsAnimationData.totalNbrOfFrames * attachmentAnchorIndex;                    float4x4 current = LerpBlend(gpuEcsAttachmentAnchorData, baseIndex,                        primaryFrameIndex, secondaryFrameIndex,                        primaryTransitionToNextFrame, secondaryTransitionToNextFrame,                        secondaryBlendFactor);                    float4x4 previous = LerpBlend(gpuEcsAttachmentAnchorData, baseIndex,                        previousPrimaryFrameIndex, previousSecondaryFrameIndex,                        previousPrimaryTransitionToNextFrame, previousSecondaryTransitionToNextFrame,                        previousSecondaryBlendFactor);                    gpuEcsCurrentAttachmentAnchors[attachmentAnchorIndex] =                        new GpuEcsCurrentAttachmentAnchorBufferElement()                        {                            currentTransform = LerpTransform(previous, current, previousToCurrent)                        };                }            }        }    }    private float4x4 LerpBlend(in List<GpuEcsAttachmentAnchorDataBufferElement> gpuEcsAttachmentAnchorData,        int baseIndex, int frameIndexA, int frameIndexB,        float frameIndexATransitionToNextFrame, float frameIndexBTransitionToNextFrame,        float t)    {        float4x4 result;        if (t == 0)            result = LerpNextFrame(gpuEcsAttachmentAnchorData, baseIndex, frameIndexA,                frameIndexATransitionToNextFrame);        else if (t == 1f)            result = LerpNextFrame(gpuEcsAttachmentAnchorData, baseIndex, frameIndexB,                frameIndexBTransitionToNextFrame);        else        {            float4x4 primary = LerpNextFrame(gpuEcsAttachmentAnchorData, baseIndex, frameIndexA,                frameIndexATransitionToNextFrame);            float4x4 secondary = LerpNextFrame(gpuEcsAttachmentAnchorData, baseIndex, frameIndexB,                frameIndexBTransitionToNextFrame);            result = LerpTransform(primary, secondary, t);        }        return result;    }    private float4x4 LerpNextFrame(in List<GpuEcsAttachmentAnchorDataBufferElement> gpuEcsAttachmentAnchorData,        int baseIndex, int frameIndex, float transitionToNextFrame)    {        return LerpTransform(            gpuEcsAttachmentAnchorData[baseIndex + frameIndex].anchorTransform,            gpuEcsAttachmentAnchorData[baseIndex + frameIndex + 1].anchorTransform,            transitionToNextFrame        );    }    private float4x4 LerpTransform(float4x4 valueA, float4x4 valueB, float t)    {        float3 posA = new float3(valueA.c3.x, valueA.c3.y, valueA.c3.z);        quaternion rotA = new quaternion(valueA);        float3 posB = new float3(valueB.c3.x, valueB.c3.y, valueB.c3.z);        quaternion rotB = new quaternion(valueB);        float3 pos = math.lerp(posA, posB, t);        Quaternion rot = math.slerp(rotA, rotB, t);        return float4x4.TRS(pos, rot, new float3(1f, 1f, 1f));    }    private void UpdateAnimatorState(ref float normalizedTime, ref bool stopped,        ref GpuEcsAnimatorEventBufferElement gpuEcsAnimatorEventBuffer,        AnimatorInfo animatorInfo,        in GpuEcsAnimatorControlStates controlState,        in List<GpuEcsAnimationDataBufferElement> gpuEcsAnimationDataBuffer,        in List<GpuEcsAnimationEventOccurenceBufferElement> gpuEcsAnimationEventOccurenceBuffer,        out float primaryBlendFactor, out float primaryTransitionToNextFrame, out int primaryFrameIndex,        out float secondaryBlendFactor, out float secondaryTransitionToNextFrame, out int secondaryFrameIndex,        bool forPrevious)    {        GpuEcsAnimationDataBufferElement animationData = gpuEcsAnimationDataBuffer[animatorInfo.animationID];        if (animationData.nbrOfInBetweenSamples == 1)        {            float blendSpeedAdjustment = 1f;            UpdateAnimationNormalizedTime(ref normalizedTime, ref stopped, ref gpuEcsAnimatorEventBuffer, animatorInfo,                controlState,                gpuEcsAnimationEventOccurenceBuffer, animationData, blendSpeedAdjustment,                out float transitionToNextFrame, out int relativeFrameIndex, forPrevious);            primaryBlendFactor = 1;            primaryTransitionToNextFrame = transitionToNextFrame;            primaryFrameIndex = animationData.startFrameIndex + relativeFrameIndex;            secondaryBlendFactor = 0;            secondaryTransitionToNextFrame = 0;            secondaryFrameIndex = 0;        }        else        {            float endBlend = (float)(animationData.nbrOfInBetweenSamples - 1);            float currentBlendSetFloat = animatorInfo.blendFactor * endBlend;            int currentBlendSet = (int)math.floor(currentBlendSetFloat);            float transitionToNextSet = currentBlendSetFloat - (float)currentBlendSet;            float blendSpeedAdjustment = animatorInfo.blendFactor * animationData.blendTimeCorrection +                                         (1f - animatorInfo.blendFactor);            UpdateAnimationNormalizedTime(ref normalizedTime, ref stopped, ref gpuEcsAnimatorEventBuffer, animatorInfo,                controlState,                gpuEcsAnimationEventOccurenceBuffer, animationData, blendSpeedAdjustment,                out float transitionToNextFrame, out int relativeFrameIndex, forPrevious);            primaryBlendFactor = 1f - transitionToNextSet;            primaryTransitionToNextFrame = transitionToNextFrame;            primaryFrameIndex = animationData.startFrameIndex + currentBlendSet * animationData.nbrOfFramesPerSample +                                relativeFrameIndex;            secondaryBlendFactor = transitionToNextSet;            secondaryTransitionToNextFrame = transitionToNextFrame;            secondaryFrameIndex = animationData.startFrameIndex +                                  (currentBlendSet + 1) * animationData.nbrOfFramesPerSample + relativeFrameIndex;        }    }    private void UpdateAnimationNormalizedTime(ref float normalizedTime, ref bool stopped,        ref GpuEcsAnimatorEventBufferElement gpuEcsAnimatorEventBuffer,        AnimatorInfo animatorInfo, in GpuEcsAnimatorControlStates controlState,        in List<GpuEcsAnimationEventOccurenceBufferElement> gpuEcsAnimationEventOccurenceBuffer,        GpuEcsAnimationDataBufferElement animationData, float blendSpeedAdjustment,        out float transitionToNextFrame, out int relativeFrameIndex, bool forPrevious)    {        int endFrame = animationData.nbrOfFramesPerSample - 1;        float animationLength = (float)endFrame / GlobalConstants.SampleFrameRate;        float currentTime = normalizedTime * animationLength;        if (!stopped) currentTime += Time.deltaTime * animatorInfo.speedFactor * blendSpeedAdjustment;        float normalizedTimeLastUpdate = normalizedTime;        normalizedTime = currentTime / animationLength;        for (int eventOccurencId = animationData.startEventOccurenceId;             eventOccurencId < animationData.startEventOccurenceId + animationData.nbrOfEventOccurenceIds;             eventOccurencId++)        {            GpuEcsAnimationEventOccurenceBufferElement occurence = gpuEcsAnimationEventOccurenceBuffer[eventOccurencId];            if (normalizedTimeLastUpdate < occurence.eventNormalizedTime &&                normalizedTime > occurence.eventNormalizedTime)            {                //Trigger event                gpuEcsAnimatorEventBuffer = (new GpuEcsAnimatorEventBufferElement()                {                    animationId = animatorInfo.animationID,                    eventId = occurence.eventId                });            }        }        if (!forPrevious && (animationData.loop || controlState == GpuEcsAnimatorControlStates.Start))        {            while (normalizedTime >= 1f) normalizedTime -= 1f;        }        else        {            if (normalizedTime >= 1f)            {                normalizedTime = 1f;                stopped = true;            }        }        if (normalizedTime == 1f)        {            relativeFrameIndex = endFrame - 1;            transitionToNextFrame = 1f;        }        else        {            float relativeFrameIndexFloat = normalizedTime * (float)endFrame;            relativeFrameIndex = (int)math.floor(relativeFrameIndexFloat);            transitionToNextFrame = relativeFrameIndexFloat - (float)relativeFrameIndex;        }    }}
 |