示例#1
0
        /// <summary>
        /// 编码成AnimationCurve
        /// </summary>
        /// <param name="clip"></param>
        /// <param name="curve"></param>
        public void encodeData(CompressedClipData clip, AnimationCurve curve)
        {
            List <Keyframe> keys = new List <Keyframe>(curve.keys);

            deleteOverframe(clip.frameRate, keys);
            EncodeFrames(clip, curve, keys);
        }
        /// <summary>
        /// 编码成AnimationCurve
        /// </summary>
        /// <param name="clip"></param>
        /// <param name="curve"></param>
        public void encodeData(CompressedClipData clip, AnimationCurve curve, ValueMode valueMode, bool tan)
        {
            float           maxTime   = clip.length;
            float           time      = clip.length;
            float           frameRate = clip.frameRate;
            List <Keyframe> keys      = new List <Keyframe>(curve.keys);

            deleteOverframe(frameRate, keys);
            var length = keys.Count;

            //keysData = new uint[length];
            if (valueMode == ValueMode.Byte1)
            {
                keysValueByte = new byte[length];
            }
            else
            {
                keysValueByte = new byte[length * 2];
            }
            if (tan)
            {
                keysTans = new float[length];
            }
            //计算最大值和最小值
            valueMin = float.MaxValue;
            valueMax = float.MinValue;
            for (int i = 0; i < length; i++)
            {
                var key = keys[i];
                valueMin = Mathf.Min(valueMin, key.value);
                valueMax = Mathf.Max(valueMax, key.value);
            }
            int timeBytes = Mathf.CeilToInt((time * frameRate + 1) / 8);

            keysTime = new byte[timeBytes];

            float valueSize = valueMax - valueMin;

            //编码时间和关键帧值
            for (int i = 0; i < length; i++)
            {
                var key = keys[i];
                //时间
                int  keyIndex     = Mathf.RoundToInt(key.time * frameRate);
                int  byteIndex    = keyIndex / 8;
                int  byteBit      = keyIndex % 8;
                byte keysTimeByte = keysTime[byteIndex];
                keysTime[byteIndex] |= (byte)(1 << byteBit);

                encodBytes(keysValueByte, valueMode, i, ref key);
                if (tan)
                {
                    keysTans[i] = key.inTangent;
                }
            }
            this.valueMode = (byte)valueMode;
            encodeDebugData(keys);
        }
示例#3
0
        protected virtual void InitEncode(CompressedClipData clip, AnimationCurve curve, List <Keyframe> keys)
        {
            //计算最大值和最小值
            valueMin = float.MaxValue;
            valueMax = float.MinValue;
            var keysCount = keys.Count;

            for (int i = 0; i < keysCount; i++)
            {
                var key = keys[i];
                valueMin = Mathf.Min(valueMin, key.value);
                valueMax = Mathf.Max(valueMax, key.value);
            }
            this.keysValueByte = new byte[keysCount];
        }
示例#4
0
        //压缩曲线数据
        void CompressCurveData(CompressedClipData compressingData, EditorCurveBinding binding)
        {
            if (binding.isPPtrCurve)
            {
                //属性帧不压缩,还原到stubClip里
                var keyframes = AnimationUtility.GetObjectReferenceCurve(rawClip, binding);
                AnimationUtility.SetObjectReferenceCurve(stubClip, binding, keyframes);
            }
            else if (UncompressFields.Contains(binding.propertyName))
            {
                //白名单内的属性也不压缩
                var curve = AnimationUtility.GetEditorCurve(rawClip, binding);
                AnimationUtility.SetEditorCurve(stubClip, binding, curve);
            }
            else
            {
                //从共享数据里获取字段ID
                var propertyId = shareData.getFieldIndex(binding.path, binding.type.FullName, binding.propertyName);
                //
                var curve = AnimationUtility.GetEditorCurve(rawClip, binding);// curves[i];
                //检测是否需要存储切线数据
                bool needStoreTanData = false;
                if (stateFlag && stateFlag.rotationTan && binding.propertyName.StartsWith("m_LocalRotation."))
                {
                    needStoreTanData = true;
                }

                //选择不同的存储方式
                CurveDataBasicValues curveData;
                if (needStoreTanData)
                {
                    var storeTanData = new CurveDataStoreTan();
                    compressingData.curvesStoreTan.Add(storeTanData);
                    curveData = storeTanData;
                }
                else
                {
                    var calcTanData = new CurveDataCalcTan();
                    compressingData.curvesCalcTan.Add(calcTanData);
                    curveData = calcTanData;
                }
                curveData.initProperty(propertyId, binding.path, binding.type.FullName, binding.propertyName);
                curveData.encodeData(compressingData, curve);
                stateMachineFields.Add(binding);
            }
        }
示例#5
0
        //压缩Clip数据
        public CompressedClipData CompressClipData()
        {
            CompressedClipData compressingData = ScriptableObject.CreateInstance <CompressedClipData>();

            compressingData.name      = rawClip.name + "_data";
            compressingData.length    = rawClip.length;
            compressingData.wrapMode  = (byte)rawClip.wrapMode;
            compressingData.frameRate = (byte)rawClip.frameRate;
            //data.shareData = shareData;
            EditorCurveBinding[] bindings = AnimationUtility.GetCurveBindings(rawClip);

            for (int i = 0; i < bindings.Length; i++)
            {
                CompressCurveData(compressingData, bindings[i]);
            }
            compressingData.shareData = shareData;
            EditorUtility.SetDirty(shareData);
            return(compressingData);
        }
示例#6
0
        protected virtual void EncodeFrames(CompressedClipData clip, AnimationCurve curve, List <Keyframe> keyframes)
        {
            float maxTime    = clip.length;
            float clipLength = clip.length;
            float frameRate  = clip.frameRate;
            var   keysCount  = keyframes.Count;

            InitEncode(clip, curve, keyframes);
            initFramesTime(clipLength, frameRate);

            //编码时间和关键帧值
            for (int keyIndex = 0; keyIndex < keysCount; keyIndex++)
            {
                var keyframe = keyframes[keyIndex];
                EncodeFrameTime(keysTime, keyIndex, frameRate, keyframe.time);
                EncodeFrameValue(keyIndex, ref keyframe);
            }
            encodeDebugData(keyframes);
        }
示例#7
0
        //解码动画曲线
        public virtual AnimationCurve decodeData(CompressedClipData clip)
        {
            float          maxTime = clip.length;
            AnimationCurve curve   = new AnimationCurve();
            var            length  = keysValueByte.Length;

            // float ValueMax = valueMode == ValueMode.Byte1 ? byte.MaxValue : ushort.MaxValue;
            var keys = new Keyframe[length];

            for (int i = 0; i < length; i++)
            {
                Keyframe key = new Keyframe();
                DecodeFrame(i, ref key);
                keys[i] = key;
            }
            decodeTime(clip, keys);
            decodeDebugData(keys);
            curve.keys = keys;
            SmoothTangents(curve, length);
            return(curve);
        }
        //解码动画曲线
        public AnimationCurve decodeData(CompressedClipData clip)
        {
            float          maxTime   = clip.length;
            ValueMode      valueMode = (ValueMode)this.valueMode;
            AnimationCurve curve     = new AnimationCurve();
            var            length    = keysValueByte.Length;

            if (valueMode == ValueMode.Byte2 || valueMode == ValueMode.ValueTan)
            {
                length = length / 2;
            }
            // float ValueMax = valueMode == ValueMode.Byte1 ? byte.MaxValue : ushort.MaxValue;
            var  keys     = new Keyframe[length];
            bool tansData = keysTans != null && keysTans.Length > 0;

            for (int i = 0; i < length; i++)
            {
                Keyframe key = new Keyframe();
                decodeBytes(keysValueByte, valueMode, i, ref key);
                if (tansData)
                {
                    key.inTangent  = keysTans[i];
                    key.outTangent = keysTans[i];
                }
                keys[i] = key;
            }
            decodeTime(clip, keys);
            decodeDebugData(keys);
            curve.keys = keys;
            if (valueMode != ValueMode.ValueTan && !tansData)
            {
                for (int i = 0; i < length; i++)
                {
                    curve.SmoothTangents(i, 0f);
                }
            }

            return(curve);
        }
示例#9
0
        //解码时间信息
        void decodeTime(CompressedClipData clip, Keyframe[] keys)
        {
            float frameRate = clip.frameRate;

            for (int i = 0, idx = 0; i < keysTime.Length; i++)
            {
                byte timeBits = keysTime[i];
                for (int j = 0; j < 8; j++)
                {
                    if (((timeBits >> j) & 1) != 0)
                    {
                        if (keys.Length <= idx)
                        {
                            Debug.LogError("解码动画数据异常:帧时间索引:" + idx + " 当前帧:" + (i * 8 + j) + " 动画名称:" + clip.name + " 曲线:" + property);
                        }
                        else
                        {
                            keys[idx++].time = (i * 8 + j) / frameRate;
                        }
                    }
                }
            }
        }
示例#10
0
        public string Process()
        {
            this.rawClip = animatorState.motion as AnimationClip;
            if (!rawClip)
            {
                return(null);
            }
            this.stateFlag = findStateFlag(animatorState);
            //查找标记,检查是否可以跳过
            if (stateFlag && stateFlag.skipCompressed)
            {
                return(null);
            }
            var size = UnityEngine.Profiler.GetRuntimeMemorySize(rawClip);

            //小于16K 不压缩
            if (size < 1024 * 16)
            {
                return(null);
            }

            string rawClipPath = AssetDatabase.GetAssetPath(rawClip);

            if (string.IsNullOrEmpty(rawClipPath))
            {
                return(null);
            }

            string anim_gen_dir = Path.GetDirectoryName(rawClipPath) + "/_anim_gen_";
            string dataDir      = anim_gen_dir + "/datas";
            string stubDir      = anim_gen_dir + "/stubs";

            Directory.CreateDirectory(anim_gen_dir);
            Directory.CreateDirectory(dataDir);
            Directory.CreateDirectory(stubDir);

            this.shareData = getShareData(anim_gen_dir);
            this.stubClip  = new AnimationClip();
            AnimationClipSettings settings = AnimationUtility.GetAnimationClipSettings(rawClip);

            stubClip.SetCurve("", typeof(CompressedAnimationDirver), "stubAnimParam", AnimationCurve.Linear(0, 0, rawClip.length, 1));
            stubClip.name = rawClip.name + "_stub";
            this.clipData = CompressClipData();
            AnimationUtility.SetAnimationClipSettings(stubClip, settings);

            //*注意:这里是为了兼容通过AnimationClipSettings设置Loop而Wrap没设置
            if (settings.loopTime)
            {
                clipData.wrapMode = (byte)WrapMode.Loop;
                stubClip.wrapMode = WrapMode.Loop;
            }
            else
            {
                stubClip.wrapMode = rawClip.wrapMode;
            }
            animatorState.motion = stubClip;
            AssetDatabase.CreateAsset(stubClip, stubDir + "/" + stubClip.name + ".anim");
            string dataPath = dataDir + "/" + clipData.name + ".asset";

            AssetDatabase.CreateAsset(clipData, dataPath);
            var stateProxy = animatorState.AddStateMachineBehaviour <CompressionAnimatorStateProxy>();

            stateProxy.data = clipData;
            return(dataPath);
        }
示例#11
0
        internal void DoStateEnter(Animator animator, ref AnimatorStateInfo stateInfo, CompressedClipData data)
        {
            if (!data)
            {
                playingClip = null;
                return;
            }
            var clip      = data.getOrCreateClip();
            var anim      = GetOrCreateAnimation();
            var clipState = anim[clip.name];

            if (clipState == null)
            {
                anim.AddClip(clip, clip.name);
            }
            if (!anim.isPlaying)
            {
                anim.Play(clip.name);
            }
            else
            {
                anim.CrossFade(clip.name);
            }
            animator.updateMode = AnimatorUpdateMode.AnimatePhysics;
            playingClip         = clip;
            //anim.localBounds = new Bounds(new Vector3(9527 * 2, 9527 * 2, -9527 * 100), new Vector3());
        }
示例#12
0
        internal void DoStateExit(Animator animator, ref AnimatorStateInfo stateInfo, CompressedClipData data)
        {
            if (!data)
            {
                return;
            }
            var clip = data.getOrCreateClip();

            anim.Stop(clip.name);
            if (clip == playingClip)
            {
                playingClip = null;
            }
        }
 protected override void InitEncode(CompressedClipData clip, AnimationCurve curve, List <Keyframe> keys)
 {
     base.InitEncode(clip, curve, keys);
     keysTans = new float[keys.Count];
 }