private GPUAnimations.Animation GetAnimation(int index)
                {
                    GPUAnimations animations = _animationTexture.GetAnimations();

                    GPUAnimations.Animation animation = animations._animations[Mathf.Clamp(index, 0, animations._animations.Length)];
                    return(animation);
                }
 public void Play(GameObject gameObject, GPUAnimations.Animation animation, WrapMode wrapMode = WrapMode.Default, float speed = 1.0f)
 {
     _gameObject = gameObject;
     _animation  = animation;
     _frame      = 0f;
     _speed      = speed;
     _wrapMode   = wrapMode;
 }
 public GPUAnimationPlayer(GPUAnimations.Animation animation, WrapMode wrapMode = WrapMode.Default, float speed = 1.0f)
 {
     _animation = animation;
     _wrapMode  = wrapMode;
     _speed     = speed;
     _frame     = 0f;
     _loops     = 0;
 }
Esempio n. 4
0
                internal GPUAnimationState(GPUAnimation owner, GPUAnimations.Animation animation)
                {
                    _owner = owner;

                    WrapMode wrapMode = animation._wrapMode;

                    if (wrapMode == WrapMode.Default)
                    {
                        wrapMode = WrapMode.Once;
                    }

                    _player = new GPUAnimationPlayer(animation, wrapMode);
                }
 private void PlayAnimation(AnimatorStateInfo state, AnimatorClipInfo[] clips, int playerIndex)
 {
     if (clips.Length > 0)
     {
         AnimationClip           clip      = clips[0].clip;
         GPUAnimations.Animation animation = ((GPUAnimatorOverrideController)_animator.runtimeAnimatorController).GetAnimation(clip);
         _clipPlayers[playerIndex] = new GPUAnimationPlayer(animation, animation._wrapMode, 0.0f);
     }
     else
     {
         _clipPlayers[playerIndex] = new GPUAnimationPlayer();
     }
 }
Esempio n. 6
0
 private void PlayAnimation(AnimatorStateInfo state, AnimatorClipInfo[] clips, int playerIndex)
 {
     if (clips.Length > 0)
     {
         AnimationClip           clip           = clips[0].clip;
         int                     animationIndex = _animationLookUp[clip];
         GPUAnimations.Animation animation      = _animations.GetAnimations()[animationIndex];
         _clipPlayers[playerIndex].Play(this.gameObject, animation, clip.wrapMode, 0f);
     }
     else
     {
         _clipPlayers[playerIndex].Stop();
     }
 }
                private Vector4 StartNewAnimation(bool randomOffset)
                {
                    ParticleAnimation anim = PickRandomAnimation();

                    GPUAnimations.Animation animation = GetAnimation(anim._animationIndex);

                    Vector4 data;

                    data.x = anim._animationIndex;
                    data.y = randomOffset ? Random.Range(0, animation._totalFrames - 2) : 0;
                    data.z = anim._speedRange.GetRandomValue();
                    data.w = 1.0f;

                    return(data);
                }
                protected override void UpdateProperties()
                {
        #if UNITY_EDITOR
                    for (int i = 0; i < _materials.Length; i++)
                    {
                        _animationTexture.SetMaterialProperties(_materials[i]);
                    }
        #endif

                    //Update property block
                    for (int i = 0; i < GetNumRenderedParticles(); i++)
                    {
                        int index = GetRenderedParticlesIndex(i);
                        GPUAnimations.Animation animation = GetAnimation(Mathf.RoundToInt(_particleCustomData[index].x));
                        _particleCurrentFrame[i] = animation._startFrameOffset + _particleCustomData[index].y;
                    }

                    //Update property block
                    _propertyBlock.SetFloatArray("frameIndex", _particleCurrentFrame);
                }
                private void UpdateAnimations()
                {
                    int numParticles = _particleSystem.GetCustomParticleData(_particleCustomData, _customDataChannel);

                    //Update particle frame progress
                    for (int i = 0; i < numParticles; i++)
                    {
                        Vector4 customData = _particleCustomData[i];

                        //New particle - start playing new animation
                        if (customData.w == 0.0f)
                        {
                            _particleCustomData[i] = StartNewAnimation(true);
                        }
                        //Progress current animation
                        else
                        {
                            GPUAnimations.Animation animation = GetAnimation(Mathf.RoundToInt(customData.x));

                            //Update current frame
                            customData.y += Time.deltaTime * animation._fps * customData.z;

                            //If animation is finished start playing new animation
                            if (customData.y > animation._totalFrames)
                            {
                                _particleCustomData[i] = StartNewAnimation(false);
                            }
                            else
                            {
                                _particleCustomData[i] = customData;
                            }
                        }
                    }

                    //Update custom data
                    _particleSystem.SetCustomParticleData(_particleCustomData, _customDataChannel);
                }
                    private IEnumerator BakeAnimationTexture(string path)
                    {
                        _working = true;

                        GameObject gameObject = Instantiate(_evaluatedObject);

                        {
                            if (PrefabUtility.IsAnyPrefabInstanceRoot(gameObject))
                            {
                                PrefabUtility.UnpackPrefabInstance(gameObject, PrefabUnpackMode.Completely, InteractionMode.AutomatedAction);
                            }

                            gameObject.SetActive(true);
                            gameObject.transform.parent        = null;
                            gameObject.transform.localPosition = Vector3.zero;
                            gameObject.transform.localRotation = Quaternion.identity;
                            gameObject.transform.localScale    = Vector3.one;
                        }

                        AnimationClip[] animationClips       = _animations;
                        string[]        animationStateNames  = null;
                        int[]           animationStateLayers = null;
                        Animator        animator             = null;

                        //If using animator then get clips and state names from controller
                        if (_useAnimator)
                        {
                            animator = GameObjectUtils.GetComponent <Animator>(gameObject, true);
                            GetAnimationClipsFromAnimator(animator, out animationClips, out animationStateNames, out animationStateLayers);

                            if (animationClips.Length == 0)
                            {
                                DestroyImmediate(gameObject);
                                _working = false;
                                yield break;
                            }

                            AnimatorUtility.DeoptimizeTransformHierarchy(animator.gameObject);
                            animator.cullingMode = AnimatorCullingMode.AlwaysAnimate;
                        }

                        Matrix4x4 rootMat = gameObject.transform.worldToLocalMatrix;

                        SkinnedMeshRenderer[] skinnedMeshes = gameObject.GetComponentsInChildren <SkinnedMeshRenderer>();
                        Transform[]           bones         = skinnedMeshes[_skinnedMeshIndex].bones;
                        Matrix4x4[]           bindposes     = skinnedMeshes[_skinnedMeshIndex].sharedMesh.bindposes;
                        int numBones = bones.Length;

                        if (numBones == 0)
                        {
                            DestroyImmediate(gameObject);
                            _working = false;
                            yield break;
                        }

                        Vector3[]    origBonePositons  = new Vector3[numBones];
                        Quaternion[] origBoneRotations = new Quaternion[numBones];
                        Vector3[]    origBoneScales    = new Vector3[numBones];

                        GPUAnimations.Animation[] animations = new GPUAnimations.Animation[animationClips.Length];

                        //3d array - animation / frame / bones
                        Matrix4x4[][][] boneMatricies = new Matrix4x4[animations.Length + 1][][];

                        //Insert dummy one frame animation at start which is just the reference pose
                        boneMatricies[0]    = new Matrix4x4[1][];
                        boneMatricies[0][0] = new Matrix4x4[numBones];

                        for (int i = 0; i < numBones; i++)
                        {
                            origBonePositons[i]  = bones[i].localPosition;
                            origBoneRotations[i] = bones[i].localRotation;
                            origBoneScales[i]    = bones[i].localScale;

                            //Save reference pose bone matrix
                            boneMatricies[0][0][i] = rootMat * bones[i].localToWorldMatrix * bindposes[i];
                        }

                        //Start after first frame (as this frame is our reference pose)
                        int startOffset          = 1;
                        int totalNumberOfSamples = 1;

                        for (int animIndex = 0; animIndex < animations.Length; animIndex++)
                        {
                            AnimationClip clip          = animationClips[animIndex];
                            bool          hasRootMotion = _useAnimator && clip.hasMotionCurves;

                            string name         = clip.name;
                            int    totalFrames  = Mathf.Max(Mathf.FloorToInt(clip.length * clip.frameRate), 1);
                            int    totalSamples = totalFrames + 1;
                            totalNumberOfSamples += totalSamples;

                            WrapMode         wrapMode = GetClipWrapMode(clip);
                            AnimationEvent[] events   = clip.events;

                            //Sample animation
                            boneMatricies[animIndex + 1] = new Matrix4x4[totalSamples][];

                            Vector3[] rootMotionVelocities        = null;
                            Vector3[] rootMotionAngularVelocities = null;

                            if (hasRootMotion)
                            {
                                rootMotionVelocities        = new Vector3[totalSamples];
                                rootMotionAngularVelocities = new Vector3[totalSamples];
                            }

                            //Reset all bone transforms before sampling animations
                            for (int i = 0; i < numBones; i++)
                            {
                                bones[i].localPosition = origBonePositons[i];
                                bones[i].localRotation = origBoneRotations[i];
                                bones[i].localScale    = origBoneScales[i];
                            }

                            //If using an animator, start playing animation with correct layer weights set
                            if (_useAnimator)
                            {
                                for (int layer = 1; layer < animator.layerCount; layer++)
                                {
                                    animator.SetLayerWeight(animIndex, layer == animationStateLayers[animIndex] ? 1.0f : 0.0f);
                                }

                                animator.Play(animationStateNames[animIndex], animationStateLayers[animIndex]);

                                //Needed to prevent first frame pop?
                                {
                                    animator.Update(0f);
                                    yield return(null);

                                    animator.Play(animationStateNames[animIndex], animationStateLayers[animIndex]);
                                    animator.Update(0f);
                                    yield return(null);

                                    animator.Play(animationStateNames[animIndex], animationStateLayers[animIndex]);
                                    animator.Update(0f);
                                    yield return(null);
                                }
                            }

                            for (int i = 0; i < totalSamples; i++)
                            {
                                float normalisedTime = i / (float)totalFrames;

                                //Using animator, update animator to progress forward with animation
                                if (_useAnimator)
                                {
                                    for (int layer = 1; layer < animator.layerCount; layer++)
                                    {
                                        animator.SetLayerWeight(layer, 0.0f);
                                    }

                                    animator.SetLayerWeight(animationStateLayers[animIndex], 1.0f);
                                    float layerWeight = animator.GetLayerWeight(animationStateLayers[animIndex]);

                                    animator.Play(animationStateNames[animIndex], animationStateLayers[animIndex], normalisedTime);
                                    animator.Update(0f);

                                    layerWeight = animator.GetLayerWeight(animationStateLayers[animIndex]);

                                    //Wait for end of frame
                                    yield return(null);
                                }
                                //Sample animation using legacy system
                                else
                                {
                                    bool wasLegacy = clip.legacy;
                                    clip.legacy = true;
                                    clip.SampleAnimation(gameObject, normalisedTime * clip.length);
                                    clip.legacy = wasLegacy;
                                }

                                //Save bone matrices
                                boneMatricies[animIndex + 1][i] = new Matrix4x4[numBones];

                                for (int boneIndex = 0; boneIndex < numBones; boneIndex++)
                                {
                                    boneMatricies[animIndex + 1][i][boneIndex] = rootMat * bones[boneIndex].localToWorldMatrix * bindposes[boneIndex];
                                }

                                //Save root motion velocities
                                if (hasRootMotion)
                                {
                                    rootMotionVelocities[i]        = animator.velocity;
                                    rootMotionAngularVelocities[i] = animator.angularVelocity;
                                }
                            }

                            //Create animation
                            animations[animIndex] = new GPUAnimations.Animation(name, startOffset, totalFrames, clip.frameRate, wrapMode, events, hasRootMotion, rootMotionVelocities, rootMotionAngularVelocities);
                            startOffset          += totalSamples;
                        }

                        //Create and save texture
                        Texture2D texture;

                        {
                            if (!CalculateTextureSize(totalNumberOfSamples, numBones, out int textureSize))
                            {
                                DestroyImmediate(gameObject);
                                _working = false;
                                yield break;
                            }

                            texture = new Texture2D(textureSize, textureSize, TextureFormat.RGBAHalf, false)
                            {
                                filterMode = FilterMode.Point
                            };

                            //Loop through animations / frames / bones setting pixels for each bone matrix
                            int pixelx = 0;
                            int pixely = 0;

                            //Foreach animation
                            for (int animIndex = 0; animIndex < boneMatricies.Length; animIndex++)
                            {
                                //For each frame
                                for (int j = 0; j < boneMatricies[animIndex].Length; j++)
                                {
                                    //Convert all frame bone matrices to colors
                                    Color[] matrixPixels = ConvertMatricesToColor(boneMatricies[animIndex][j]);
                                    texture.SetPixels(pixelx, pixely, GPUAnimations.kPixelsPerBoneMatrix, numBones, matrixPixels);

                                    //Shift to next frame position
                                    pixelx += GPUAnimations.kPixelsPerBoneMatrix;

                                    //If less than 4 pixels from edge, move to next row
                                    if (textureSize - pixelx < GPUAnimations.kPixelsPerBoneMatrix)
                                    {
                                        pixelx  = 0;
                                        pixely += numBones;
                                    }
                                }
                            }

                            texture.Apply();
                        }

                        //Save our exposed bones
                        GPUAnimations.ExposedBone[] exposedBones;
                        {
                            exposedBones = new GPUAnimations.ExposedBone[_exposedBones.Count];

                            for (int i = 0; i < exposedBones.Length; i++)
                            {
                                //Work out bone index
                                int boneIndex = _exposedBones[i];

                                Matrix4x4 inverseBindPose = bindposes[boneIndex].inverse;

                                //Work out bone matrixes
                                Vector3[]    exposedBonePositions = new Vector3[totalNumberOfSamples];
                                Quaternion[] exposedBoneRotations = new Quaternion[totalNumberOfSamples];
                                Vector3[]    exposedBoneScales    = new Vector3[totalNumberOfSamples];

                                int sampleIndex = 0;
                                for (int anim = 0; anim < boneMatricies.Length; anim++)
                                {
                                    for (int frame = 0; frame < boneMatricies[anim].Length; frame++)
                                    {
                                        Matrix4x4 boneMatrix = boneMatricies[anim][frame][boneIndex] * inverseBindPose;

                                        exposedBonePositions[sampleIndex] = boneMatrix.MultiplyPoint3x4(Vector3.zero);
                                        exposedBoneRotations[sampleIndex] = boneMatrix.rotation;
                                        exposedBoneScales[sampleIndex]    = boneMatrix.lossyScale;

                                        sampleIndex++;
                                    }
                                }

                                exposedBones[i] = new GPUAnimations.ExposedBone(boneIndex, exposedBonePositions, exposedBoneRotations, exposedBoneScales);
                            }
                        }

                        GPUAnimations animationTexture = new GPUAnimations(texture, animations, _boneNames, exposedBones);

                        SaveAnimationTexture(animationTexture, path);

                        DestroyImmediate(gameObject);
                        _working = false;
                        yield break;
                    }
Esempio n. 11
0
                public static GPUAnimations Read(BinaryReader reader)
                {
                    string[] bones = new string[reader.ReadInt32()];
                    for (int i = 0; i < bones.Length; i++)
                    {
                        bones[i] = reader.ReadString();
                    }

                    int animCount = reader.ReadInt32();

                    GPUAnimations.Animation[] animations = new GPUAnimations.Animation[animCount];

                    for (int i = 0; i < animCount; i++)
                    {
                        string   name        = reader.ReadString();
                        int      startOffset = reader.ReadInt32();
                        int      totalFrames = reader.ReadInt32();
                        float    fps         = reader.ReadSingle();
                        WrapMode wrapMode    = (WrapMode)reader.ReadInt32();

                        int numEvents           = reader.ReadInt32();
                        AnimationEvent[] events = new AnimationEvent[numEvents];

                        for (int j = 0; j < numEvents; j++)
                        {
                            events[j] = new AnimationEvent
                            {
                                time         = reader.ReadSingle(),
                                functionName = reader.ReadString(),

                                stringParameter = reader.ReadString(),
                                floatParameter  = reader.ReadSingle(),
                                intParameter    = reader.ReadInt32()
                                                  //TO DO?
                                                  //evnt.objectReferenceParameter = reader.Rea();
                            };
                        }

                        bool hasRootMotion = reader.ReadBoolean();

                        Vector3[] rootMotionVelocities        = null;
                        Vector3[] rootMotionAngularVelocities = null;

                        if (hasRootMotion)
                        {
                            rootMotionVelocities        = new Vector3[totalFrames];
                            rootMotionAngularVelocities = new Vector3[totalFrames];

                            for (int j = 0; j < totalFrames; j++)
                            {
                                rootMotionVelocities[j]        = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                                rootMotionAngularVelocities[j] = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                            }
                        }

                        animations[i] = new GPUAnimations.Animation(name, startOffset, totalFrames, fps, wrapMode, events, hasRootMotion, rootMotionVelocities, rootMotionAngularVelocities);
                    }

                    int exposedBoneCount = reader.ReadInt32();

                    GPUAnimations.ExposedBone[] exposedBones = new GPUAnimations.ExposedBone[exposedBoneCount];

                    for (int i = 0; i < exposedBoneCount; i++)
                    {
                        int          boneIndex     = reader.ReadInt32();
                        int          numSamples    = reader.ReadInt32();
                        Vector3[]    bonePositions = new Vector3[numSamples];
                        Quaternion[] boneRotations = new Quaternion[numSamples];
                        Vector3[]    boneScales    = new Vector3[numSamples];

                        for (int j = 0; j < numSamples; j++)
                        {
                            bonePositions[j] = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                            boneRotations[j] = new Quaternion(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                            boneScales[j]    = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
                        }

                        exposedBones[i] = new GPUAnimations.ExposedBone(boneIndex, bonePositions, boneRotations, boneScales);
                    }


                    TextureFormat format        = (TextureFormat)reader.ReadInt32();
                    int           textureWidth  = reader.ReadInt32();
                    int           textureHeight = reader.ReadInt32();
                    int           byteLength    = reader.ReadInt32();

                    byte[] bytes = new byte[byteLength];
                    bytes = reader.ReadBytes(byteLength);
                    Texture2D texture = new Texture2D(textureWidth, textureHeight, format, false);

                    texture.filterMode = FilterMode.Point;
                    texture.LoadRawTextureData(bytes);
                    texture.Apply();

                    return(new GPUAnimations(texture, animations, bones, exposedBones));
                }
                    private IEnumerator BakeAnimationTexture()
                    {
                        GameObject gameObject = Instantiate(_animatorObject);

                        SkinnedMeshRenderer[] skinnedMeshes = gameObject.GetComponentsInChildren <SkinnedMeshRenderer>();
                        SkinnedMeshRenderer   skinnedMesh   = skinnedMeshes[_skinnedMeshIndex];

                        Transform[]     bones          = skinnedMesh.bones;
                        Matrix4x4[]     bindposes      = skinnedMesh.sharedMesh.bindposes;
                        AnimationClip[] animationClips = _animations;
                        Animator        animator       = null;

                        string[] animationStateNames = null;

                        if (skinnedMesh.bones.Length == 0)
                        {
                            yield break;
                        }

                        //If using animator then get clips and state names from controller
                        if (_useAnimator)
                        {
                            animator = GameObjectUtils.GetComponent <Animator>(gameObject, true);

                            if (animator == null)
                            {
                                yield break;
                            }

                            GetAnimationClipsFromAnimator(animator, out animationClips, out animationStateNames);

                            if (animationClips.Length == 0)
                            {
                                yield break;
                            }
                        }

                        int numBones = bones.Length;

                        GPUAnimations.Animation[] animations = new GPUAnimations.Animation[animationClips.Length];

                        //3d array - animation / frame / bones
                        Matrix4x4[][][] boneWorldMatrix = new Matrix4x4[animations.Length][][];

                        Matrix4x4 rootMat     = gameObject.transform.worldToLocalMatrix;
                        int       startOffset = 0;

                        for (int animIndex = 0; animIndex < animations.Length; animIndex++)
                        {
                            AnimationClip clip          = animationClips[animIndex];
                            bool          hasRootMotion = animator != null && clip.hasMotionCurves;

                            string           name        = clip.name;
                            int              totalFrames = Mathf.FloorToInt(clip.length * clip.frameRate);
                            WrapMode         wrapMode    = clip.wrapMode;
                            AnimationEvent[] events      = clip.events;

                            //Sample animation
                            boneWorldMatrix[animIndex] = new Matrix4x4[totalFrames][];

                            Vector3[] rootMotionVelocities        = null;
                            Vector3[] rootMotionAngularVelocities = null;

                            if (hasRootMotion)
                            {
                                rootMotionVelocities        = new Vector3[totalFrames];
                                rootMotionAngularVelocities = new Vector3[totalFrames];
                            }

                            float lastFrame = totalFrames - 1;

                            for (int frame = 0; frame < totalFrames; frame++)
                            {
                                float normalisedTime = frame / lastFrame;

                                //Sample animation using legacy system
                                if (animator == null)
                                {
                                    bool wasLegacy = clip.legacy;
                                    clip.legacy = true;
                                    clip.SampleAnimation(gameObject, normalisedTime * clip.length);
                                    clip.legacy = wasLegacy;
                                }
                                //Using animator, update animator to progress forward with animation
                                else
                                {
                                    animator.Play(animationStateNames[animIndex], 0, normalisedTime);
                                    animator.Update(0f);
                                    yield return(null);
                                }

                                //Save bone matrices
                                boneWorldMatrix[animIndex][frame] = new Matrix4x4[numBones];

                                for (int boneIndex = 0; boneIndex < numBones; boneIndex++)
                                {
                                    boneWorldMatrix[animIndex][frame][boneIndex] = rootMat * bones[boneIndex].localToWorldMatrix * bindposes[boneIndex];
                                }

                                //Save root motion velocities
                                if (hasRootMotion)
                                {
                                    rootMotionVelocities[frame]        = animator.velocity;
                                    rootMotionAngularVelocities[frame] = animator.angularVelocity;
                                }
                            }

                            //Create animation
                            animations[animIndex] = new GPUAnimations.Animation(name, startOffset, totalFrames, clip.frameRate, wrapMode, events, hasRootMotion, rootMotionVelocities, rootMotionAngularVelocities);
                            startOffset          += totalFrames;
                        }

                        //Create and save texture! Work out width!
                        TextureFormat format = TextureFormat.RGBAHalf;
                        int           textureSize;

                        if (!CalculateTextureSize(boneWorldMatrix, out textureSize))
                        {
                            yield break;
                        }

                        Texture2D texture = new Texture2D(textureSize, textureSize, format, false);

                        texture.filterMode = FilterMode.Point;

                        //Loop through animations / frames / bones setting pixels for each bone matrix
                        int pixelx = 0;
                        int pixely = 0;

                        //Foreach animation
                        for (int animIndex = 0; animIndex < boneWorldMatrix.Length; animIndex++)
                        {
                            //For each frame
                            for (int j = 0; j < boneWorldMatrix[animIndex].Length; j++)
                            {
                                //Convert all frame bone matrices to colors
                                Color[] matrixPixels = ConvertMatricesToColor(boneWorldMatrix[animIndex][j]);
                                texture.SetPixels(pixelx, pixely, 4, numBones, matrixPixels);

                                //Shift to next frame position
                                pixelx += 4;

                                //If less than 4 pixels from edge, move to next row
                                if (textureSize - pixelx < 4)
                                {
                                    pixelx  = 0;
                                    pixely += numBones;
                                }
                            }
                        }

                        texture.Apply();

                        GPUAnimations animationTexture = new GPUAnimations(animations, numBones, texture);

                        SaveAnimationTexture(animationTexture, _currentFileName);

                        DestroyImmediate(gameObject);
                    }