コード例 #1
0
        // 無駄なカーブを登録してるけどどうするか
        void FullEntryBoneAnimation(MMD.VMD.VMDFormat format, AnimationClip clip, Dictionary <string, string> dic, Dictionary <string, GameObject> obj, int interpolationQuality)
        {
            foreach (KeyValuePair <string, List <MMD.VMD.VMDFormat.Motion> > p in format.motion_list.motion)
            {
                // 互いに名前の一致する場合にRigidbodyが存在するか調べたい
                GameObject current_obj = null;
                string     bonePath    = null;
                // keyはtransformの名前, valueはパス
                if (dic.TryGetValue(p.Key, out bonePath))
                {
                    current_obj = obj[p.Key];

                    // Rigidbodyがある場合はキーフレの登録を無視する
                    var rigid = current_obj.GetComponent <Rigidbody>();
                    if (rigid != null && !rigid.isKinematic)
                    {
                        continue;
                    }
                }

                // キーフレの登録
                //CreateKeysForLocation(format, clip, p.Key, bonePath, interpolationQuality, current_obj);
                CreateKeysForRotation(format, clip, p.Key, bonePath, interpolationQuality);
            }
        }
コード例 #2
0
        // クリップをアニメーションに登録する
        private AnimationClip CreateAnimationClip_(MMD.VMD.VMDFormat format, GameObject assign_pmd, int interpolationQuality)
        {
            //スケール設定
            scale_ = 1.0f;
            if (!assign_pmd)
            {
                return(null);
            }
            MMDEngine engine = assign_pmd.GetComponent <MMDEngine>();

            if (!engine)
            {
                return(null);
            }
            scale_ = engine.scale;

            //Animation anim = assign_pmd.GetComponent<Animation>();

            // クリップの作成
            AnimationClip clip = new AnimationClip();

            clip.name = assign_pmd.name + "_" + format.name;

            Dictionary <string, string>     bone_path = new Dictionary <string, string>();
            Dictionary <string, GameObject> gameobj   = new Dictionary <string, GameObject>();

            GetGameObjects(gameobj, assign_pmd);                        // 親ボーン下のGameObjectを取得
            FullSearchBonePath(assign_pmd.transform, bone_path);
            FullEntryBoneAnimation(format, clip, bone_path, gameobj, interpolationQuality);

            CreateKeysForSkin(format, clip);                    // 表情の追加

            return(clip);
        }
コード例 #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
        // 無駄なカーブを登録してるけどどうするか
        void FullEntryBoneAnimation(MMD.VMD.VMDFormat format, AnimationClip clip, Dictionary <string, string> dic, Dictionary <string, GameObject> obj, int interpolationQuality)
        {
            foreach (KeyValuePair <string, string> p in dic)            // keyはtransformの名前, valueはパス
            {
                // 互いに名前の一致する場合にRigidbodyが存在するか調べたい
                GameObject current_obj = null;
                if (obj.ContainsKey(p.Key))
                {
                    current_obj = obj[p.Key];

                    // Rigidbodyがある場合はキーフレの登録を無視する
                    var rigid = current_obj.GetComponent <Rigidbody>();
                    if (rigid != null && !rigid.isKinematic)
                    {
                        continue;
                    }
                }

                // キーフレの登録
                CreateKeysForLocation(format, clip, p.Key, p.Value, interpolationQuality, current_obj);
                CreateKeysForRotation(format, clip, p.Key, p.Value, interpolationQuality);
            }
        }
コード例 #5
0
        void CreateKeysForSkin(MMD.VMD.VMDFormat format, AnimationClip clip)
        {
            const float tick_time = 1f / 30f;

            // 全ての表情に打たれているキーフレームを探索
            List <VMD.VMDFormat.SkinData> s;

            foreach (var skin in format.skin_list.skin)
            {
                s = skin.Value;
                Keyframe[] keyframe = new Keyframe[skin.Value.Count];

                // キーフレームの登録を行う
                for (int i = 0; i < skin.Value.Count; i++)
                {
                    keyframe[i] = new Keyframe(s[i].frame_no * tick_time, s[i].weight);
                    //線形補間する
                    if (i > 0)
                    {
                        float t = GetLinearTangentForPosition(keyframe[i - 1], keyframe[i]);
                        keyframe[i - 1].outTangent = t;
                        keyframe[i].inTangent      = t;
                    }
                }
                AddDummyKeyframe(ref keyframe);

                // Z軸移動にキーフレームを打つ
                AnimationCurve curve = new AnimationCurve(keyframe);
                for (int i = 0; i < curve.keys.Length; i++)
                {
                    AnimationUtility.SetKeyLeftTangentMode(curve, i, AnimationUtility.TangentMode.Linear);
                    AnimationUtility.SetKeyRightTangentMode(curve, i, AnimationUtility.TangentMode.Linear);
                }

                AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve("Expression/" + skin.Key, typeof(Transform), "m_LocalPosition.z"), curve);
            }
        }
コード例 #6
0
 void BurnUnityFormatForVMD(MMD.VMD.VMDFormat format)
 {
     MMD.VMD.VMDConverter conv = new MMD.VMD.VMDConverter();
     conv.CreateAnimationClip(format, this.assign_pmd, this.anim, this.create_asset);
 }
コード例 #7
0
        // 移動のみの抽出
        void CreateKeysForLocation(MMD.VMD.VMDFormat format, AnimationClip clip, string current_bone, string bone_path, int interpolationQuality, GameObject current_obj = null)
        {
            try
            {
                const float tick_time = 1.0f / VMD_FPS;

                Vector3 default_position = Vector3.zero;
                if (current_obj != null)
                {
                    default_position = current_obj.transform.localPosition;
                }

                List <MMD.VMD.VMDFormat.Motion> mlist = format.motion_list.motion[current_bone];

                int keyframeCountX = GetKeyframeCount(mlist, 0, interpolationQuality);
                int keyframeCountY = GetKeyframeCount(mlist, 1, interpolationQuality);
                int keyframeCountZ = GetKeyframeCount(mlist, 2, interpolationQuality);

                FloatKeyframe[] lx_keys = new FloatKeyframe[keyframeCountX];
                FloatKeyframe[] ly_keys = new FloatKeyframe[keyframeCountY];
                FloatKeyframe[] lz_keys = new FloatKeyframe[keyframeCountZ];

                FloatKeyframe lx_prev_key = null;
                FloatKeyframe ly_prev_key = null;
                FloatKeyframe lz_prev_key = null;
                int           ix          = 0;
                int           iy          = 0;
                int           iz          = 0;
                for (int i = 0; i < mlist.Count; i++)
                {
                    float tick = mlist[i].frame_no * tick_time;

                    FloatKeyframe lx_cur_key = new FloatKeyframe(tick, mlist[i].location.x * scale_ + default_position.x);
                    FloatKeyframe ly_cur_key = new FloatKeyframe(tick, mlist[i].location.y * scale_ + default_position.y);
                    FloatKeyframe lz_cur_key = new FloatKeyframe(tick, mlist[i].location.z * scale_ + default_position.z);

                    // 各軸別々に補間が付いてる
                    FloatKeyframe.AddBezierKeyframes(mlist[i].interpolation, 0, lx_prev_key, lx_cur_key, interpolationQuality, ref lx_keys, ref ix);
                    FloatKeyframe.AddBezierKeyframes(mlist[i].interpolation, 1, ly_prev_key, ly_cur_key, interpolationQuality, ref ly_keys, ref iy);
                    FloatKeyframe.AddBezierKeyframes(mlist[i].interpolation, 2, lz_prev_key, lz_cur_key, interpolationQuality, ref lz_keys, ref iz);

                    lx_prev_key = lx_cur_key;
                    ly_prev_key = ly_cur_key;
                    lz_prev_key = lz_cur_key;
                }

                // 回転ボーンの場合はデータが入ってないはず
                if (mlist.Count != 0)
                {
                    AnimationCurve curve_x = ToAnimationCurveForLocation(lx_keys);
                    AnimationCurve curve_y = ToAnimationCurveForLocation(ly_keys);
                    AnimationCurve curve_z = ToAnimationCurveForLocation(lz_keys);

                    AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve(bone_path, typeof(Transform), "m_LocalPosition.x"), curve_x);
                    AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve(bone_path, typeof(Transform), "m_LocalPosition.y"), curve_y);
                    AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve(bone_path, typeof(Transform), "m_LocalPosition.z"), curve_z);
                }
            }
            catch (KeyNotFoundException)
            {
                Debug.LogError("互換性のないボーンが読み込まれました:" + current_bone);
            }
        }