예제 #1
0
    public void AddNode(Transform node)
    {
        Vector3Curve positionCurve;

        if(nodes.Count > 0)
        {
            int lastIndex = nodes.Count - 1;

            positionCurve = new Vector3Curve(nodes[lastIndex], node, curveFactor);

            for(float i = 0.1f; i < 1.1f; i += 0.1f)
            {
                Transform point = new GameObject("").transform;
                point.position = positionCurve.Evaluate(i);
                point.rotation = positionCurve.EvaluateRotation(i);
                point.parent = points;
                nodes.Add(point);
            }
        }
        else
        {
            Transform point = new GameObject("").transform;
            point.position = node.position;
            point.rotation = node.rotation;
            point.parent = points;
            nodes.Add(point);
        }
        Destroy(node.gameObject);
    }
예제 #2
0
    /// <summary>
    /// 整个的UI对话框的出现,显示,消失,包含画线,消除线
    /// </summary>
    /// <param name="lineRenderer"></param>
    /// <param name="origin"></param>
    /// <param name="middlePoint"></param>
    /// <param name="end"></param>
    /// <returns></returns>
    private IEnumerator RenderingLine(LineRenderer lineRenderer, Vector3 origin, Vector3 middlePoint, Vector3 end)
    {
        Vector3Curve v3Curve = new Vector3Curve(new Vector3KeyFrame(0.0f, origin), new Vector3KeyFrame(0.4f, middlePoint), new Vector3KeyFrame(1.0f, end));

        yield return(StartCoroutine(RenderProgressLine(lineRenderer, v3Curve, 0.4f, this.speedOut, this.durationOut)));

        // Display UI
        var animator = CreateCanvas();

        this.targetTime = Time.time + this.holdTime;
        while (Time.time < targetTime)
        {
            yield return(new WaitForSeconds(0.5f));
        }

        // Close the menu and line
        animator.SetBool("Close", true);
        yield return(new WaitUntil(() => animator.GetCurrentAnimatorStateInfo(0).IsName("Closed")));

        animator.gameObject.SetActive(false);

        // Draw back the line
        yield return(StartCoroutine(RenderProgressLine(lineRenderer, v3Curve, 0.4f, this.speedIn, this.durationIn)));

        Destroy(this.gameObject);
    }
예제 #3
0
    private IEnumerator RenderProgressLine(LineRenderer lineRenderer, Vector3Curve v3Curve, float middleTime, AnimationCurve speed, float duration)
    {
        float interval = duration / 20.0f;

        for (float i = 0; i < 1.0f; i += 0.05f)
        {
            lineRenderer.SetPositions(positions);
            float mappedTime = speed.Evaluate(i);

            positions[2] = v3Curve.Evaluate(mappedTime);
            if (mappedTime < middleTime)
            {
                positions[1] = positions[2];
            }
            yield return(new WaitForSeconds(duration / 20));
        }
        float mappedTime1 = speed.Evaluate(1.0f);

        positions[2] = v3Curve.Evaluate(mappedTime1);
        if (mappedTime1 < middleTime)
        {
            positions[1] = positions[2];
        }
        lineRenderer.SetPositions(positions);
    }
예제 #4
0
        partial void OnClicked(int component)
        {
            Vector3Distribution distribution = Value;

            if (DistributionType == PropertyDistributionType.Curve)
            {
                AnimationCurve[] curves = AnimationUtility.SplitCurve3D(distribution.GetMinCurve());
                if (component < curves.Length)
                {
                    CurveEditorWindow.Show(curves[component], (success, curve) =>
                    {
                        if (!success)
                        {
                            return;
                        }

                        curves[component] = curve;

                        Vector3Curve compoundCurve = AnimationUtility.CombineCurve3D(curves);
                        Value = new Vector3Distribution(compoundCurve);
                        OnChanged?.Invoke();
                        OnConfirmed?.Invoke();
                    });
                }
            }
            else if (DistributionType == PropertyDistributionType.RandomCurveRange)
            {
                AnimationCurve[] minCurves = AnimationUtility.SplitCurve3D(distribution.GetMinCurve());
                AnimationCurve[] maxCurves = AnimationUtility.SplitCurve3D(distribution.GetMaxCurve());

                if (component < minCurves.Length && component < maxCurves.Length)
                {
                    CurveEditorWindow.Show(minCurves[component], maxCurves[component],
                                           (success, minCurve, maxCurve) =>
                    {
                        if (!success)
                        {
                            return;
                        }

                        minCurves[component] = minCurve;
                        maxCurves[component] = maxCurve;

                        Vector3Curve minCompoundCurves = AnimationUtility.CombineCurve3D(minCurves);
                        Vector3Curve maxCompoundCurves = AnimationUtility.CombineCurve3D(maxCurves);

                        Value = new Vector3Distribution(minCompoundCurves, maxCompoundCurves);
                        OnChanged?.Invoke();
                        OnConfirmed?.Invoke();
                    });
                }
            }
        }
        private void SetVector3CurveData(Vector3Curve vec3urve, AnimationCurve curve, string propertyName)
        {
            int cnt = curve.keys.Length;

            Keyframe[] srcKeys = curve.keys;

            if (vec3urve.keys == null)
            {
                vec3urve.keys = new Vector3KeyFrame[cnt];
            }

            vec3urve.preWrapMode  = curve.preWrapMode;
            vec3urve.postWrapMode = curve.postWrapMode;
            //vec3urve.rotationOrder  = RotationOrder.Default;

            if (propertyName.EndsWith(".x"))
            {
                for (int i = 0; i < cnt; i++)
                {
                    Keyframe keyFrame = srcKeys[i];
                    vec3urve.keys[i].time       = keyFrame.time;
                    vec3urve.keys[i].value.x    = keyFrame.value;
                    vec3urve.keys[i].inSlope.x  = keyFrame.inTangent;
                    vec3urve.keys[i].outSlope.x = keyFrame.outTangent;
                }
            }
            else if (propertyName.EndsWith(".y"))
            {
                for (int i = 0; i < cnt; i++)
                {
                    Keyframe keyFrame = srcKeys[i];
                    vec3urve.keys[i].time       = keyFrame.time;
                    vec3urve.keys[i].value.y    = keyFrame.value;
                    vec3urve.keys[i].inSlope.y  = keyFrame.inTangent;
                    vec3urve.keys[i].outSlope.y = keyFrame.outTangent;
                }
            }
            else if (propertyName.EndsWith(".z"))
            {
                for (int i = 0; i < cnt; i++)
                {
                    Keyframe keyFrame = srcKeys[i];
                    vec3urve.keys[i].time       = keyFrame.time;
                    vec3urve.keys[i].value.z    = keyFrame.value;
                    vec3urve.keys[i].inSlope.z  = keyFrame.inTangent;
                    vec3urve.keys[i].outSlope.z = keyFrame.outTangent;
                }
            }
        }
        private void ProcessClip()
        {
            EditorCurveBinding[] bindings = AnimationUtility.GetCurveBindings(_clip);
            foreach (var binding in bindings)
            {
                AnimationCurve curve = AnimationUtility.GetEditorCurve(_clip, binding);
                ProcessCurve(curve, binding);
            }

            // 某些 Curve 只有两个关键帧并且值是相同的,去掉此类 Curve 的第二个关键帧以节省空间
            foreach (ClipCurveData data in _curveDic.Values)
            {
                RotationCurve rotCurve = data.rotationCurve;
                if (rotCurve.keys.Length == 2 && rotCurve.keys[0] == rotCurve.keys[1])
                {
                    rotCurve.keys = new RotationKeyFrame[1] {
                        rotCurve.keys[0]
                    }
                }
                ;

                Vector3Curve posCurve = data.positionCurve;
                if (posCurve.keys.Length == 2 && posCurve.keys[0] == posCurve.keys[1])
                {
                    posCurve.keys = new Vector3KeyFrame[1] {
                        posCurve.keys[0]
                    }
                }
                ;

                Vector3Curve scaleCurve = data.scaleCurve;
                if (scaleCurve.keys.Length == 2 && scaleCurve.keys[0] == scaleCurve.keys[1])
                {
                    if (scaleCurve.keys[0].value == Vector3.one) // 这种情况就不要记录曲线了
                    {
                        data.scaleCurve = null;
                    }
                    else
                    {
                        scaleCurve.keys = new Vector3KeyFrame[1] {
                            scaleCurve.keys[0]
                        }
                    };
                }
            }
        }
예제 #7
0
 private static extern AnimationCurve[] Internal_splitCurve3D(Vector3Curve compoundCurve);
예제 #8
0
 /// <summary>Registers a new curve used for animating scale.</summary>
 /// <param name="name">
 /// Unique name of the curve. This name will be used mapping the curve to the relevant bone in a skeleton, if any.
 /// </param>
 /// <param name="curve">Curve to add to the clip.</param>
 public void AddScaleCurve(string name, Vector3Curve curve)
 {
     Internal_addScaleCurve(mCachedPtr, name, curve);
 }
예제 #9
0
 private static extern void Internal_TDistribution2(Vector3Distribution managedInstance, Vector3Curve curve);
예제 #10
0
 /// <summary>Creates a new distribution that evaluates a curve.</summary>
 public Vector3Distribution(Vector3Curve curve)
 {
     Internal_TDistribution2(this, curve);
 }
예제 #11
0
 private void Awake()
 {
     this.curve = new Vector3Curve(new Vector3KeyFrame(0, Vector3.zero), new Vector3KeyFrame(0.7f, new Vector3(0.2f, 0.9f, 0.5f)), new Vector3KeyFrame(1.0f, Vector3.one));
 }
예제 #12
0
        private void AddTransformCurve(float time, TransformType transType, IReadOnlyList <float> curveValues,
                                       IReadOnlyList <float> inSlopeValues, IReadOnlyList <float> outSlopeValues, int offset, string path)
        {
            switch (transType)
            {
            case TransformType.Translation:
            {
                Vector3Curve curve = new Vector3Curve(path);
                if (!m_translations.TryGetValue(curve, out List <KeyframeTpl <Vector3f> > transCurve))
                {
                    transCurve = new List <KeyframeTpl <Vector3f> >();
                    m_translations.Add(curve, transCurve);
                }

                float x = curveValues[offset + 0];
                float y = curveValues[offset + 1];
                float z = curveValues[offset + 2];

                float inX = inSlopeValues[0];
                float inY = inSlopeValues[1];
                float inZ = inSlopeValues[2];

                float outX = outSlopeValues[0];
                float outY = outSlopeValues[1];
                float outZ = outSlopeValues[2];

                Vector3f value    = new Vector3f(x, y, z);
                Vector3f inSlope  = new Vector3f(inX, inY, inZ);
                Vector3f outSlope = new Vector3f(outX, outY, outZ);
                KeyframeTpl <Vector3f> transKey = new KeyframeTpl <Vector3f>(time, value, inSlope, outSlope, KeyframeTpl <Vector3f> .DefaultVector3Weight);
                transCurve.Add(transKey);
            }
            break;

            case TransformType.Rotation:
            {
                QuaternionCurve curve = new QuaternionCurve(path);
                if (!m_rotations.TryGetValue(curve, out List <KeyframeTpl <Quaternionf> > rotCurve))
                {
                    rotCurve = new List <KeyframeTpl <Quaternionf> >();
                    m_rotations.Add(curve, rotCurve);
                }

                float x = curveValues[offset + 0];
                float y = curveValues[offset + 1];
                float z = curveValues[offset + 2];
                float w = curveValues[offset + 3];

                float inX = inSlopeValues[0];
                float inY = inSlopeValues[1];
                float inZ = inSlopeValues[2];
                float inW = inSlopeValues[3];

                float outX = outSlopeValues[0];
                float outY = outSlopeValues[1];
                float outZ = outSlopeValues[2];
                float outW = outSlopeValues[3];

                Quaternionf value                = new Quaternionf(x, y, z, w);
                Quaternionf inSlope              = new Quaternionf(inX, inY, inZ, inW);
                Quaternionf outSlope             = new Quaternionf(outX, outY, outZ, outW);
                KeyframeTpl <Quaternionf> rotKey = new KeyframeTpl <Quaternionf>(time, value, inSlope, outSlope, KeyframeTpl <Quaternionf> .DefaultQuaternionWeight);
                rotCurve.Add(rotKey);
            }
            break;

            case TransformType.Scaling:
            {
                Vector3Curve curve = new Vector3Curve(path);
                if (!m_scales.TryGetValue(curve, out List <KeyframeTpl <Vector3f> > scaleCurve))
                {
                    scaleCurve = new List <KeyframeTpl <Vector3f> >();
                    m_scales.Add(curve, scaleCurve);
                }

                float x = curveValues[offset + 0];
                float y = curveValues[offset + 1];
                float z = curveValues[offset + 2];

                float inX = inSlopeValues[0];
                float inY = inSlopeValues[1];
                float inZ = inSlopeValues[2];

                float outX = outSlopeValues[0];
                float outY = outSlopeValues[1];
                float outZ = outSlopeValues[2];

                Vector3f value    = new Vector3f(x, y, z);
                Vector3f inSlope  = new Vector3f(inX, inY, inZ);
                Vector3f outSlope = new Vector3f(outX, outY, outZ);
                KeyframeTpl <Vector3f> scaleKey = new KeyframeTpl <Vector3f>(time, value, inSlope, outSlope, KeyframeTpl <Vector3f> .DefaultVector3Weight);
                scaleCurve.Add(scaleKey);
            }
            break;

            case TransformType.EulerRotation:
            {
                Vector3Curve curve = new Vector3Curve(path);
                if (!m_eulers.TryGetValue(curve, out List <KeyframeTpl <Vector3f> > eulerCurve))
                {
                    eulerCurve = new List <KeyframeTpl <Vector3f> >();
                    m_eulers.Add(curve, eulerCurve);
                }

                float x = curveValues[offset + 0];
                float y = curveValues[offset + 1];
                float z = curveValues[offset + 2];

                float inX = inSlopeValues[0];
                float inY = inSlopeValues[1];
                float inZ = inSlopeValues[2];

                float outX = outSlopeValues[0];
                float outY = outSlopeValues[1];
                float outZ = outSlopeValues[2];

                Vector3f value    = new Vector3f(x, y, z);
                Vector3f inSlope  = new Vector3f(inX, inY, inZ);
                Vector3f outSlope = new Vector3f(outX, outY, outZ);
                KeyframeTpl <Vector3f> eulerKey = new KeyframeTpl <Vector3f>(time, value, inSlope, outSlope, KeyframeTpl <Vector3f> .DefaultVector3Weight);
                eulerCurve.Add(eulerKey);
            }
            break;

            default:
                throw new NotImplementedException(transType.ToString());
            }
        }
        /// <summary>
        /// Loads curve and event information from the provided clip, and creates a new instance of this object containing
        /// the required data for editing the source clip in the animation editor.
        /// </summary>
        /// <param name="clip">Clip to load.</param>
        /// <returns>Editor specific editable information about an animation clip.</returns>
        public static EditorAnimClipInfo Create(AnimationClip clip)
        {
            EditorAnimClipInfo clipInfo = new EditorAnimClipInfo();

            clipInfo.clip       = clip;
            clipInfo.isImported = IsClipImported(clip);
            clipInfo.sampleRate = (int)clip.SampleRate;

            AnimationCurves    clipCurves     = clip.Curves;
            EditorAnimClipData editorClipData = null;

            EditorAnimClipData lGetAnimClipData(ResourceMeta meta)
            {
                object             editorData = meta.EditorData;
                EditorAnimClipData output     = editorData as EditorAnimClipData;

                if (output == null)
                {
                    // Old editor data stores tangents only
                    if (editorData is EditorAnimClipTangents tangents)
                    {
                        output          = new EditorAnimClipData();
                        output.tangents = tangents;
                    }
                }

                return(output);
            }

            string resourcePath = ProjectLibrary.GetPath(clip);

            if (!string.IsNullOrEmpty(resourcePath))
            {
                LibraryEntry entry    = ProjectLibrary.GetEntry(resourcePath);
                string       clipName = PathEx.GetTail(resourcePath);

                if (entry != null && entry.Type == LibraryEntryType.File)
                {
                    FileEntry      fileEntry = (FileEntry)entry;
                    ResourceMeta[] metas     = fileEntry.ResourceMetas;

                    if (clipInfo.isImported)
                    {
                        for (int i = 0; i < metas.Length; i++)
                        {
                            if (clipName == metas[i].SubresourceName)
                            {
                                editorClipData = lGetAnimClipData(metas[i]);
                                break;
                            }
                        }
                    }
                    else
                    {
                        if (metas.Length > 0)
                        {
                            editorClipData = lGetAnimClipData(metas[0]);
                        }
                    }
                }
            }

            if (editorClipData == null)
            {
                editorClipData          = new EditorAnimClipData();
                editorClipData.tangents = new EditorAnimClipTangents();
            }

            int globalCurveIdx = 0;

            void lLoadVector3Curve(NamedVector3Curve[] curves, EditorVector3CurveTangents[] tangents, string subPath)
            {
                foreach (var curveEntry in curves)
                {
                    TangentMode[] tangentsX = null;
                    TangentMode[] tangentsY = null;
                    TangentMode[] tangentsZ = null;

                    if (tangents != null)
                    {
                        foreach (var tangentEntry in tangents)
                        {
                            if (tangentEntry.name == curveEntry.name)
                            {
                                tangentsX = tangentEntry.tangentsX;
                                tangentsY = tangentEntry.tangentsY;
                                tangentsZ = tangentEntry.tangentsZ;
                                break;
                            }
                        }
                    }

                    // Convert compound curve to three per-component curves
                    AnimationCurve[] componentCurves = AnimationUtility.SplitCurve3D(curveEntry.curve);

                    FieldAnimCurves fieldCurves = new FieldAnimCurves();
                    fieldCurves.type            = SerializableProperty.FieldType.Vector3;
                    fieldCurves.curveInfos      = new EdCurveDrawInfo[3];
                    fieldCurves.isPropertyCurve = !clipInfo.isImported;

                    fieldCurves.curveInfos[0]       = new EdCurveDrawInfo();
                    fieldCurves.curveInfos[0].curve = new EdAnimationCurve(componentCurves[0], tangentsX);
                    fieldCurves.curveInfos[0].color = GetUniqueColor(globalCurveIdx++);

                    fieldCurves.curveInfos[1]       = new EdCurveDrawInfo();
                    fieldCurves.curveInfos[1].curve = new EdAnimationCurve(componentCurves[1], tangentsY);
                    fieldCurves.curveInfos[1].color = GetUniqueColor(globalCurveIdx++);

                    fieldCurves.curveInfos[2]       = new EdCurveDrawInfo();
                    fieldCurves.curveInfos[2].curve = new EdAnimationCurve(componentCurves[2], tangentsZ);
                    fieldCurves.curveInfos[2].color = GetUniqueColor(globalCurveIdx++);

                    string curvePath = curveEntry.name.TrimEnd('/') + subPath;
                    clipInfo.curves[curvePath] = fieldCurves;
                }
            };

            NamedQuaternionCurve[] rotationCurves      = clipCurves.Rotation;
            NamedVector3Curve[]    eulerRotationCurves = new NamedVector3Curve[rotationCurves.Length];
            if (editorClipData.eulerCurves == null || editorClipData.eulerCurves.Length != rotationCurves.Length)
            {
                // Convert rotation from quaternion to euler if we don't have original euler animation data stored.
                for (int i = 0; i < rotationCurves.Length; i++)
                {
                    NamedQuaternionCurve quatCurve  = rotationCurves[i];
                    Vector3Curve         eulerCurve = AnimationUtility.QuaternionToEulerCurve(quatCurve.curve);

                    eulerRotationCurves[i] = new NamedVector3Curve(quatCurve.name, quatCurve.flags, eulerCurve);
                }
            }
            else
            {
                for (int i = 0; i < editorClipData.eulerCurves.Length; i++)
                {
                    EditorNamedVector3Curve edCurve = editorClipData.eulerCurves[i];

                    eulerRotationCurves[i] = new NamedVector3Curve(
                        edCurve.name, edCurve.flags, new Vector3Curve(edCurve.keyFrames));
                }
            }

            lLoadVector3Curve(clipCurves.Position, editorClipData.tangents.positionCurves, "/Position");
            lLoadVector3Curve(eulerRotationCurves, editorClipData.tangents.rotationCurves, "/Rotation");
            lLoadVector3Curve(clipCurves.Scale, editorClipData.tangents.scaleCurves, "/Scale");

            // Find which individual float curves belong to the same field
            Dictionary <string, Tuple <int, int, bool>[]> floatCurveMapping = new Dictionary <string, Tuple <int, int, bool>[]>();

            {
                int curveIdx = 0;
                foreach (var curveEntry in clipCurves.Generic)
                {
                    string path         = curveEntry.name;
                    string pathNoSuffix = null;

                    string pathSuffix;
                    if (path.Length >= 2)
                    {
                        pathSuffix   = path.Substring(path.Length - 2, 2);
                        pathNoSuffix = path.Substring(0, path.Length - 2);
                    }
                    else
                    {
                        pathSuffix = "";
                    }

                    int tangentIdx        = -1;
                    int currentTangentIdx = 0;
                    foreach (var tangentEntry in editorClipData.tangents.floatCurves)
                    {
                        if (tangentEntry.name == curveEntry.name)
                        {
                            tangentIdx = currentTangentIdx;
                            break;
                        }

                        currentTangentIdx++;
                    }

                    Animation.PropertySuffixInfo suffixInfo;
                    if (Animation.PropertySuffixInfos.TryGetValue(pathSuffix, out suffixInfo))
                    {
                        Tuple <int, int, bool>[] curveInfo;
                        if (!floatCurveMapping.TryGetValue(pathNoSuffix, out curveInfo))
                        {
                            curveInfo = new Tuple <int, int, bool> [4];
                        }

                        curveInfo[suffixInfo.elementIdx] = Tuple.Create(curveIdx, tangentIdx, suffixInfo.isVector);
                        floatCurveMapping[pathNoSuffix]  = curveInfo;
                    }
                    else
                    {
                        Tuple <int, int, bool>[] curveInfo = new Tuple <int, int, bool> [4];
                        curveInfo[0] = Tuple.Create(curveIdx, tangentIdx, suffixInfo.isVector);

                        floatCurveMapping[path] = curveInfo;
                    }

                    curveIdx++;
                }
            }

            foreach (var KVP in floatCurveMapping)
            {
                int numCurves = 0;
                for (int i = 0; i < 4; i++)
                {
                    if (KVP.Value[i] == null)
                    {
                        continue;
                    }

                    numCurves++;
                }

                if (numCurves == 0)
                {
                    continue; // Invalid curve
                }
                FieldAnimCurves fieldCurves = new FieldAnimCurves();

                // Deduce type (note that all single value types are assumed to be float even if their source type is int or bool)
                if (numCurves == 1)
                {
                    fieldCurves.type = SerializableProperty.FieldType.Float;
                }
                else if (numCurves == 2)
                {
                    fieldCurves.type = SerializableProperty.FieldType.Vector2;
                }
                else if (numCurves == 3)
                {
                    fieldCurves.type = SerializableProperty.FieldType.Vector3;
                }
                else // 4 curves
                {
                    bool isVector = KVP.Value[0].Item3;
                    if (isVector)
                    {
                        fieldCurves.type = SerializableProperty.FieldType.Vector4;
                    }
                    else
                    {
                        fieldCurves.type = SerializableProperty.FieldType.Color;
                    }
                }

                bool   isMorphCurve = false;
                string curvePath    = KVP.Key;

                fieldCurves.curveInfos = new EdCurveDrawInfo[numCurves];
                for (int i = 0; i < numCurves; i++)
                {
                    int curveIdx   = KVP.Value[i].Item1;
                    int tangentIdx = KVP.Value[i].Item2;

                    TangentMode[] tangents = null;
                    if (tangentIdx != -1)
                    {
                        tangents = editorClipData.tangents.floatCurves[tangentIdx].tangents;
                    }

                    fieldCurves.curveInfos[i]       = new EdCurveDrawInfo();
                    fieldCurves.curveInfos[i].curve = new EdAnimationCurve(clipCurves.Generic[curveIdx].curve, tangents);
                    fieldCurves.curveInfos[i].color = GetUniqueColor(globalCurveIdx++);

                    if (clipCurves.Generic[curveIdx].flags.HasFlag(AnimationCurveFlags.MorphFrame))
                    {
                        curvePath    = "MorphShapes/Frames/" + KVP.Key;
                        isMorphCurve = true;
                    }
                    else if (clipCurves.Generic[curveIdx].flags.HasFlag(AnimationCurveFlags.MorphWeight))
                    {
                        curvePath    = "MorphShapes/Weight/" + KVP.Key;
                        isMorphCurve = true;
                    }
                }

                fieldCurves.isPropertyCurve = !clipInfo.isImported && !isMorphCurve;

                clipInfo.curves[curvePath] = fieldCurves;
            }

            // Add events
            clipInfo.events = clip.Events;
            return(clipInfo);
        }
예제 #14
0
 private static extern void Internal_TAnimationCurve(Vector3Curve managedInstance, KeyFrameVec3[] keyframes);
예제 #15
0
 /// <summary>Constructs a new named animation curve.</summary>
 /// <param name="name">Name of the curve.</param>
 /// <param name="flags">Flags that describe the animation curve.</param>
 /// <param name="curve">Curve containing the animation data.</param>
 public NamedVector3Curve(string name, AnimationCurveFlags flags, Vector3Curve curve)
 {
     this.name  = name;
     this.flags = (AnimationCurveFlags)0;
     this.curve = curve;
 }
예제 #16
0
        public void ExportGenericData(IExportContainer container, YAMLMappingNode node, IReadOnlyDictionary <uint, string> tos)
        {
            StreamedClip streamedClip = MuscleClip.Clip.StreamedClip;
            DenseClip    denseClip    = MuscleClip.Clip.DenseClip;
            ConstantClip constantClip = MuscleClip.Clip.ConstantClip;

            IReadOnlyList <StreamedFrame>      streamedFrames = streamedClip.GenerateFrames(container);
            Dictionary <uint, Vector3Curve>    translations   = new Dictionary <uint, Vector3Curve>();
            Dictionary <uint, QuaternionCurve> rotations      = new Dictionary <uint, QuaternionCurve>();
            Dictionary <uint, Vector3Curve>    scales         = new Dictionary <uint, Vector3Curve>();
            Dictionary <uint, Vector3Curve>    eulers         = new Dictionary <uint, Vector3Curve>();
            Dictionary <uint, FloatCurve>      floats         = new Dictionary <uint, FloatCurve>();

            int frameCount = Math.Max(denseClip.FrameCount - 1, streamedFrames.Count - 2);

            float[] frameCurvesValue = new float[streamedClip.CurveCount];
            for (int frame = 0, streamFrame = 1; frame < frameCount; frame++, streamFrame++)
            {
                bool          isAdd = true;
                float         time;
                StreamedFrame streamedFrame = new StreamedFrame();
                if (streamFrame < streamedFrames.Count)
                {
                    streamedFrame = streamedFrames[streamFrame];
                    time          = streamedFrame.Time;
                }
                else
                {
                    time = (float)frame / SampleRate;
                }

                bool isStreamFrame = streamFrame < (streamedFrames.Count - 1);
                bool isDenseFrame  = frame < (denseClip.FrameCount - 1);

                // number of stream curves which has key in current frame
                int streamFrameCurveCount = isStreamFrame ? streamedFrame.Curves.Count : 0;
                int denseFrameCurveCount  = (int)denseClip.CurveCount;
                // total amount of curves which has key in current frame
                int frameCurveCount = streamFrameCurveCount + denseFrameCurveCount + constantClip.Constants.Count;
                int streamOffset    = (int)streamedClip.CurveCount - streamFrameCurveCount;
                for (int curve = 0; curve < frameCurveCount;)
                {
                    int curveIndex;
                    IReadOnlyList <float> curvesValue;
                    int offset;

                    if (isStreamFrame && curve < streamedFrame.Curves.Count)
                    {
#warning TODO: read TCB and convert to in/out slope
                        for (int key = curve; key < Math.Min(curve + 5, streamedFrame.Curves.Count); key++)
                        {
                            frameCurvesValue[key] = streamedFrame.Curves[key].Value;
                        }
                        curveIndex  = streamedFrame.Curves[curve].Index;
                        curvesValue = frameCurvesValue;
                        offset      = 0;
                    }
                    else if (isDenseFrame && curve < streamFrameCurveCount + denseFrameCurveCount)
                    {
                        curveIndex  = curve + streamOffset;
                        curvesValue = denseClip.SampleArray;
                        offset      = streamFrameCurveCount - frame * denseFrameCurveCount;
                    }
                    else if (!isDenseFrame && curve < streamFrameCurveCount + denseFrameCurveCount)
                    {
                        curve += denseFrameCurveCount;

                        curveIndex  = curve + streamOffset;
                        curvesValue = constantClip.Constants;
                        offset      = streamFrameCurveCount + denseFrameCurveCount;
                        isAdd       = frame == 0 || frame == frameCount - 1;
                    }
                    else
                    {
                        curveIndex  = curve + streamOffset;
                        curvesValue = constantClip.Constants;
                        offset      = streamFrameCurveCount + denseFrameCurveCount;
                        isAdd       = frame == 0 || frame == frameCount - 1;
                    }

                    GenericBinding binding  = ClipBindingConstant.FindBinding(curveIndex);
                    uint           pathHash = binding.Path;

                    if (pathHash == 0)
                    {
                        curve++;
                        continue;
                    }
                    if (!tos.TryGetValue(pathHash, out string path))
                    {
                        path = "dummy" + pathHash;
                        //Logger.Log(LogType.Debug, LogCategory.Export, $"Can't find path '{binding.Path}' in TOS for {ToLogString()}");
                    }

                    switch (binding.BindingType)
                    {
                    case BindingType.Translation:
                        // HACK: TEMP:
                        if (curve + 3 > curvesValue.Count)
                        {
                            curve += 3;
                            break;
                        }

                        float x = curvesValue[curve++ - offset];
                        float y = curvesValue[curve++ - offset];
                        float z = curvesValue[curve++ - offset];
                        float w = 0;
                        if (isAdd)
                        {
                            Vector3f trans = new Vector3f(x, y, z);
                            if (!translations.TryGetValue(pathHash, out Vector3Curve transCurve))
                            {
                                transCurve             = new Vector3Curve(path);
                                translations[pathHash] = transCurve;
                            }

                            Vector3f defWeight = new Vector3f(1.0f / 3.0f);
                            KeyframeTpl <Vector3f> transKey = new KeyframeTpl <Vector3f>(time, trans, defWeight);
                            transCurve.Curve.Curve.Add(transKey);
                        }
                        break;

                    case BindingType.Rotation:
                        // HACK: TEMP:
                        if (curve + 4 > curvesValue.Count)
                        {
                            curve += 4;
                            break;
                        }

                        x = curvesValue[curve++ - offset];
                        y = curvesValue[curve++ - offset];
                        z = curvesValue[curve++ - offset];
                        w = curvesValue[curve++ - offset];
                        if (isAdd)
                        {
                            Quaternionf rot = new Quaternionf(x, y, z, w);
                            if (!rotations.TryGetValue(pathHash, out QuaternionCurve rotCurve))
                            {
                                rotCurve            = new QuaternionCurve(path);
                                rotations[pathHash] = rotCurve;
                            }

                            Quaternionf defWeight            = new Quaternionf(1.0f / 3.0f);
                            KeyframeTpl <Quaternionf> rotKey = new KeyframeTpl <Quaternionf>(time, rot, defWeight);
                            rotCurve.Curve.Curve.Add(rotKey);
                        }
                        break;

                    case BindingType.Scaling:
                        // HACK: TEMP:
                        if (curve + 3 > curvesValue.Count)
                        {
                            curve += 3;
                            break;
                        }

                        x = curvesValue[curve++ - offset];
                        y = curvesValue[curve++ - offset];
                        z = curvesValue[curve++ - offset];
                        if (isAdd)
                        {
                            Vector3f scale = new Vector3f(x, y, z);
                            if (!scales.TryGetValue(pathHash, out Vector3Curve scaleCurve))
                            {
                                scaleCurve       = new Vector3Curve(path);
                                scales[pathHash] = scaleCurve;
                            }

                            Vector3f defWeight = new Vector3f(1.0f / 3.0f);
                            KeyframeTpl <Vector3f> scaleKey = new KeyframeTpl <Vector3f>(time, scale, defWeight);
                            scaleCurve.Curve.Curve.Add(scaleKey);
                        }
                        break;

                    case BindingType.EulerRotation:
                        // HACK: TEMP:
                        if (curve + 3 > curvesValue.Count)
                        {
                            curve += 3;
                            break;
                        }

                        x = curvesValue[curve++ - offset];
                        y = curvesValue[curve++ - offset];
                        z = curvesValue[curve++ - offset];
                        if (isAdd)
                        {
                            Vector3f euler = new Vector3f(x, y, z);
                            if (!eulers.TryGetValue(pathHash, out Vector3Curve eulerCurve))
                            {
                                eulerCurve       = new Vector3Curve(path);
                                eulers[pathHash] = eulerCurve;
                            }

                            Vector3f defWeight = new Vector3f(1.0f / 3.0f);
                            KeyframeTpl <Vector3f> eulerKey = new KeyframeTpl <Vector3f>(time, euler, defWeight);
                            eulerCurve.Curve.Curve.Add(eulerKey);
                        }
                        break;

                    case BindingType.Floats:
                        float value = curvesValue[curve++ - offset];
                        if (isAdd)
                        {
                            Float @float = new Float(value);
                            if (!floats.TryGetValue(pathHash, out FloatCurve floatCurve))
                            {
                                floatCurve       = new FloatCurve(path);
                                floats[pathHash] = floatCurve;
                            }

                            Float defWeight = new Float(1.0f / 3.0f);
                            KeyframeTpl <Float> floatKey = new KeyframeTpl <Float>(time, @float, defWeight);
                            floatCurve.Curve.Curve.Add(floatKey);
                        }
                        break;

                    default:
#warning TODO: ???
                        curve++;
                        //throw new NotImplementedException(binding.BindingType.ToString());
                        break;
                    }
                }
            }

            node.Add("m_RotationCurves", rotations.Values.ExportYAML(container));
            node.Add("m_CompressedRotationCurves", YAMLSequenceNode.Empty);
            node.Add("m_EulerCurves", eulers.Values.ExportYAML(container));
            node.Add("m_PositionCurves", translations.Values.ExportYAML(container));
            node.Add("m_ScaleCurves", scales.Values.ExportYAML(container));
            node.Add("m_FloatCurves", floats.Values.ExportYAML(container));
        }
예제 #17
0
            public MemberAnimationData(EndianBinaryReader er)
            {
                Flags         = er.ReadUInt32();
                PathOffset    = (UInt32)er.BaseStream.Position + er.ReadUInt32();
                PrimitiveType = (AnimationType)er.ReadUInt32();

                switch (PrimitiveType)
                {
                case AnimationType.Vector2Animation:
                    ConstValues = new object[2];
                    Curves      = new AnimationCurve[2];
                    if ((Flags & 1) != 0)
                    {
                        ConstValues[0] = er.ReadSingle();                                              //constant
                    }
                    else if ((Flags & 4) != 0)
                    {
                        er.ReadUInt32();                                                   //nothing = empty reference
                    }
                    else
                    {
                        long offs    = er.BaseStream.Position + er.ReadUInt32();
                        long curpos_ = er.BaseStream.Position;
                        er.BaseStream.Position = offs;
                        Curves[0] = new FloatAnimationCurve(er);
                        er.BaseStream.Position = curpos_;
                    }

                    if ((Flags & 2) != 0)
                    {
                        ConstValues[1] = er.ReadSingle();                                              //constant
                    }
                    else if ((Flags & 8) != 0)
                    {
                        er.ReadUInt32();                                                   //nothing = empty reference
                    }
                    else
                    {
                        long offs    = er.BaseStream.Position + er.ReadUInt32();
                        long curpos_ = er.BaseStream.Position;
                        er.BaseStream.Position = offs;
                        Curves[1] = new FloatAnimationCurve(er);
                        er.BaseStream.Position = curpos_;
                    }
                    break;

                case AnimationType.BakedTransformAnimation:
                    Curves = new AnimationCurve[3];
                    if ((Flags & 0x10) != 0)
                    {
                        er.ReadUInt32();                                                 //nothing = empty reference
                    }
                    else
                    {
                        //Matrix33curve reference
                        long offs    = er.BaseStream.Position + er.ReadUInt32();
                        long curpos_ = er.BaseStream.Position;
                        er.BaseStream.Position = offs;
                        Curves[0] = new Matrix33Curve(er);
                        er.BaseStream.Position = curpos_;
                    }
                    if ((Flags & 8) != 0)
                    {
                        er.ReadUInt32();                                              //nothing = empty reference
                    }
                    else
                    {
                        //Vector3curve reference (translation)
                        long offs    = er.BaseStream.Position + er.ReadUInt32();
                        long curpos_ = er.BaseStream.Position;
                        er.BaseStream.Position = offs;
                        Curves[1] = new Vector3Curve(er);
                        er.BaseStream.Position = curpos_;
                    }
                    if ((Flags & 0x20) != 0)
                    {
                        er.ReadUInt32();                                                 //nothing = empty reference
                    }
                    else
                    {
                        //Vector3curve reference (scale)
                        long offs    = er.BaseStream.Position + er.ReadUInt32();
                        long curpos_ = er.BaseStream.Position;
                        er.BaseStream.Position = offs;
                        Curves[2] = new Vector3Curve(er);
                        er.BaseStream.Position = curpos_;
                    }
                    break;

                default:
                    break;
                }

                long curpos = er.BaseStream.Position;

                er.BaseStream.Position = PathOffset;
                Path = er.ReadStringNT(Encoding.ASCII);
                er.BaseStream.Position = curpos;
            }
예제 #18
0
 /// <summary>Converts a curve in euler angles (in degrees) into a curve using quaternions.</summary>
 public static QuaternionCurve EulerToQuaternionCurve(Vector3Curve eulerCurve)
 {
     return(Internal_eulerToQuaternionCurve(eulerCurve));
 }
예제 #19
0
 /// <summary>Splits a Vector3 curve into three individual curves, one for each component.</summary>
 public static AnimationCurve[] SplitCurve3D(Vector3Curve compoundCurve)
 {
     return(Internal_splitCurve3D(compoundCurve));
 }
예제 #20
0
 /// <summary>Creates a new distribution that returns a random value in a range determined by two curves.</summary>
 public Vector3Distribution(Vector3Curve minCurve, Vector3Curve maxCurve)
 {
     Internal_TDistribution3(this, minCurve, maxCurve);
 }
예제 #21
0
 private static extern QuaternionCurve Internal_eulerToQuaternionCurve(Vector3Curve eulerCurve);
예제 #22
0
 private static extern void Internal_TDistribution3(Vector3Distribution managedInstance, Vector3Curve minCurve, Vector3Curve maxCurve);
예제 #23
0
 private static extern void Internal_addScaleCurve(IntPtr thisPtr, string name, Vector3Curve curve);