private void ApplyRootMotion(AnimationInstancing instance)
        {
            AnimationInfo info = instance.GetCurrentAnimationInfo();

            if (info == null || !info.rootMotion)
            {
                return;
            }

            int preSampleFrame  = (int)instance.curFrame;
            int nextSampleFrame = (int)(instance.curFrame + 1.0f);

            if (nextSampleFrame >= info.totalFrame)
            {
                return;
            }

            Vector3 preVelocity     = info.velocity[preSampleFrame];
            Vector3 nextVelocity    = info.velocity[nextSampleFrame];
            Vector3 velocity        = Vector3.Lerp(preVelocity, nextVelocity, instance.curFrame - preSampleFrame);
            Vector3 angularVelocity = Vector3.Lerp(info.angularVelocity[preSampleFrame], info.angularVelocity[nextSampleFrame], instance.curFrame - preSampleFrame);

            {
                Quaternion localQuaternion = instance.worldTransform.localRotation;
                Quaternion delta           = Quaternion.Euler(angularVelocity * Time.deltaTime);
                localQuaternion = localQuaternion * delta;

                Vector3 offset = velocity * Time.deltaTime;
                offset = localQuaternion * offset;
                //offset.y = 0.0f;
                Vector3 localPosition = instance.worldTransform.localPosition;
                localPosition += offset;
#if UNITY_5_6_OR_NEWER
                instance.worldTransform.SetPositionAndRotation(localPosition, localQuaternion);
#else
                instance.worldTransform.localPosition = localPosition;
                instance.worldTransform.localRotation = localQuaternion;
#endif
            }
        }
        private void PrepareBoneTexture(ArrayList infoList)
        {
            int count = 1;
            int[] frames = new int[infoList.Count];
            for (int i = 0; i != infoList.Count; ++i)
            {
                AnimationInfo info = infoList[i] as AnimationInfo;
                frames[i] = info.totalFrame;
            }
            int textureWidth = CalculateTextureSize(out count, frames);
            //int textureHeight = textureWidth;
            Debug.Assert(textureWidth > 0);

            bakedBoneTexture = new Texture2D[count];
            TextureFormat format = TextureFormat.RGBAHalf;
            for (int i = 0; i != count; ++i)
            {
                int width = count > 1 && i < count ? stardardTextureSize[stardardTextureSize.Length - 1] : textureWidth;
                bakedBoneTexture[i] = new Texture2D(width, width, format, false);
                bakedBoneTexture[i].filterMode = FilterMode.Point;
            }
        }
Example #3
0
        public bool InitializeAnimation()
        {
//            if (prefab == null)
            //                prefab = GameObject.Find(prefabName);
            Debug.Assert(cfgName != "");
//            GameObject thisPrefab = prefab;
            isMeshRender = false;
            if (lodInfo[0].skinnedMeshRenderer.Length == 0)
            {
                // This is only a MeshRenderer, it has no animations.
                isMeshRender = true;
                AnimationInstancingMgr.Instance.AddMeshVertex(this,
                                                              lodInfo,
                                                              null,
                                                              null,
                                                              bonePerVertex);
                return(true);
            }
            if (animationInfo == null)
            {
                animationInfo = AnimationManager.Instance.FindAnimationInfo(cfgName, this);
            }

            if (animationInfo != null)
            {
                aniInfo = animationInfo.listAniInfo;
                Prepare(aniInfo, animationInfo.extraBoneInfo);
            }
            if (searchInfo == null)
            {
                searchInfo = new AnimationInfo();
            }
            if (comparer == null)
            {
                comparer = new ComparerHash();
            }
            return(true);
        }
Example #4
0
        public void PlayAnimation(int animationIndex)
        {
            if (aniInfo == null)
            {
                return;
            }
            if (animationIndex == aniIndex)
            {
                return;
            }

            Debug.Assert(animationIndex < aniInfo.Count);
            if (0 <= animationIndex && animationIndex < aniInfo.Count)
            {
                aniIndex        = animationIndex;
                curAnimation    = GetCurrentAnimationInfo();
                curFrame        = 0.0f;
                oldFrame        = 0.0f;
                eventIndex      = -1;
                aniTextureIndex = curAnimation.textureIndex;
            }
            RefreshAttachmentAnimation(animationIndex);
        }
Example #5
0
        private void UpdateAnimationEvent()
        {
            AnimationInfo info = GetCurrentAnimationInfo();

            if (info == null)
            {
                return;
            }
            if (info.eventList.Count == 0)
            {
                return;
            }

            if (aniEvent == null)
            {
                float time = curFrame / info.fps;
                for (int i = eventIndex >= 0? eventIndex: 0; i < info.eventList.Count; ++i)
                {
                    if (info.eventList[i].time > time)
                    {
                        aniEvent   = info.eventList[i];
                        eventIndex = i;
                        break;
                    }
                }
            }

            if (aniEvent != null)
            {
                float time = curFrame / info.fps;
                if (aniEvent.time <= time)
                {
                    gameObject.SendMessage(aniEvent.function, aniEvent);
                    aniEvent = null;
                }
            }
        }
        private void SaveAnimationInfo(string name)
        {
            string folderName = "AnimationTexture";
            string path       = Application.dataPath + "/" + CLPathCfg.self.basePath + "/upgradeRes4Dev/priority/" + folderName + "/";

            if (!Directory.Exists(path))
            {
                AssetDatabase.CreateFolder("Assets", folderName);
            }
            FileStream   file   = File.Open(path + name + ".bytes", FileMode.Create);
            BinaryWriter writer = new BinaryWriter(file);

            writer.Write(aniInfo.Count);
            foreach (var obj in aniInfo)
            {
                AnimationInfo info = (AnimationInfo)obj;
                //writer.Write(info.animationNameHash);
                writer.Write(info.animationName);
                writer.Write(info.animationIndex);
                writer.Write(info.textureIndex);
                writer.Write(info.totalFrame);
                writer.Write(info.fps);
                writer.Write(info.rootMotion);
                if (info.rootMotion)
                {
                    Debug.Assert(info.totalFrame == info.velocity.Length);
                    for (int i = 0; i != info.velocity.Length; ++i)
                    {
                        writer.Write(info.velocity[i].x);
                        writer.Write(info.velocity[i].y);
                        writer.Write(info.velocity[i].z);

                        writer.Write(info.angularVelocity[i].x);
                        writer.Write(info.angularVelocity[i].y);
                        writer.Write(info.angularVelocity[i].z);
                    }
                }
                writer.Write(info.eventList.Count);
                foreach (var evt in info.eventList)
                {
                    writer.Write(evt.function);
                    writer.Write(evt.floatParameter);
                    writer.Write(evt.intParameter);
                    writer.Write(evt.stringParameter);
                    writer.Write(evt.time);
                    writer.Write(evt.objectParameter);
                }
            }

            writer.Write(exposeAttachments);
            if (exposeAttachments)
            {
                writer.Write(extraBoneInfo.extraBone.Length);
                for (int i = 0; i != extraBoneInfo.extraBone.Length; ++i)
                {
                    writer.Write(extraBoneInfo.extraBone[i]);
                }
                for (int i = 0; i != extraBoneInfo.extraBindPose.Length; ++i)
                {
                    for (int j = 0; j != 16; ++j)
                    {
                        writer.Write(extraBoneInfo.extraBindPose[i][j]);
                    }
                }
            }

            Texture2D[] texture = bakedBoneTexture;
            writer.Write(texture.Length);
            writer.Write(textureBlockWidth);
            writer.Write(textureBlockHeight);
            for (int i = 0; i != texture.Length; ++i)
            {
                byte[] bytes = texture[i].GetRawTextureData();
                writer.Write(texture[i].width);
                writer.Write(texture[i].height);
                writer.Write(bytes.Length);
                writer.Write(bytes);
            }

            file.Close();
            aniInfo.Clear();
        }
        void BakeAnimation()
        {
#if UNITY_ANDROID || UNITY_IPHONE
            Debug.LogError("You can't bake animations on IOS or Android. Please switch to PC.");
            return;
#endif
            if (generatedPrefab != null)
            {
                GameObject obj = Instantiate(generatedPrefab);
                obj.transform.position = Vector3.zero;
                obj.transform.rotation = Quaternion.identity;
                Animator animator = obj.GetComponentInChildren <Animator>();

                AnimationInstancing script = obj.GetComponent <AnimationInstancing>();
                Debug.Assert(script);
                SkinnedMeshRenderer[] meshRender    = obj.GetComponentsInChildren <SkinnedMeshRenderer>();
                List <Matrix4x4>      bindPose      = new List <Matrix4x4>(150);
                Transform[]           boneTransform = RuntimeHelper.MergeBone(meshRender, bindPose);
                Reset();
                AddMeshVertex2Generate(meshRender, boneTransform, bindPose.ToArray());

                Transform rootNode = meshRender[0].rootBone;
                for (int j = 0; j != meshRender.Length; ++j)
                {
                    meshRender[j].enabled = true;
                }

                int frames = 0;
                var clips  = GetClips(true);
                foreach (AnimationClip animClip in clips)
                {
                    //float lastFrameTime = 0;
                    int aniName    = animClip.name.GetHashCode();
                    int bakeFrames = Mathf.CeilToInt(animClip.length * aniFps);

                    AnimationInfo info = new AnimationInfo();
                    info.animationNameHash = aniName;
                    info.animationIndex    = frames;
                    info.totalFrame        = bakeFrames;

                    //bool rotationRootMotion = false, positionRootMotion = false;
                    //for (int i = 0; i < bakeFrames; i += 1)
                    //{
                    //    float bakeDelta = Mathf.Clamp01(((float)i / bakeFrames));
                    //    float animationTime = bakeDelta * animClip.length;
                    //    animClip.SampleAnimation(obj, animationTime);

                    //    info.position[i] = rootNode.localPosition;
                    //    info.rotation[i] = rootNode.localRotation;
                    //    if (i > 0 && info.position[i] != info.position[i - 1])
                    //    {
                    //        positionRootMotion = true;
                    //    }
                    //    if (i > 0 && info.rotation[i] != info.rotation[i - 1])
                    //    {
                    //        rotationRootMotion = true;
                    //    }
                    //}
                    //info.rootMotion = positionRootMotion;

                    Matrix4x4 rootMatrix1stFrame = Matrix4x4.identity;
                    animator.applyRootMotion = true;
                    animator.Play("TestState", 0);
                    //                 animator.StartRecording(bakeFrames);
                    //                 for (int i = 0; i < bakeFrames; i += 1)
                    //                 {
                    //                     animator.Update(1.0f / m_fps);
                    //                 }
                    //                 animator.StopRecording();
                    //
                    //                 animator.StartPlayback();
                    //                 animator.playbackTime = 0;
                    //AnimationInstancing script = m_prefab.GetComponent<AnimationInstancing>();
                    for (int i = 0; i < bakeFrames; i += 1)
                    {
                        //float bakeDelta = Mathf.Clamp01(((float)i / bakeFrames));
                        //float animationTime = bakeDelta * animClip.length;
                        //float normalizedTime = animationTime / animClip.length;

                        //UnityEditor.Animations.AnimatorController ac = animator.runtimeAnimatorController;
                        //UnityEditorInternal.StateMachine sm = ac.GetLayerStateMachine(0);


                        //AnimatorStateInfo nameInfo = animator.GetCurrentAnimatorStateInfo(0);

                        //                     if (lastFrameTime == 0)
                        //                     {
                        //                         float nextBakeDelta = Mathf.Clamp01(((float)(i + 1) / bakeFrames));
                        //                         float nextAnimationTime = nextBakeDelta * animClip.length;
                        //                         lastFrameTime = animationTime - nextAnimationTime;
                        //                     }
                        //                     animator.Update(animationTime - lastFrameTime);
                        //                     lastFrameTime = animationTime;

                        animator.Update(1.0f / bakeFrames);

                        //animClip.SampleAnimation(obj, animationTime);

                        //if (i == 0)
                        //{
                        //    rootMatrix1stFrame = boneTransform[0].localToWorldMatrix;
                        //}
                        for (int j = 0; j != meshRender.Length; ++j)
                        {
                            GenerateBoneMatrix(meshRender[j].name.GetHashCode(),
                                               aniName,
                                               i,
                                               rootMatrix1stFrame,
                                               info.rootMotion);
                        }
                    }

                    aniInfo.Add(info);
                    frames += bakeFrames;
                    SetupAnimationTexture(aniInfo);
                }
                //AnimationInstancingMgr.Instance.ExportBoneTexture(m_prefab.name);
                SaveAnimationInfo(generatedPrefab.name);

                DestroyImmediate(obj);
            }
        }
        public void SetupAnimationTexture(ArrayList infoList)
        {
            int preNameCode = generateObjectData[0].stateName;

            //int preTextureIndex = m_bakedTextureIndex;
            for (int i = 0; i != currentDataIndex; ++i)
            {
                GenerateOjbectInfo matrixData = generateObjectData[i];
                if (matrixData.boneMatrix == null)
                {
                    continue;
                }
                if (preNameCode != matrixData.stateName)
                {
                    preNameCode = matrixData.stateName;
                    int totalFrames = currentDataIndex - i;
                    for (int j = i; j != currentDataIndex; ++j)
                    {
                        if (preNameCode != generateObjectData[j].stateName)
                        {
                            totalFrames = j - i;
                            break;
                        }
                    }

                    int width  = bakedBoneTexture[bakedTextureIndex].width;
                    int height = bakedBoneTexture[bakedTextureIndex].height;
                    int y      = pixely;
                    int currentLineBlockCount = (width - pixelx) / textureBlockWidth % (width / textureBlockWidth);
                    totalFrames -= currentLineBlockCount;
                    if (totalFrames > 0)
                    {
                        int framesEachLine = width / textureBlockWidth;
                        y += (totalFrames / framesEachLine) * textureBlockHeight;
                        y += currentLineBlockCount > 0 ? textureBlockHeight : 0;
                        if (height < y + textureBlockHeight)
                        {
                            ++bakedTextureIndex;
                            pixelx = 0;
                            pixely = 0;
                            Debug.Assert(bakedTextureIndex < bakedBoneTexture.Length);
                        }
                    }

                    foreach (var obj in infoList)
                    {
                        AnimationInfo info = obj as AnimationInfo;
                        if (info.animationNameHash == matrixData.stateName)
                        {
                            info.animationIndex = pixelx / textureBlockWidth + pixely / textureBlockHeight * bakedBoneTexture[bakedTextureIndex].width / textureBlockWidth;
                            info.textureIndex   = bakedTextureIndex;
                        }
                    }
                }
                if (matrixData.boneMatrix != null)
                {
                    Debug.Assert(pixely + textureBlockHeight <= bakedBoneTexture[bakedTextureIndex].height);
                    Color[] color = UtilityHelper.Convert2Color(matrixData.boneMatrix, boneCount);
                    bakedBoneTexture[bakedTextureIndex].SetPixels(pixelx, pixely, textureBlockWidth, textureBlockHeight, color);
                    matrixData.frameIndex = pixelx / textureBlockWidth + pixely / textureBlockHeight * bakedBoneTexture[bakedTextureIndex].width / textureBlockWidth;
                    pixelx += textureBlockWidth;
                    if (pixelx + textureBlockWidth > bakedBoneTexture[bakedTextureIndex].width)
                    {
                        pixelx  = 0;
                        pixely += textureBlockHeight;
                    }
                    if (pixely + textureBlockHeight > bakedBoneTexture[bakedTextureIndex].height)
                    {
                        Debug.Assert(generateObjectData[i + 1].stateName != matrixData.stateName);
                        ++bakedTextureIndex;
                        pixelx = 0;
                        pixely = 0;
                        Debug.Assert(bakedTextureIndex < bakedBoneTexture.Length);
                    }
                }
                else
                {
                    Debug.Assert(false);
                    ArrayList          list         = generateMatrixDataPool[matrixData.stateName];
                    GenerateOjbectInfo originalData = list[matrixData.boneListIndex] as GenerateOjbectInfo;
                    matrixData.frameIndex = originalData.frameIndex;
                }
            }
            currentDataIndex = 0;
        }