Exemplo n.º 1
0
        /// <summary>
        /// Compresses the AnimationCurve data currently held in these VectorHandCurves.
        /// </summary>
        public void Compress()
        {
            AnimationCurveUtil.Compress(isTrackedCurve, maxDelta: 0.001f);

            palmPosCurves.Compress();
            palmRotCurves.Compress();

            for (int i = 0; i < jointPositionCurves.Length; i++)
            {
                jointPositionCurves[i].Compress(maxDistanceError: 0.001f);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Compresses the curves in these QuaternionCurves using
        /// AnimationCurveUtil.CompressRotations.
        /// </summary>
        public void Compress(float maxAngleError = 1f)
        {
            AnimationCurve outXCurve, outYCurve, outZCurve, outWCurve;

            AnimationCurveUtil.CompressRotations(xCurve, yCurve, zCurve, wCurve,
                                                 out outXCurve, out outYCurve,
                                                 out outZCurve, out outWCurve,
                                                 maxAngleError: maxAngleError);
            xCurve = outXCurve;
            yCurve = outYCurve;
            zCurve = outZCurve;
            wCurve = outWCurve;
        }
Exemplo n.º 3
0
        private ColorAnimation UpdateAnimation()
        {
            if (!animationDirty)
            {
                return(animation);
            }

            animation.Duration   = AnimationDuration;
            animation.AlphaCurve = CreateEaseAnimationCurve();
            animation.RedCurve   = AnimationCurveUtil.Constant(0, AnimationDuration, Color.r);
            animation.GreenCurve = AnimationCurveUtil.Constant(0, AnimationDuration, Color.g);
            animation.BlueCurve  = AnimationCurveUtil.Constant(0, AnimationDuration, Color.b);

            animationDirty = false;
            return(animation);
        }
Exemplo n.º 4
0
    void Start()
    {
        //カーブを設定
        if (Application.platform == RuntimePlatform.WindowsEditor && generateCurveOnStartEditor)
        {
            Keyframe[] keys = new Keyframe[envelopeKeys.Length];
            for (int i = 0; i < envelopeKeys.Length; i++)
            {
                EnvelopeKey envKey = envelopeKeys[i];
                keys[i] = AnimationCurveUtil.GetNewKey(envKey.time, envKey.value, envKey.leftTangent, envKey.rightTangent);
            }

            envelopeCurve              = new AnimationCurve(keys);
            envelopeCurve.preWrapMode  = preWrapMode;
            envelopeCurve.postWrapMode = postWrapMode;
            AnimationCurveUtil.UpdateAllLinearTangents(envelopeCurve);
        }
    }
Exemplo n.º 5
0
        protected void finishRecording(ProgressBar progress)
        {
            string targetFolderPath = targetFolder.Path;

            if (targetFolderPath == null)
            {
                if (gameObject.scene.IsValid() && !string.IsNullOrEmpty(gameObject.scene.path))
                {
                    string sceneFolder = Path.GetDirectoryName(gameObject.scene.path);
                    targetFolderPath = Path.Combine(sceneFolder, "Recordings");
                }
                else
                {
                    targetFolderPath = Path.Combine("Assets", "Recordings");
                }
            }

            int    folderSuffix = 1;
            string finalSubFolder;

            do
            {
                finalSubFolder = Path.Combine(targetFolderPath, recordingName + " " + folderSuffix.ToString().PadLeft(2, '0'));
                folderSuffix++;
            } while (Directory.Exists(finalSubFolder));

            string dataDirectory = Path.Combine(finalSubFolder, "_Data");

            Directory.CreateDirectory(dataDirectory);
            Directory.CreateDirectory(finalSubFolder);
            AssetDatabase.Refresh();

            progress.Begin(6, "Saving Recording", "", () => {
                if (!_isRecording)
                {
                    return;
                }
                _isRecording = false;

                //Turn on auto-pushing for all auto-proxy components
                foreach (var autoProxy in GetComponentsInChildren <AutoValueProxy>())
                {
                    autoProxy.autoPushingEnabled = true;
                }

                progress.Begin(3, "", "Reverting Scene State", () => {
                    //For all of our transform data, revert to the first piece recorded
                    progress.Begin(_transformData.Count, "", "", () => {
                        foreach (var pair in _transformData)
                        {
                            progress.Step();
                            var transform = pair.Key;
                            var data      = pair.Value;

                            if (transform == null || data.Count == 0)
                            {
                                continue;
                            }

                            data[0].ApplyTo(transform);
                        }
                    });

                    //For all recorded curves, revert to start of curve
                    progress.Begin(_curves.Count, "", "", () => {
                        AnimationClip tempClip = new AnimationClip();
                        foreach (var data in _curves)
                        {
                            progress.Step();
                            AnimationUtility.SetEditorCurve(tempClip, data.binding, data.curve);
                        }
                        tempClip.SampleAnimation(gameObject, 0);
                    });

                    //For all non-transform components, revert to original serialized values
                    progress.Begin(_initialComponentData.Count, "", "", () => {
                        foreach (var pair in _initialComponentData)
                        {
                            progress.Step();
                            var component = pair.Key;
                            var sobj      = pair.Value;

                            if (component == null || component is Transform)
                            {
                                continue;
                            }


                            //We don't want to revert method recordings!
                            if (component is MethodRecording ||
                                component is RecordedAudio)
                            {
                                continue;
                            }

                            var flags = sobj.FindProperty("m_ObjectHideFlags");
                            if (flags == null)
                            {
                                Debug.LogError("Could not find hide flags for " + component);
                                continue;
                            }

                            //We have to dirty the serialized object somehow
                            //apparently there is no api to do this
                            //all objects have hide flags so we just touch them and revert them
                            int originalFlags = flags.intValue;
                            flags.intValue    = ~originalFlags;
                            flags.intValue    = originalFlags;

                            try {
                                //Applies previous state of entire component
                                sobj.ApplyModifiedProperties();
                            } catch (Exception e) {
                                Debug.LogError("Exception when trying to apply properties to " + component);
                                Debug.LogException(e);
                            }
                        }
                    });
                });

                progress.Begin(1, "", "Patching Materials: ", () => {
                    GetComponentsInChildren(true, _recorders);
                    foreach (var recorder in _recorders)
                    {
                        DestroyImmediate(recorder);
                    }

                    //Patch up renderer references to materials
                    var allMaterials = Resources.FindObjectsOfTypeAll <Material>().
                                       Query().
                                       Where(AssetDatabase.IsMainAsset).
                                       ToList();

                    var renderers = GetComponentsInChildren <Renderer>(includeInactive: true);

                    progress.Begin(renderers.Length, "", "", () => {
                        foreach (var renderer in renderers)
                        {
                            progress.Step(renderer.name);

                            var materials = renderer.sharedMaterials;
                            for (int i = 0; i < materials.Length; i++)
                            {
                                var material = materials[i];
                                if (material == null)
                                {
                                    continue;
                                }

                                if (!AssetDatabase.IsMainAsset(material))
                                {
                                    var matchingMaterial = allMaterials.Query().FirstOrDefault(m => material.name.Contains(m.name) &&
                                                                                               material.shader == m.shader);

                                    if (matchingMaterial != null)
                                    {
                                        materials[i] = matchingMaterial;
                                    }
                                }
                            }
                            renderer.sharedMaterials = materials;
                        }
                    });
                });

                progress.Begin(_behaviourActivity.Count, "", "Converting Activity Data: ", () => {
                    foreach (var pair in _behaviourActivity)
                    {
                        var targetBehaviour = pair.Key;
                        var activityData    = pair.Value;

                        if (targetBehaviour == null)
                        {
                            continue;
                        }

                        progress.Step(targetBehaviour.name);

                        string path         = AnimationUtility.CalculateTransformPath(targetBehaviour.transform, transform);
                        Type type           = targetBehaviour.GetType();
                        string propertyName = "m_Enabled";

                        AnimationCurve curve = new AnimationCurve();
                        foreach (var dataPoint in activityData)
                        {
                            int index = curve.AddKey(dataPoint.time, dataPoint.enabled ? 1 : 0);
                            AnimationUtility.SetKeyLeftTangentMode(curve, index, AnimationUtility.TangentMode.Constant);
                            AnimationUtility.SetKeyRightTangentMode(curve, index, AnimationUtility.TangentMode.Constant);
                        }

                        if (curve.IsConstant())
                        {
                            continue;
                        }

                        var binding = EditorCurveBinding.FloatCurve(path, type, propertyName);

                        if (_curves.Query().Any(c => c.binding == binding))
                        {
                            Debug.LogError("Binding already existed?");
                            Debug.LogError(binding.path + " : " + binding.propertyName);
                            continue;
                        }

                        _curves.Add(new CurveData()
                        {
                            binding = binding,
                            curve   = curve
                        });
                    }
                });

                progress.Begin(_transformData.Count, "", "Converting Transform Data: ", () => {
                    foreach (var pair in _transformData)
                    {
                        var targetTransform = pair.Key;
                        var targetData      = pair.Value;

                        progress.Step(targetTransform.name);

                        string path = AnimationUtility.CalculateTransformPath(targetTransform, transform);

                        bool isActivityConstant = true;
                        bool isPositionConstant = true;
                        bool isRotationConstant = true;
                        bool isScaleConstant    = true;

                        {
                            bool startEnabled        = targetData[0].enabled;
                            Vector3 startPosition    = targetData[0].localPosition;
                            Quaternion startRotation = targetData[0].localRotation;
                            Vector3 startScale       = targetData[0].localScale;
                            for (int i = 1; i < targetData.Count; i++)
                            {
                                isActivityConstant &= targetData[i].enabled == startEnabled;
                                isPositionConstant &= targetData[i].localPosition == startPosition;
                                isRotationConstant &= targetData[i].localRotation == startRotation;
                                isScaleConstant    &= targetData[i].localScale == startScale;
                            }
                        }

                        for (int i = 0; i < TransformData.CURVE_COUNT; i++)
                        {
                            string propertyName = TransformData.GetName(i);
                            Type type           = typeof(Transform);

                            AnimationCurve curve = new AnimationCurve();
                            var dataType         = TransformData.GetDataType(i);

                            switch (dataType)
                            {
                            case TransformDataType.Position:
                                if (isPositionConstant)
                                {
                                    continue;
                                }
                                break;

                            case TransformDataType.Rotation:
                                if (isRotationConstant)
                                {
                                    continue;
                                }
                                break;

                            case TransformDataType.Scale:
                                if (isScaleConstant)
                                {
                                    continue;
                                }
                                break;

                            case TransformDataType.Activity:
                                if (isActivityConstant)
                                {
                                    continue;
                                }
                                type = typeof(GameObject);
                                break;
                            }

                            for (int j = 0; j < targetData.Count; j++)
                            {
                                int index = curve.AddKey(targetData[j].time, targetData[j].GetFloat(i));
                                if (dataType == TransformDataType.Activity)
                                {
                                    AnimationUtility.SetKeyLeftTangentMode(curve, index, AnimationUtility.TangentMode.Constant);
                                    AnimationUtility.SetKeyRightTangentMode(curve, index, AnimationUtility.TangentMode.Constant);
                                }
                            }

                            var binding = EditorCurveBinding.FloatCurve(path, type, propertyName);

                            if (_curves.Query().Any(c => c.binding == binding))
                            {
                                Debug.LogError("Duplicate object was created??");
                                Debug.LogError("Named " + targetTransform.name + " : " + binding.path + " : " + binding.propertyName);
                            }
                            else
                            {
                                _curves.Add(new CurveData()
                                {
                                    binding = binding,
                                    curve   = curve
                                });
                            }
                        }
                    }
                });

                progress.Begin(_curves.Count, "", "Compressing Data: ", () => {
                    _curves.Sort((a, b) => a.binding.propertyName.CompareTo(b.binding.propertyName));
                    foreach (var data in _curves)
                    {
                        using (new ProfilerSample("A")) {
                            EditorCurveBinding binding = data.binding;
                            AnimationCurve curve       = data.curve;

                            progress.Step(binding.propertyName);

                            GameObject animationGameObject;
                            {
                                var animatedObj = AnimationUtility.GetAnimatedObject(gameObject, binding);
                                if (animatedObj is GameObject)
                                {
                                    animationGameObject = animatedObj as GameObject;
                                }
                                else
                                {
                                    animationGameObject = (animatedObj as Component).gameObject;
                                }
                            }

                            bool isMatBinding = binding.propertyName.StartsWith("material.") &&
                                                binding.type.IsSubclassOf(typeof(Renderer));

                            //But if the curve is constant, just get rid of it!
                            //Except for material curves, which we always need to keep
                            if (curve.IsConstant() && !isMatBinding)
                            {
                                //Check to make sure there are no other matching curves that are
                                //non constant.  If X and Y are constant but Z is not, we need to
                                //keep them all :(
                                if (_curves.Query().Where(p => p.binding.path == binding.path &&
                                                          p.binding.type == binding.type &&
                                                          p.binding.propertyName.TrimEnd(2) == binding.propertyName.TrimEnd(2)).
                                    All(k => k.curve.IsConstant()))
                                {
                                    continue;
                                }
                            }

                            //First do a lossless compression
                            using (new ProfilerSample("B")) {
                                curve = AnimationCurveUtil.Compress(curve, Mathf.Epsilon, checkSteps: 3);
                            }

                            Transform targetTransform = null;
                            var targetObj             = AnimationUtility.GetAnimatedObject(gameObject, binding);
                            if (targetObj is GameObject)
                            {
                                targetTransform = (targetObj as GameObject).transform;
                            }
                            else if (targetObj is Component)
                            {
                                targetTransform = (targetObj as Component).transform;
                            }
                            else
                            {
                                Debug.LogError("Target obj was of type " + targetObj.GetType().Name);
                            }
                        }
                    }
                });
            });

            progress.Begin(4, "Finalizing Assets", "", () => {
                var postProcessComponent = gameObject.AddComponent <HierarchyPostProcess>();

                GameObject myGameObject = gameObject;

                DestroyImmediate(this);

                //Create all the files for the method recording
                progress.Step("Creating Method Recording Files...");
                var methodRecordings = myGameObject.GetComponentsInChildren <MethodRecording>();
                for (int i = 0; i < methodRecordings.Length; i++)
                {
                    var methodRecording = methodRecordings[i];
                    string fullPath     = Path.Combine(finalSubFolder, "MethodRecording_" + i + ".asset");
                    methodRecording.ExitRecordingMode(fullPath);
                }

                postProcessComponent.dataFolder = new AssetFolder(dataDirectory);

                //Create the asset that holds all of the curve data
                progress.Begin(_curves.Count, "", "", () => {
                    string curveFile = Path.Combine(dataDirectory, "Curves.data");
                    using (var writer = File.CreateText(curveFile)) {
                        foreach (var data in _curves)
                        {
                            progress.Step(data.binding.propertyName);

                            var bindingData = new EditorCurveBindingData()
                            {
                                path         = data.binding.path,
                                propertyName = data.binding.propertyName,
                                typeName     = data.binding.type.Name,
                                curve        = data.curve
                            };

                            writer.WriteLine(JsonUtility.ToJson(bindingData));
                        }
                    }
                });

                //Create the asset that holds all of the leap data
                if (_leapData.Count > 0)
                {
                    progress.Begin(_leapData.Count, "", "", () => {
                        string leapFile = Path.Combine(dataDirectory, "Frames.data");

                        using (var writer = File.CreateText(leapFile)) {
                            for (int i = 0; i < _leapData.Count; i++)
                            {
                                progress.Step("Frame " + i);
                                writer.WriteLine(JsonUtility.ToJson(_leapData[i]));
                            }
                        }
                    });
                }

                progress.Step("Creating Final Prefab...");
                //Init the post process component
                postProcessComponent.recordingName = recordingName;
                postProcessComponent.assetFolder   = new AssetFolder(finalSubFolder);

                string prefabPath = Path.Combine(finalSubFolder, recordingName + " Raw.prefab");
                PrefabUtility.CreatePrefab(prefabPath.Replace('\\', '/'), myGameObject);

                AssetDatabase.Refresh();

                EditorApplication.isPlaying = false;
            });
        }
        private void doCompression(ProgressBar progress,
                                   UnityEngine.Object targetObject,
                                   Dictionary <EditorCurveBinding, AnimationCurve> toCompress,
                                   Dictionary <EditorCurveBinding, AnimationCurve> bindingMap)
        {
            var propertyToMaxError = calculatePropertyErrors(targetObject);

            List <EditorCurveBinding> bindings;

            progress.Begin(6, "", targetObject.name, () => {
                //First do rotations
                bindings = toCompress.Keys.Query().ToList();
                progress.Begin(bindings.Count, "", "", () => {
                    foreach (var wBinding in bindings)
                    {
                        progress.Step();

                        if (!wBinding.propertyName.EndsWith(".w"))
                        {
                            continue;
                        }

                        string property = wBinding.propertyName.Substring(0, wBinding.propertyName.Length - 2);
                        string xProp    = property + ".x";
                        string yProp    = property + ".y";
                        string zProp    = property + ".z";

                        var xMaybe = toCompress.Keys.Query().FirstOrNone(t => t.propertyName == xProp);
                        var yMaybe = toCompress.Keys.Query().FirstOrNone(t => t.propertyName == yProp);
                        var zMaybe = toCompress.Keys.Query().FirstOrNone(t => t.propertyName == zProp);

                        Maybe.MatchAll(xMaybe, yMaybe, zMaybe, (xBinding, yBinding, zBinding) => {
                            float maxAngleError;
                            if (!propertyToMaxError.TryGetValue(property, out maxAngleError))
                            {
                                maxAngleError = rotationMaxError;
                            }

                            AnimationCurve compressedX, compressedY, compressedZ, compressedW;
                            AnimationCurveUtil.CompressRotations(toCompress[xBinding],
                                                                 toCompress[yBinding],
                                                                 toCompress[zBinding],
                                                                 toCompress[wBinding],
                                                                 out compressedX,
                                                                 out compressedY,
                                                                 out compressedZ,
                                                                 out compressedW,
                                                                 maxAngleError);

                            bindingMap[xBinding] = compressedX;
                            bindingMap[yBinding] = compressedY;
                            bindingMap[zBinding] = compressedZ;
                            bindingMap[wBinding] = compressedW;

                            toCompress.Remove(xBinding);
                            toCompress.Remove(yBinding);
                            toCompress.Remove(zBinding);
                            toCompress.Remove(wBinding);
                        });
                    }
                });

                //Next do scales
                bindings = toCompress.Keys.Query().ToList();
                progress.Begin(bindings.Count, "", "", () => {
                    foreach (var binding in bindings)
                    {
                        progress.Step();

                        if (!binding.propertyName.EndsWith(".x") &&
                            !binding.propertyName.EndsWith(".y") &&
                            !binding.propertyName.EndsWith(".z"))
                        {
                            continue;
                        }

                        if (!binding.propertyName.Contains("LocalScale"))
                        {
                            continue;
                        }

                        bindingMap[binding] = AnimationCurveUtil.CompressScale(toCompress[binding], scaleMaxError);
                        toCompress.Remove(binding);
                    }
                });

                //Next do positions
                bindings = toCompress.Keys.Query().ToList();
                progress.Begin(bindings.Count, "", "", () => {
                    foreach (var xBinding in bindings)
                    {
                        progress.Step();

                        if (!xBinding.propertyName.EndsWith(".x"))
                        {
                            continue;
                        }

                        string property = xBinding.propertyName.Substring(0, xBinding.propertyName.Length - 2);
                        string yProp    = property + ".y";
                        string zProp    = property + ".z";

                        var yMaybe = toCompress.Keys.Query().FirstOrNone(t => t.propertyName == yProp);
                        var zMaybe = toCompress.Keys.Query().FirstOrNone(t => t.propertyName == zProp);

                        Maybe.MatchAll(yMaybe, zMaybe, (yBinding, zBinding) => {
                            float maxDistanceError;
                            if (!propertyToMaxError.TryGetValue(property, out maxDistanceError))
                            {
                                maxDistanceError = positionMaxError;
                            }

                            AnimationCurve compressedX, compressedY, compressedZ;
                            AnimationCurveUtil.CompressPositions(toCompress[xBinding],
                                                                 toCompress[yBinding],
                                                                 toCompress[zBinding],
                                                                 out compressedX,
                                                                 out compressedY,
                                                                 out compressedZ,
                                                                 maxDistanceError);

                            bindingMap[xBinding] = compressedX;
                            bindingMap[yBinding] = compressedY;
                            bindingMap[zBinding] = compressedZ;

                            toCompress.Remove(xBinding);
                            toCompress.Remove(yBinding);
                            toCompress.Remove(zBinding);
                        });
                    }
                });

                //Next do colors
                bindings = toCompress.Keys.Query().ToList();
                progress.Begin(bindings.Count, "", "", () => {
                    foreach (var rBinding in bindings)
                    {
                        progress.Step();

                        if (!rBinding.propertyName.EndsWith(".r"))
                        {
                            continue;
                        }

                        string property = rBinding.propertyName.Substring(0, rBinding.propertyName.Length - 2);
                        string gProp    = property + ".g";
                        string bProp    = property + ".b";

                        var gMaybe = toCompress.Keys.Query().FirstOrNone(t => t.propertyName == gProp);
                        var bMaybe = toCompress.Keys.Query().FirstOrNone(t => t.propertyName == bProp);

                        Maybe.MatchAll(gMaybe, bMaybe, (gBinding, bBinding) => {
                            AnimationCurve compressedR, compressedG, compressedB;
                            AnimationCurveUtil.CompressColorsHSV(toCompress[rBinding],
                                                                 toCompress[gBinding],
                                                                 toCompress[bBinding],
                                                                 out compressedR,
                                                                 out compressedG,
                                                                 out compressedB,
                                                                 colorHueMaxError,
                                                                 colorSaturationMaxError,
                                                                 colorValueMaxError);

                            bindingMap[rBinding] = compressedR;
                            bindingMap[gBinding] = compressedG;
                            bindingMap[bBinding] = compressedB;
                        });
                    }
                });

                //Then do color alpha
                bindings = toCompress.Keys.Query().ToList();
                progress.Begin(bindings.Count, "", "", () => {
                    foreach (var aBinding in bindings)
                    {
                        progress.Step();

                        if (!aBinding.propertyName.EndsWith(".a"))
                        {
                            continue;
                        }

                        var compressedA = AnimationCurveUtil.Compress(toCompress[aBinding], colorAlphaMaxError);

                        toCompress.Remove(aBinding);
                        bindingMap[aBinding] = compressedA;
                    }
                });

                //Then everything else
                bindings = toCompress.Keys.Query().ToList();
                progress.Begin(bindings.Count, "", "", () => {
                    foreach (var binding in bindings)
                    {
                        progress.Step();

                        float maxError;
                        if (!propertyToMaxError.TryGetValue(binding.propertyName, out maxError))
                        {
                            maxError = genericMaxError;
                        }

                        var compressedCurve = AnimationCurveUtil.Compress(toCompress[binding], maxError);

                        toCompress.Remove(binding);
                        bindingMap[binding] = compressedCurve;
                    }
                });
            });
        }
Exemplo n.º 7
0
 public void AddOffset(Vector3 offset)
 {
     _xCurve = AnimationCurveUtil.ConstantValueOffset(_xCurve, offset.x);
     _yCurve = AnimationCurveUtil.ConstantValueOffset(_yCurve, offset.y);
     _zCurve = AnimationCurveUtil.ConstantValueOffset(_zCurve, offset.z);
 }
Exemplo n.º 8
0
        protected void finishRecording(ProgressBar progress)
        {
            progress.Begin(5, "Saving Recording", "", () => {
                if (!_isRecording)
                {
                    return;
                }
                _isRecording = false;

                //Turn on auto-pushing for all auto-proxy components
                foreach (var autoProxy in GetComponentsInChildren <AutoValueProxy>())
                {
                    autoProxy.autoPushingEnabled = true;
                }

                progress.Begin(1, "", "Reverting Scene State", () => {
                    foreach (var pair in _initialTransformData)
                    {
                        pair.Key.localPosition = pair.Value.localPosition;
                        pair.Key.localRotation = pair.Value.localRotation;
                        pair.Key.localScale    = pair.Value.localScale;
                        pair.Key.gameObject.SetActive(pair.Value.enabled);
                    }

                    foreach (var pair in _initialActivityData)
                    {
                        EditorUtility.SetObjectEnabled(pair.Key, pair.Value);
                    }
                });

                progress.Begin(1, "", "Patching Materials: ", () => {
                    GetComponentsInChildren(true, _recorders);
                    foreach (var recorder in _recorders)
                    {
                        DestroyImmediate(recorder);
                    }

                    //Patch up renderer references to materials
                    var allMaterials = Resources.FindObjectsOfTypeAll <Material>().
                                       Query().
                                       Where(AssetDatabase.IsMainAsset).
                                       ToList();

                    var renderers = GetComponentsInChildren <Renderer>(includeInactive: true);

                    progress.Begin(renderers.Length, "", "", () => {
                        foreach (var renderer in renderers)
                        {
                            progress.Step(renderer.name);

                            var materials = renderer.sharedMaterials;
                            for (int i = 0; i < materials.Length; i++)
                            {
                                var material = materials[i];
                                if (!AssetDatabase.IsMainAsset(material))
                                {
                                    var matchingMaterial = allMaterials.Query().FirstOrDefault(m => material.name.Contains(m.name) &&
                                                                                               material.shader == m.shader);

                                    if (matchingMaterial != null)
                                    {
                                        materials[i] = matchingMaterial;
                                    }
                                }
                            }
                            renderer.sharedMaterials = materials;
                        }
                    });
                });

                progress.Begin(_behaviourActivity.Count, "", "Converting Activity Data: ", () => {
                    foreach (var pair in _behaviourActivity)
                    {
                        var targetBehaviour = pair.Key;
                        var activityData    = pair.Value;

                        progress.Step(targetBehaviour.name);

                        string path         = AnimationUtility.CalculateTransformPath(targetBehaviour.transform, transform);
                        Type type           = targetBehaviour.GetType();
                        string propertyName = "m_Enabled";

                        AnimationCurve curve = new AnimationCurve();
                        foreach (var dataPoint in activityData)
                        {
                            int index = curve.AddKey(dataPoint.time, dataPoint.enabled ? 1 : 0);
                            AnimationUtility.SetKeyLeftTangentMode(curve, index, AnimationUtility.TangentMode.Constant);
                            AnimationUtility.SetKeyRightTangentMode(curve, index, AnimationUtility.TangentMode.Constant);
                        }

                        if (curve.IsConstant())
                        {
                            continue;
                        }

                        var binding = EditorCurveBinding.FloatCurve(path, type, propertyName);

                        if (_curves.ContainsKey(binding))
                        {
                            Debug.LogError("Binding already existed?");
                            Debug.LogError(binding.path + " : " + binding.propertyName);
                            continue;
                        }
                        _curves.Add(binding, curve);
                    }
                });

                progress.Begin(_transformData.Count, "", "Converting Transform Data: ", () => {
                    foreach (var pair in _transformData)
                    {
                        var targetTransform = pair.Key;
                        var targetData      = pair.Value;

                        progress.Step(targetTransform.name);

                        string path = AnimationUtility.CalculateTransformPath(targetTransform, transform);

                        bool isActivityConstant = true;
                        bool isPositionConstant = true;
                        bool isRotationConstant = true;
                        bool isScaleConstant    = true;

                        {
                            bool startEnabled        = targetData[0].enabled;
                            Vector3 startPosition    = targetData[0].localPosition;
                            Quaternion startRotation = targetData[0].localRotation;
                            Vector3 startScale       = targetData[0].localScale;
                            for (int i = 1; i < targetData.Count; i++)
                            {
                                isActivityConstant &= targetData[i].enabled == startEnabled;
                                isPositionConstant &= targetData[i].localPosition == startPosition;
                                isRotationConstant &= targetData[i].localRotation == startRotation;
                                isScaleConstant    &= targetData[i].localScale == startScale;
                            }
                        }

                        for (int i = 0; i < TransformData.CURVE_COUNT; i++)
                        {
                            string propertyName = TransformData.GetName(i);
                            Type type           = typeof(Transform);

                            AnimationCurve curve = new AnimationCurve();
                            var dataType         = TransformData.GetDataType(i);

                            switch (dataType)
                            {
                            case TransformDataType.Position:
                                if (isPositionConstant)
                                {
                                    continue;
                                }
                                break;

                            case TransformDataType.Rotation:
                                if (isRotationConstant)
                                {
                                    continue;
                                }
                                break;

                            case TransformDataType.Scale:
                                if (isScaleConstant)
                                {
                                    continue;
                                }
                                break;

                            case TransformDataType.Activity:
                                if (isActivityConstant)
                                {
                                    continue;
                                }
                                type = typeof(GameObject);
                                break;
                            }

                            for (int j = 0; j < targetData.Count; j++)
                            {
                                int index = curve.AddKey(targetData[j].time, targetData[j].GetFloat(i));
                                if (dataType == TransformDataType.Activity)
                                {
                                    AnimationUtility.SetKeyLeftTangentMode(curve, index, AnimationUtility.TangentMode.Constant);
                                    AnimationUtility.SetKeyRightTangentMode(curve, index, AnimationUtility.TangentMode.Constant);
                                }
                            }

                            var binding = EditorCurveBinding.FloatCurve(path, type, propertyName);

                            if (_curves.ContainsKey(binding))
                            {
                                Debug.LogError("Duplicate object was created??");
                                Debug.LogError("Named " + targetTransform.name + " : " + binding.path + " : " + binding.propertyName);
                            }
                            else
                            {
                                _curves.Add(binding, curve);
                            }
                        }
                    }
                });

                progress.Begin(_curves.Count, "", "Compressing Data: ", () => {
                    foreach (var pair in _curves)
                    {
                        EditorCurveBinding binding = pair.Key;
                        AnimationCurve curve       = pair.Value;

                        progress.Step(binding.propertyName);

                        GameObject animationGameObject;
                        {
                            var animatedObj = AnimationUtility.GetAnimatedObject(gameObject, binding);
                            if (animatedObj is GameObject)
                            {
                                animationGameObject = animatedObj as GameObject;
                            }
                            else
                            {
                                animationGameObject = (animatedObj as Component).gameObject;
                            }
                        }

                        //But if the curve is constant, just get rid of it!
                        if (curve.IsConstant())
                        {
                            //Check to make sure there are no other matching curves that are
                            //non constant.  If X and Y are constant but Z is not, we need to
                            //keep them all :(
                            if (_curves.Query().Where(p => p.Key.path == binding.path &&
                                                      p.Key.type == binding.type &&
                                                      p.Key.propertyName.TrimEnd(2) == binding.propertyName.TrimEnd(2)).
                                All(k => k.Value.IsConstant()))
                            {
                                continue;
                            }
                        }

                        //First do a lossless compression
                        curve = AnimationCurveUtil.Compress(curve, Mathf.Epsilon);

                        Transform targetTransform = null;
                        var targetObj             = AnimationUtility.GetAnimatedObject(gameObject, binding);
                        if (targetObj is GameObject)
                        {
                            targetTransform = (targetObj as GameObject).transform;
                        }
                        else if (targetObj is Component)
                        {
                            targetTransform = (targetObj as Component).transform;
                        }
                        else
                        {
                            Debug.LogError("Target obj was of type " + targetObj.GetType().Name);
                        }

                        var dataRecorder = targetTransform.GetComponent <RecordedData>();
                        if (dataRecorder == null)
                        {
                            dataRecorder = targetTransform.gameObject.AddComponent <RecordedData>();
                        }

                        dataRecorder.data.Add(new RecordedData.EditorCurveBindingData()
                        {
                            path         = binding.path,
                            propertyName = binding.propertyName,
                            typeName     = binding.type.Name,
                            curve        = curve
                        });
                    }
                });

                progress.Step("Finalizing Prefab...");

                var postProcessComponent = gameObject.AddComponent <HierarchyPostProcess>();

                GameObject myGameObject = gameObject;

                DestroyImmediate(this);

                string targetFolderPath = targetFolder.Path;
                if (targetFolderPath == null)
                {
                    if (myGameObject.scene.IsValid() && !string.IsNullOrEmpty(myGameObject.scene.path))
                    {
                        string sceneFolder = Path.GetDirectoryName(myGameObject.scene.path);
                        targetFolderPath   = Path.Combine(sceneFolder, "Recordings");
                    }
                    else
                    {
                        targetFolderPath = Path.Combine("Assets", "Recordings");
                    }
                }

                int folderSuffix = 1;
                string finalSubFolder;
                do
                {
                    finalSubFolder = Path.Combine(targetFolderPath, recordingName + " " + folderSuffix.ToString().PadLeft(2, '0'));
                    folderSuffix++;
                } while (Directory.Exists(finalSubFolder));

                Directory.CreateDirectory(finalSubFolder);
                AssetDatabase.Refresh();

                postProcessComponent.recordingName    = recordingName;
                postProcessComponent.assetFolder.Path = finalSubFolder;
                postProcessComponent.leapData         = _leapData;

                string prefabPath = Path.Combine(finalSubFolder, recordingName + " Raw.prefab");
                PrefabUtility.CreatePrefab(prefabPath.Replace('\\', '/'), myGameObject);
                AssetDatabase.Refresh();

                EditorApplication.isPlaying = false;
            });
        }