Пример #1
0
 // 線形補間
 public static QuaternionKeyframe Lerp(QuaternionKeyframe from, QuaternionKeyframe to, Vector2 t)
 {
     return(new QuaternionKeyframe(
                Mathf.Lerp(from.time, to.time, t.x),
                Quaternion.Slerp(from.value, to.value, t.y)
                ));
 }
Пример #2
0
    //计算四元数的插值
    void _hermiteInterpolateQuaternion(QuaternionKeyframe frame, QuaternionKeyframe nextFrame, float t, float dur, Quaternion calcOut)
    {
        Quaternion p0 = frame.value;
        Vector4    tan0 = frame.outTangent;
        Quaternion p1 = nextFrame.value;
        Vector4    tan1 = nextFrame.inTangent;
        float      t2 = t * t;
        float      t3 = t2 * t;
        float      a = 2.0f * t3 - 3.0f * t2 + 1.0f;
        float      b = t3 - 2.0f * t2 + t;
        float      c = t3 - t2;
        float      d = -2.0f * t3 + 3.0f * t2;
        float      t0 = tan0.x, t1 = tan1.x;

        if (/*__JS__ */ !float.IsInfinity(t0) && !float.IsInfinity(t1))
        {
            calcOut.x = a * p0.x + b * t0 * dur + c * t1 * dur + d * p1.x;
        }
        else
        {
            calcOut.x = p0.x;
        }
        t0 = tan0.y; t1 = tan1.y;
        if (/*__JS__ */ !float.IsInfinity(t0) && !float.IsInfinity(t1))
        {
            calcOut.y = a * p0.y + b * t0 * dur + c * t1 * dur + d * p1.y;
        }
        else
        {
            calcOut.y = p0.y;
        }
        t0 = tan0.z; t1 = tan1.z;
        if (/*__JS__ */ !float.IsInfinity(t0) && !float.IsInfinity(t1))
        {
            calcOut.z = a * p0.z + b * t0 * dur + c * t1 * dur + d * p1.z;
        }
        else
        {
            calcOut.z = p0.z;
        }
        t0 = tan0.w; t1 = tan1.w;
        if (/*__JS__ */ !float.IsInfinity(t0) && !float.IsInfinity(t1))
        {
            calcOut.w = a * p0.w + b * t0 * dur + c * t1 * dur + d * p1.w;
        }
        else
        {
            calcOut.w = p0.w;
        }
    }
Пример #3
0
        // あるボーンに含まれるキーフレを抽出
        // これは回転のみ
        void CreateKeysForRotation(MMD.VMD.VMDFormat format, AnimationClip clip, string current_bone, string bone_path, int interpolationQuality)
        {
            try
            {
                List <MMD.VMD.VMDFormat.Motion> mlist = format.motion_list.motion[current_bone];
                int keyframeCount = GetKeyframeCount(mlist, 3, interpolationQuality);

                QuaternionKeyframe[] r_keys     = new QuaternionKeyframe[keyframeCount];
                QuaternionKeyframe   r_prev_key = null;
                int ir = 0;
                for (int i = 0; i < mlist.Count; i++)
                {
                    const float tick_time = 1.0f / 30.0f;
                    float       tick      = mlist[i].flame_no * tick_time;

                    Quaternion         rotation  = mlist[i].rotation;
                    QuaternionKeyframe r_cur_key = new QuaternionKeyframe(tick, rotation);
                    QuaternionKeyframe.AddBezierKeyframes(mlist[i].interpolation, 3, r_prev_key, r_cur_key, interpolationQuality, ref r_keys, ref ir);
                    r_prev_key = r_cur_key;
                }

                Keyframe[] rx_keys = null;
                Keyframe[] ry_keys = null;
                Keyframe[] rz_keys = null;
                ToKeyframesForRotation(r_keys, ref rx_keys, ref ry_keys, ref rz_keys);
                AnimationCurve curve_x = new AnimationCurve(rx_keys);
                AnimationCurve curve_y = new AnimationCurve(ry_keys);
                AnimationCurve curve_z = new AnimationCurve(rz_keys);
                // ここで回転オイラー角をセット(補間はクォータニオン)
#if !UNITY_4_2 //4.3以降
                AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve(bone_path, typeof(Transform), "localEulerAngles.x"), curve_x);
                AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve(bone_path, typeof(Transform), "localEulerAngles.y"), curve_y);
                AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve(bone_path, typeof(Transform), "localEulerAngles.z"), curve_z);
#else
                AnimationUtility.SetEditorCurve(clip, bone_path, typeof(Transform), "localEulerAngles.x", curve_x);
                AnimationUtility.SetEditorCurve(clip, bone_path, typeof(Transform), "localEulerAngles.y", curve_y);
                AnimationUtility.SetEditorCurve(clip, bone_path, typeof(Transform), "localEulerAngles.z", curve_z);
#endif
            }
            catch (KeyNotFoundException)
            {
                //Debug.LogError("互換性のないボーンが読み込まれました:" + bone_path);
            }
        }
Пример #4
0
 // ベジェを線形補間で近似したキーフレームを追加する
 public static void AddBezierKeyframes(byte[] interpolation, int type,
                                       QuaternionKeyframe prev_keyframe, QuaternionKeyframe cur_keyframe, int interpolationQuality,
                                       ref QuaternionKeyframe[] keyframes, ref int index)
 {
     if (prev_keyframe == null || IsLinear(interpolation, type))
     {
         keyframes[index++] = cur_keyframe;
     }
     else
     {
         Vector2 bezierHandleA = GetBezierHandle(interpolation, type, 0);
         Vector2 bezierHandleB = GetBezierHandle(interpolation, type, 1);
         int     sampleCount   = interpolationQuality;
         for (int j = 0; j < sampleCount; j++)
         {
             float   t      = (j + 1) / (float)sampleCount;
             Vector2 sample = SampleBezier(bezierHandleA, bezierHandleB, t);
             keyframes[index++] = QuaternionKeyframe.Lerp(prev_keyframe, cur_keyframe, sample);
         }
     }
 }