public InstanceAnimationInfo FindAnimationInfo(string cfgName, AnimationInstancing instance)
        {
//            Debug.Assert(prefab != null);
            InstanceAnimationInfo info = null;

            if (m_animationInfo.TryGetValue(cfgName, out info))
            {
                return(info);
            }

//#if UNITY_IPHONE || UNITY_ANDROID
//            Debug.Assert(m_useBundle);
//			if (m_mainBundle == null)
//              Debug.LogError("You should call LoadAnimationAssetBundle first.");
//#endif
            if (m_useBundle)
            {
                CreateAnimationRequest request = new CreateAnimationRequest();
                request.cfgName  = cfgName;
                request.instance = instance;
                if (m_mainBundle != null)
                {
                    StartCoroutine(LoadAnimationInfoFromAssetBundle(request));
                }
                else
                {
                    m_requestList.Add(request);
                }
                return(null);
            }
            else
            {
                return(CreateAnimationInfoFromFile(cfgName));
            }
        }
        public void AddInstance(GameObject obj)
        {
            AnimationInstancing script = obj.GetComponent <AnimationInstancing>();

            Debug.Assert(script != null);
            if (script == null)
            {
                Debug.LogError("The prefab you created doesn't attach the script 'AnimationInstancing'.");
                Destroy(obj);
                return;
            }

            try
            {
                bool success = script.InitializeAnimation();
                if (success)
                {
                    aniInstancingList.Add(script);
                }
            }
            catch (Exception e)
            {
                Debug.LogError(e.Message);
                Debug.Log("Initialize animation failed. Please check out the backed animation infos and regenerate it.");
                script.enabled = false;
            }
        }
Esempio n. 3
0
 public void Deattach(AnimationInstancing attachment)
 {
     attachment.visible        = false;
     attachment.parentInstance = null;
     RefreshAttachmentAnimation(-1);
     listAttachment.Remove(attachment);
 }
Esempio n. 4
0
        public void UpdateAnimation()
        {
            if (aniInfo == null || curAnimation == null)
            {
                return;
            }

            curFrame += playSpeed * Time.deltaTime * curAnimation.fps;
            int totalFrame = curAnimation.totalFrame;

            if (loop)
            {
                if (curFrame < 0f)
                {
                    curFrame += (totalFrame - 1);
                }
                else if (curFrame > totalFrame - 1)
                {
                    curFrame -= (totalFrame - 1);
                }
            }
            curFrame = Mathf.Clamp(curFrame, 0f, totalFrame - 1);

            for (int i = 0; i != listAttachment.Count; ++i)
            {
                AnimationInstancing attachment = listAttachment[i];
                attachment.transform.position = transform.position;
                attachment.transform.rotation = transform.rotation;
            }
            UpdateAnimationEvent();
            CheckProgress();              // add by chenbin
        }
        public GameObject CreateInstance(GameObject prefab)
        {
            Debug.Assert(prefab != null);
            GameObject          obj    = Instantiate(prefab, Vector3.zero, Quaternion.identity);
            AnimationInstancing script = obj.GetComponent <AnimationInstancing>();

            script.prefab = prefab;
            return(obj);
        }
 private void OnDestroy()
 {
     if (!AnimationInstancingMgr.IsDestroy())
     {
         AnimationInstancingMgr.Instance.RemoveInstance(this);
     }
     if (parentInstance != null)
     {
         parentInstance.Deattach(this);
         parentInstance = null;
     }
 }
Esempio n. 7
0
 // Use this for initialization
 void Start()
 {
     if (!AnimationInstancing.AnimationInstancingMgr.Instance.UseInstancing)
     {
         avatar = GetComponent <Animator>();
     }
     else
     {
         instancing = GetComponent <AnimationInstancing.AnimationInstancing>();
         Debug.Assert(instancing);
         if (instancing == null)
         {
             gameObject.SetActive(false);
         }
     }
 }
        public void RemoveInstance(AnimationInstancing instance)
        {
            Debug.Assert(aniInstancingList != null);
            bool removed = aniInstancingList.Remove(instance);

            if (removed)
            {
                --usedBoundingSphereCount;
                cullingGroup.SetBoundingSphereCount(usedBoundingSphereCount);
                Debug.Assert(usedBoundingSphereCount >= 0);
                if (usedBoundingSphereCount < 0)
                {
                    Debug.DebugBreak();
                }
            }
        }
        static void DrawGizmo(AnimationInstancing instance, GizmoType gizmoType)
        {
            //Gizmos.DrawSphere(instance.gameObject.transform.position, 3);
            if (!instance.enabled)
                return;
            if (EditorApplication.isPlaying)
                return;

            GameObject obj = instance.gameObject;
            SkinnedMeshRenderer[] render = obj.GetComponentsInChildren<SkinnedMeshRenderer>();
            for (int i = 0; i != render.Length; ++i)
            {
                Gizmos.DrawMesh(render[i].sharedMesh, obj.transform.position, obj.transform.rotation); 
            }
            
        }
Esempio n. 10
0
        public void clear()
        {
            if (!AnimationInstancingMgr.IsDestroy())
            {
                AnimationInstancingMgr.Instance.RemoveInstance(this);
                AnimationInstancingMgr.Instance.RemoveMeshVertex(this, lodInfo);
            }
            if (parentInstance != null)
            {
                parentInstance.Deattach(this);
                parentInstance = null;
            }

            Stop();
//			playSpeed = 1.0f;
//			lodFrequencyCount = 0;
        }
Esempio n. 11
0
 private void RefreshAttachmentAnimation(int index)
 {
     for (int k = 0; k != listAttachment.Count; ++k)
     {
         AnimationInstancing attachment = listAttachment[k];
         for (int i = 0; i != attachment.lodInfo.Length; ++i)
         {
             LodInfo info = attachment.lodInfo[i];
             for (int j = 0; j != info.meshRenderer.Length; ++j)
             {
                 //MeshRenderer render = info.meshRenderer[j];
                 AnimationInstancingMgr.VertexCache cache = info.vertexCacheList[info.skinnedMeshRenderer.Length + j];
                 cache.boneTextureIndex = index;
             }
         }
     }
 }
Esempio n. 12
0
    void Update()
    {
        // the attaching should be after the master's initialize, so we put it in the first update.
        if (!initialize)
        {
            initialize = true;
            AnimationInstancing.AnimationInstancing instance = GetComponent <AnimationInstancing.AnimationInstancing>();
            if (instance)
            {
                int count = instance.GetAnimationCount();
                instance.PlayAnimation(Random.Range(0, count));
                AnimationInstancing.AnimationInstancing attachmentScript = attachment.GetComponent <AnimationInstancing.AnimationInstancing>();
                instance.Attach("ik_hand_r", attachmentScript);

                // Deattach the attachment
                // instance.Deattach(attachmentScript);
            }
        }
    }
        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
            }
        }
        void CreateObjInstancing()
        {
            //LoadAB();
            Vector3 pos   = new Vector3();
            int     width = (int)UnityEngine.Mathf.Sqrt((int)InstancingCount);

            for (int i = 0; i != InstancingCount; ++i)
            {
                GameObject prefab     = m_instancingList[Random.Range(0, m_instancingList.Length)];
                GameObject obj        = AnimationInstancingMgr.GetInstance().CreateInstance(prefab);
                GameObject attachment = null;
                if (m_testAttachment != null)
                {
                    attachment = AnimationInstancingMgr.GetInstance().CreateInstance(m_testAttachment);
                }

                Transform trans = obj.GetComponent <Transform>();
                trans.SetPositionAndRotation(pos, Quaternion.identity);
                //trans.Rotate(new Vector3(0, 45, 0));
                pos.x += 1.5f;
                if (pos.x > width * 1.5f)
                {
                    pos.x  = 0.0f;
                    pos.z += 1.5f;
                }
                AnimationInstancing script = obj.GetComponent <AnimationInstancing>();
                //script.PlayAnimation(Random.Range(0, script.m_aniInfo.Count));
                AnimationInstancing attachmentScript = null;
                if (attachment)
                {
                    attachmentScript = GetComponent <AnimationInstancing>();
                }
                StartCoroutine(RandomPlayAnimation(script, attachmentScript));
                //StartCoroutine(RandomPlayAnimation(script));
                m_objs.Add(obj);
            }
        }
        IEnumerator RandomPlayAnimation(AnimationInstancing script, AnimationInstancing attachment = null)
        {
            if (wait2Play == null)
            {
                wait2Play = new WaitForSeconds(2.0f);
            }
            yield return(wait2Play);

            script.PlayAnimation(Random.Range(0, script.GetAnimationCount()));
            //script.PlayAnimation(5);

            if (attachment != null)
            {
                //string name = Random.Range(0, 100)>50 ? "RightHand" : "LeftHand";
                string name = "Prop";
                script.Attach(name, attachment);
                //script.Attach("Neck", attachment);
            }

            if (attachment != null)
            {
                //StartCoroutine(TestDetach(script, attachment));
            }
        }
        void ApplyBoneMatrix()
        {
            Vector3 cameraPosition = cameraTransform.position;

            for (int i = 0; i != aniInstancingList.Count; ++i)
            {
                AnimationInstancing instance = aniInstancingList[i];
                if (!instance.IsPlaying())
                {
                    continue;
                }
                if (instance.aniIndex < 0 && instance.parentInstance == null)
                {
                    continue;
                }

                if (instance.applyRootMotion)
                {
                    ApplyRootMotion(instance);
                }

                instance.UpdateAnimation();
                instance.boundingSpere.position = instance.transform.position;
                boundingSphere[i] = instance.boundingSpere;

                if (!instance.visible)
                {
                    continue;
                }
                instance.UpdateLod(cameraPosition);

                AnimationInstancing.LodInfo lod = instance.lodInfo[instance.lodLevel];
                int aniTextureIndex             = -1;
                if (instance.parentInstance != null)
                {
                    aniTextureIndex = instance.parentInstance.aniTextureIndex;
                }
                else
                {
                    aniTextureIndex = instance.aniTextureIndex;
                }

                for (int j = 0; j != lod.vertexCacheList.Length; ++j)
                {
                    VertexCache   cache = lod.vertexCacheList[j];
                    MaterialBlock block = lod.materialBlockList[j];
                    Debug.Assert(block != null);
                    int packageIndex = block.runtimePackageIndex[aniTextureIndex];
                    Debug.Assert(packageIndex < block.packageList[aniTextureIndex].Count);
                    InstancingPackage package = block.packageList[aniTextureIndex][packageIndex];
                    if (package.instancingCount + 1 > instancingPackageSize)
                    {
                        ++block.runtimePackageIndex[aniTextureIndex];
                        packageIndex = block.runtimePackageIndex[aniTextureIndex];
                        if (packageIndex >= block.packageList[aniTextureIndex].Count)
                        {
                            InstancingPackage newPackage = CreatePackage(block.instanceData,
                                                                         cache.mesh,
                                                                         cache.materials,
                                                                         aniTextureIndex);
                            block.packageList[aniTextureIndex].Add(newPackage);
                            PreparePackageMaterial(newPackage, cache, aniTextureIndex);
                            newPackage.instancingCount = 1;
                        }
                        block.packageList[aniTextureIndex][packageIndex].instancingCount = 1;
                    }
                    else
                    {
                        ++package.instancingCount;
                    }

                    {
                        VertexCache       vertexCache = cache;
                        InstanceData      data        = block.instanceData;
                        int               index       = block.runtimePackageIndex[aniTextureIndex];
                        InstancingPackage pkg         = block.packageList[aniTextureIndex][index];
                        int               count       = pkg.instancingCount - 1;
                        if (count >= 0)
                        {
                            Matrix4x4   worldMat = instance.worldTransform.localToWorldMatrix;
                            Matrix4x4[] arrayMat = data.worldMatrix[aniTextureIndex][index];
                            arrayMat[count].m00 = worldMat.m00;
                            arrayMat[count].m01 = worldMat.m01;
                            arrayMat[count].m02 = worldMat.m02;
                            arrayMat[count].m03 = worldMat.m03;
                            arrayMat[count].m10 = worldMat.m10;
                            arrayMat[count].m11 = worldMat.m11;
                            arrayMat[count].m12 = worldMat.m12;
                            arrayMat[count].m13 = worldMat.m13;
                            arrayMat[count].m20 = worldMat.m20;
                            arrayMat[count].m21 = worldMat.m21;
                            arrayMat[count].m22 = worldMat.m22;
                            arrayMat[count].m23 = worldMat.m23;
                            arrayMat[count].m30 = worldMat.m30;
                            arrayMat[count].m31 = worldMat.m31;
                            arrayMat[count].m32 = worldMat.m32;
                            arrayMat[count].m33 = worldMat.m33;
                            float frameIndex = 0, preFrameIndex = -1, transition = 0f;
                            if (instance.parentInstance != null)
                            {
                                frameIndex = instance.parentInstance.aniInfo[instance.parentInstance.aniIndex].animationIndex + instance.parentInstance.curFrame;
                                if (instance.parentInstance.preAniIndex >= 0)
                                {
                                    preFrameIndex = instance.parentInstance.aniInfo[instance.parentInstance.preAniIndex].animationIndex + instance.parentInstance.preAniFrame;
                                }
                                transition = instance.parentInstance.transitionProgress;
                            }
                            else
                            {
                                frameIndex = instance.aniInfo[instance.aniIndex].animationIndex + instance.curFrame;
                                if (instance.preAniIndex >= 0)
                                {
                                    preFrameIndex = instance.aniInfo[instance.preAniIndex].animationIndex + instance.preAniFrame;
                                }
                                transition = instance.transitionProgress;
                            }
                            data.frameIndex[aniTextureIndex][index][count]         = frameIndex;
                            data.preFrameIndex[aniTextureIndex][index][count]      = preFrameIndex;
                            data.transitionProgress[aniTextureIndex][index][count] = transition;
                        }
                    }
                }
            }
        }
        IEnumerator TestDetach(AnimationInstancing script, AnimationInstancing attachment)
        {
            yield return(wait2Play);

            script.Deattach(attachment);
        }
Esempio n. 18
0
        public void Attach(string boneName, AnimationInstancing attachment)
        {
            int index    = -1;
            int hashBone = boneName.GetHashCode();

            for (int i = 0; i != allTransforms.Length; ++i)
            {
                if (allTransforms[i].name.GetHashCode() == hashBone)
                {
                    index = i;
                    break;
                }
            }
            //Debug.Assert(index >= 0);
            if (index < 0)
            {
                Debug.LogError("Can't find the bone.");
                return;
            }
            if (attachment.lodInfo[0].meshRenderer.Length == 0 && attachment.lodInfo[0].skinnedMeshRenderer.Length == 0)
            {
                Debug.LogError("The attachment doesn't have a Renderer");
                return;
            }

            attachment.parentInstance = this;
            AnimationInstancingMgr.VertexCache parentCache = AnimationInstancingMgr.Instance.FindVertexCache(lodInfo[0].skinnedMeshRenderer[0].name.GetHashCode());
            listAttachment.Add(attachment);

            int nameCode = boneName.GetHashCode();

            nameCode += attachment.lodInfo[0].meshRenderer.Length > 0? attachment.lodInfo[0].meshRenderer[0].name.GetHashCode(): 0;
            if (attachment.lodInfo[0].meshRenderer.Length == 0)
            {
                //todo, to support the attachment that has skinnedMeshRenderer;
                int skinnedMeshRenderCount = attachment.lodInfo[0].skinnedMeshRenderer.Length;
                nameCode += skinnedMeshRenderCount > 0? attachment.lodInfo[0].skinnedMeshRenderer[0].name.GetHashCode(): 0;
            }
            AnimationInstancingMgr.VertexCache cache = AnimationInstancingMgr.Instance.FindVertexCache(nameCode);
            // if we can reuse the VertexCache, we don't need to create one
            if (cache != null)
            {
                cache.boneTextureIndex = parentCache.boneTextureIndex;
                return;
            }

            AnimationInstancingMgr.Instance.AddMeshVertex(attachment.prototype.name,
                                                          attachment.lodInfo,
                                                          null,
                                                          null,
                                                          attachment.bonePerVertex,
                                                          boneName);

            for (int i = 0; i != attachment.lodInfo.Length; ++i)
            {
                LodInfo info = attachment.lodInfo[i];
                for (int j = 0; j != info.meshRenderer.Length; ++j)
                {
                    cache = info.vertexCacheList[info.skinnedMeshRenderer.Length + j];
                    //Debug.Assert(cache != null);
                    if (cache == null)
                    {
                        Debug.LogError("Can't find the VertexCache.");
                        continue;
                    }
                    //Debug.Assert(cache.boneTextureIndex < 0 || cache.boneIndex[0].x != index);

                    AnimationInstancingMgr.Instance.BindAttachment(parentCache, cache, info.meshFilter[j].sharedMesh, index);
                    AnimationInstancingMgr.Instance.SetupAdditionalData(cache);
                    cache.boneTextureIndex = parentCache.boneTextureIndex;
                }
            }
        }
Esempio n. 19
0
        public void UpdateAnimation()
        {
            if (aniInfo == null || IsPause())
            {
                return;
            }

            if (isInTransition)
            {
                transitionTimer += Time.deltaTime;
                float weight = transitionTimer / transitionDuration;
                transitionProgress = Mathf.Min(weight, 1.0f);
                if (transitionProgress >= 1.0f)
                {
                    isInTransition = false;
                    preAniIndex    = -1;
                    preAniFrame    = -1;
                }
            }
            float speed = playSpeed * speedParameter;

            curFrame += speed * Time.deltaTime * aniInfo[aniIndex].fps;
            int totalFrame = aniInfo[aniIndex].totalFrame;

            switch (wrapMode)
            {
            case WrapMode.Loop:
            {
                if (curFrame < 0f)
                {
                    curFrame += (totalFrame - 1);
                }
                else if (curFrame > totalFrame - 1)
                {
                    curFrame -= (totalFrame - 1);
                }
                break;
            }

            case WrapMode.PingPong:
            {
                if (curFrame < 0f)
                {
                    speedParameter = Mathf.Abs(speedParameter);
                    curFrame       = Mathf.Abs(curFrame);
                }
                else if (curFrame > totalFrame - 1)
                {
                    speedParameter = -Mathf.Abs(speedParameter);
                    curFrame       = 2 * (totalFrame - 1) - curFrame;
                }
                break;
            }

            case WrapMode.Default:
            case WrapMode.Once:
            {
                if (curFrame < 0f || curFrame > totalFrame - 1.0f)
                {
                    Pause();
                }
                break;
            }
            }

            curFrame = Mathf.Clamp(curFrame, 0f, totalFrame - 1);
            for (int i = 0; i != listAttachment.Count; ++i)
            {
                AnimationInstancing attachment = listAttachment[i];
                attachment.transform.position = transform.position;
                attachment.transform.rotation = transform.rotation;
            }
            UpdateAnimationEvent();
        }
        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);
            }
        }
Esempio n. 21
0
        void ApplyBoneMatrix()
        {
            Vector3 cameraPosition = cameraTransform.position;

            for (int i = 0; i != aniInstancingList.Count; ++i)
            {
                AnimationInstancing instance = aniInstancingList[i];
                if (!instance.IsPlaying())
                {
                    continue;
                }
                if (instance.aniIndex < 0 && instance.parentInstance == null)
                {
                    continue;
                }

                instance.UpdateAnimation();
                if (!instance.visible)
                {
                    continue;
                }

                if (instance.applyRootMotion)
                {
                    ApplyRootMotion(instance);
                }
                instance.UpdateLod(cameraPosition);

                AnimationInstancing.LodInfo lod = instance.lodInfo[instance.lodLevel];
#if USE_CONSTANT_BUFFER
                VertexCache  vertexCache     = lod.vertexCacheList[0];
                InstanceData data            = vertexCache.instanceData;
                int          aniTextureIndex = -1;
                if (instance.parentInstance != null)
                {
                    aniTextureIndex = instance.parentInstance.aniTextureIndex;
                }
                else
                {
                    aniTextureIndex = instance.aniTextureIndex;
                }
                int index = vertexCache.runtimePackageIndex[aniTextureIndex];
                VertexCache.InstancingPackage pkg = vertexCache.packageList[aniTextureIndex][index];
                int count = pkg.instancingCount - 1;
                if (count >= 0)
                {
                    Matrix4x4   worldMat = instance.worldTransform.localToWorldMatrix;
                    Matrix4x4[] arrayMat = data.worldMatrix[aniTextureIndex][index];
                    arrayMat[count].m00 = worldMat.m00;
                    arrayMat[count].m01 = worldMat.m01;
                    arrayMat[count].m02 = worldMat.m02;
                    arrayMat[count].m03 = worldMat.m03;
                    arrayMat[count].m10 = worldMat.m10;
                    arrayMat[count].m11 = worldMat.m11;
                    arrayMat[count].m12 = worldMat.m12;
                    arrayMat[count].m13 = worldMat.m13;
                    arrayMat[count].m20 = worldMat.m20;
                    arrayMat[count].m21 = worldMat.m21;
                    arrayMat[count].m22 = worldMat.m22;
                    arrayMat[count].m23 = worldMat.m23;
                    arrayMat[count].m30 = worldMat.m30;
                    arrayMat[count].m31 = worldMat.m31;
                    arrayMat[count].m32 = worldMat.m32;
                    arrayMat[count].m33 = worldMat.m33;
                    float frameIndex = 0;
                    if (instance.parentInstance != null)
                    {
                        frameIndex = instance.parentInstance.aniInfo[instance.parentInstance.aniIndex].animationIndex + instance.parentInstance.curFrame;
                    }
                    else
                    {
                        frameIndex = instance.aniInfo[instance.aniIndex].animationIndex + instance.curFrame;
                    }

                    data.frameIndex[aniTextureIndex][index][count] = frameIndex;

                    instance.boundingSpere.position.x = worldMat.m03;
                    instance.boundingSpere.position.y = worldMat.m13;
                    instance.boundingSpere.position.z = worldMat.m23;
                    boundingSphere[i] = instance.boundingSpere;
                }

                for (int j = 0; j != lod.vertexCacheList.Length; ++j)
                {
                    VertexCache cache        = lod.vertexCacheList[j] as VertexCache;
                    int         packageIndex = cache.runtimePackageIndex[aniTextureIndex];
                    Debug.Assert(packageIndex < cache.packageList[aniTextureIndex].Count);
                    VertexCache.InstancingPackage package = cache.packageList[aniTextureIndex][packageIndex];
                    if (package.instancingCount + 1 > instancingPackageSize)
                    {
                        ++cache.runtimePackageIndex[aniTextureIndex];
                        packageIndex = cache.runtimePackageIndex[aniTextureIndex];
                        if (packageIndex >= cache.packageList[aniTextureIndex].Count)
                        {
                            VertexCache.InstancingPackage newPackage = CreatePackage(cache.instanceData,
                                                                                     cache.mesh,
                                                                                     vertexCache.materials,
                                                                                     aniTextureIndex);
                            cache.packageList[aniTextureIndex].Add(newPackage);
                            PreparePackageMaterial(newPackage, cache, aniTextureIndex);
                            newPackage.instancingCount = 1;
                        }
                    }
                    else
                    {
                        ++package.instancingCount;
                    }
                }
#else
                for (int j = 0; j != lod.vertexCacheList.Length; ++j)
                {
                    VertexCache cache = lod.vertexCacheList[j] as VertexCache;
                    if (cache.instancingData == null)
                    {
                        cache.instancingData = new InstancingData[cache.instancingCount];
                        cache.bufInstance    = new ComputeBuffer((int)cache.instancingCount, 64 + 4 + 4 + 8);
                    }
                    Matrix4x4 worldMat = instance.worldTransform.localToWorldMatrix;
                    cache.instancingData[cache.currentInstancingIndex].worldMatrix.m00 = worldMat.m00;
                    cache.instancingData[cache.currentInstancingIndex].worldMatrix.m01 = worldMat.m01;
                    cache.instancingData[cache.currentInstancingIndex].worldMatrix.m02 = worldMat.m02;
                    cache.instancingData[cache.currentInstancingIndex].worldMatrix.m03 = worldMat.m03;
                    cache.instancingData[cache.currentInstancingIndex].worldMatrix.m10 = worldMat.m10;
                    cache.instancingData[cache.currentInstancingIndex].worldMatrix.m11 = worldMat.m11;
                    cache.instancingData[cache.currentInstancingIndex].worldMatrix.m12 = worldMat.m12;
                    cache.instancingData[cache.currentInstancingIndex].worldMatrix.m13 = worldMat.m13;
                    cache.instancingData[cache.currentInstancingIndex].worldMatrix.m20 = worldMat.m20;
                    cache.instancingData[cache.currentInstancingIndex].worldMatrix.m21 = worldMat.m21;
                    cache.instancingData[cache.currentInstancingIndex].worldMatrix.m22 = worldMat.m22;
                    cache.instancingData[cache.currentInstancingIndex].worldMatrix.m23 = worldMat.m23;
                    cache.instancingData[cache.currentInstancingIndex].worldMatrix.m30 = worldMat.m30;
                    cache.instancingData[cache.currentInstancingIndex].worldMatrix.m31 = worldMat.m31;
                    cache.instancingData[cache.currentInstancingIndex].worldMatrix.m32 = worldMat.m32;
                    cache.instancingData[cache.currentInstancingIndex].worldMatrix.m33 = worldMat.m33;
                    cache.instancingData[cache.currentInstancingIndex].frameIndex      = instance.aniInfo[animationIndex].animationIndex + instance.curFrame;
                    cache.instancingData[cache.currentInstancingIndex].animationIndex  = 0;
                    ++cache.currentInstancingIndex;
                }
#endif
            }
        }
        void BakeWithAnimator()
        {
#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)
            {
                generatedObject = Instantiate(generatedPrefab);
                generatedObject.transform.position = Vector3.zero;
                generatedObject.transform.rotation = Quaternion.identity;
                Animator animator = generatedObject.GetComponentInChildren <Animator>();

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

                // calculate the bindpose of attached points
                if (generatedFbx)
                {
                    List <Transform> listExtra  = new List <Transform>();
                    Transform[]      trans      = generatedFbx.GetComponentsInChildren <Transform>();
                    Transform[]      bakedTrans = generatedObject.GetComponentsInChildren <Transform>();
                    foreach (var obj in selectExtraBone)
                    {
                        if (!obj.Value)
                        {
                            continue;
                        }

                        for (int i = 0; i != trans.Length; ++i)
                        {
                            Transform tran = trans[i] as Transform;
                            if (tran.name == obj.Key)
                            {
                                bindPose.Add(tran.localToWorldMatrix);
                                listExtra.Add(bakedTrans[i]);
                            }
                        }
                    }

                    Transform[] totalTransform = new Transform[boneTransform.Length + listExtra.Count];
                    System.Array.Copy(boneTransform, totalTransform, boneTransform.Length);
                    System.Array.Copy(listExtra.ToArray(), 0, totalTransform, boneTransform.Length, listExtra.Count);
                    boneTransform = totalTransform;
                    //boneTransform = boneTransform;

                    extraBoneInfo               = new ExtraBoneInfo();
                    extraBoneInfo.extraBone     = new string[listExtra.Count];
                    extraBoneInfo.extraBindPose = new Matrix4x4[listExtra.Count];
                    for (int i = 0; i != listExtra.Count; ++i)
                    {
                        extraBoneInfo.extraBone[i]     = listExtra[i].name;
                        extraBoneInfo.extraBindPose[i] = bindPose[bindPose.Count - listExtra.Count + i];
                    }
                }
                Reset();
                AddMeshVertex2Generate(meshRender, boneTransform, bindPose.ToArray());

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

                UnityEditor.Animations.AnimatorController controller = animator.runtimeAnimatorController as UnityEditor.Animations.AnimatorController;
                Debug.Assert(controller.layers.Length > 0);
                cacheTransition.Clear();
                cacheAnimationEvent.Clear();
                UnityEditor.Animations.AnimatorControllerLayer layer = controller.layers[0];
                AnalyzeStateMachine(layer.stateMachine, animator, meshRender, 0, aniFps, 0);
                generateCount = generateInfo.Count;
            }
        }
        void AnalyzeStateMachine(UnityEditor.Animations.AnimatorStateMachine stateMachine,
                                 Animator animator,
                                 SkinnedMeshRenderer[] meshRender,
                                 int layer,
                                 int bakeFPS,
                                 int animationIndex)
        {
            AnimationInstancing instance = generatedPrefab.GetComponent <AnimationInstancing>();

            if (instance == null)
            {
                Debug.LogError("You should select a prefab with AnimationInstancing component.");
                return;
            }
            if (string.IsNullOrEmpty(instance.cfgName))
            {
                instance.cfgName = generatedPrefab.name;
            }

            for (int i = 0; i != stateMachine.states.Length; ++i)
            {
                ChildAnimatorState state = stateMachine.states[i];
                if (state.state == null || state.state.motion == null) // add by chenbin
                {
                    continue;                                          // add by chenbin
                }                                                      // add by chenbin
                bool needBake = false;
                if (!generateAnims.TryGetValue(state.state.motion.name, out needBake))
                {
                    continue;
                }
                foreach (var obj in generateInfo)
                {
                    if (obj.info.animationName == state.state.motion.name)
                    {
                        needBake = false;
                        break;
                    }
                }

                if (!needBake)
                {
                    continue;
                }

                AnimationBakeInfo bake = new AnimationBakeInfo();
                bake.length               = state.state.motion.averageDuration;
                bake.animator             = animator;
                bake.animator.cullingMode = AnimatorCullingMode.AlwaysAnimate;
                bake.meshRender           = meshRender;
                bake.layer = layer;
                bake.info  = new AnimationInfo();
                bake.info.animationName     = state.state.motion.name;
                bake.info.animationNameHash = state.state.nameHash;
                bake.info.animationIndex    = animationIndex;
                bake.info.totalFrame        = (int)(state.state.motion.averageDuration * bakeFPS);
                bake.info.fps        = bakeFPS;
                bake.info.rootMotion = true;
                if (bake.info.rootMotion)
                {
                    bake.info.velocity        = new Vector3[bake.info.totalFrame];
                    bake.info.angularVelocity = new Vector3[bake.info.totalFrame];
                }
                generateInfo.Add(bake);
                animationIndex += bake.info.totalFrame;
                totalFrame     += bake.info.totalFrame;

                bake.info.eventList = new List <AnimationEvent>();
                AnimationClip clip = state.state.motion as AnimationClip;
                foreach (var evt in clip.events)
                {
                    AnimationEvent aniEvent = new AnimationEvent();
                    aniEvent.function        = evt.functionName;
                    aniEvent.floatParameter  = evt.floatParameter;
                    aniEvent.intParameter    = evt.intParameter;
                    aniEvent.stringParameter = evt.stringParameter;
                    aniEvent.time            = evt.time;
                    if (evt.objectReferenceParameter != null)
                    {
                        aniEvent.objectParameter = evt.objectReferenceParameter.name;
                    }
                    else
                    {
                        aniEvent.objectParameter = "";
                    }
                    bake.info.eventList.Add(aniEvent);
                }

                cacheTransition.Add(state.state, state.state.transitions);
                state.state.transitions = null;
                cacheAnimationEvent.Add(clip, clip.events);
                UnityEngine.AnimationEvent[] tempEvent = new UnityEngine.AnimationEvent[0];
                UnityEditor.AnimationUtility.SetAnimationEvents(clip, tempEvent);
            }
            for (int i = 0; i != stateMachine.stateMachines.Length; ++i)
            {
                AnalyzeStateMachine(stateMachine.stateMachines[i].stateMachine, animator, meshRender, layer, bakeFPS, animationIndex);
            }
        }
 public void AddBoundingSphere(AnimationInstancing instance)
 {
     boundingSphere[usedBoundingSphereCount++] = instance.boundingSpere;
     cullingGroup.SetBoundingSphereCount(usedBoundingSphereCount);
     instance.visible = cullingGroup.IsVisible(usedBoundingSphereCount - 1);
 }
Esempio n. 25
0
        public void Attach(string boneName, AnimationInstancing attachment)
        {
            int index    = -1;
            int hashBone = boneName.GetHashCode();

            for (int i = 0; i != allTransforms.Length; ++i)
            {
                if (allTransforms[i].name.GetHashCode() == hashBone)
                {
                    index = i;
                    break;
                }
            }
            Debug.Assert(index >= 0);
            if (index < 0)
            {
                Debug.LogError("Can't find the bone.");
                return;
            }

            attachment.parentInstance = this;

//			string vertexName = lodInfo[0].skinnedMeshRenderer[0].name.GetHashCode() +"_" + lodInfo[0].skinnedMeshRenderer[0].sharedMaterial.name.GetHashCode() + "_0";
            AnimationInstancingMgr.VertexCache parentCache = AnimationInstancingMgr.Instance.FindVertexCache(AnimationInstancingMgr.getVertexName(lodInfo[0].skinnedMeshRenderer[0]));
            listAttachment.Add(attachment);

            int skinnedMeshRenderCount = attachment.lodInfo[0].skinnedMeshRenderer.Length;
//			int nameCode = attachment.lodInfo[0].meshRenderer[0].name.GetHashCode() + boneName.GetHashCode();
            string nameCode = AnimationInstancingMgr.getVertexName(attachment.lodInfo[0].meshRenderer[0]);

            AnimationInstancingMgr.VertexCache cache = AnimationInstancingMgr.Instance.FindVertexCache(nameCode);
            // if we can reuse the VertexCache, we don't need to create one
            if (cache != null && cache.boneTextureIndex >= 0 &&
                cache.boneTextureIndex == parentCache.boneTextureIndex &&
                cache.boneIndex[0].x == index)
            {
                for (int i = 0; i != attachment.lodInfo.Length; ++i)
                {
                    LodInfo info = attachment.lodInfo[i];
                    for (int j = 0; j != info.meshRenderer.Length; ++j)
                    {
                        nameCode = AnimationInstancingMgr.getVertexName(info.meshRenderer[j], boneName.GetHashCode());
                        cache    = AnimationInstancingMgr.Instance.FindVertexCache(nameCode);
                        info.vertexCacheList[info.skinnedMeshRenderer.Length + j] = cache;
                    }
                }
                return;
            }

            AnimationInstancingMgr.Instance.AddMeshVertex(attachment,
                                                          attachment.lodInfo,
                                                          null,
                                                          null,
                                                          attachment.bonePerVertex,
                                                          boneName);

            for (int i = 0; i != attachment.lodInfo.Length; ++i)
            {
                LodInfo info = attachment.lodInfo[i];
                for (int j = 0; j != info.meshRenderer.Length; ++j)
                {
                    cache = info.vertexCacheList[info.skinnedMeshRenderer.Length + j];
                    Debug.Assert(cache != null);
                    if (cache == null)
                    {
                        Debug.LogError("Can't find the VertexCache.");
                        continue;
                    }
                    Debug.Assert(cache.boneTextureIndex < 0 || cache.boneIndex[0].x != index);

                    AnimationInstancingMgr.Instance.BindAttachment(parentCache, info.meshFilter[j].sharedMesh, index);
                    AnimationInstancingMgr.Instance.SetupAdditionalData(cache);
                    cache.boneTextureIndex = parentCache.boneTextureIndex;
                }
            }
        }