Exemple #1
0
        /// <summary>
        /// モーションクリップをアセットとして保存する。
        /// </summary>
        static void save(UnityEngine.Object[] selectedObjects, MotionClip motionClip)
        {
            // 渡されたアセットと同じ場所のパス生成

            var srcFilePath = AssetDatabase.GetAssetPath(selectedObjects.OfType <GameObject>().First());

            var folderPath = Path.GetDirectoryName(srcFilePath);

            var fileName = Path.GetFileNameWithoutExtension(srcFilePath);

            var dstFilePath = folderPath + $"/Motion {fileName}.asset";


            // アセットとして MotionClip を生成

            AssetDatabase.CreateAsset(motionClip, dstFilePath);

            AssetDatabase.Refresh();
        }
        static public void ConvertFrom(this MotionDataInNative dst, MotionClip src)
        {
            // ボーン
            var qParentBones =
                from parentPath in src.StreamPaths.Select(path => getParent(path))                      // ペアレントパス列挙
                join pathIndex in src.StreamPaths.Select((path, i) => (path, i))                        // 順序数を保持する索引と外部結合する
                on parentPath equals pathIndex.path
                into pathIndexes
                from pathIndex in pathIndexes.DefaultIfEmpty((path: "", i: -1))                                 // 結合できないパスは -1
                select pathIndex.i
            ;

            string getParent(string path) => Path.GetDirectoryName(path).Replace("\\", "/");


            // モーション
            var qMotions =
                from motion in src.MotionData.Motions
                select new MotionUnitInNative
            {
                TimeLength = motion.TimeLength
            };



            // ソース全キー
            var qKeys =
                from motion in src.MotionData.Motions
                from section in motion.Sections
                from stream in section.Streams
                from key in Enumerable.Zip(stream.keys.Append(new KeyDataUnit()), stream.keys, (pre, now) => (pre, now))
                select new KeyUnitInNative
            {
                //	Time	= new float4( key.now.Time - key.pre.Time, 0.0f, 0.0f, 0.0f ),
                Time  = new float4(key.now.Time, 0.0f, 0.0f, 0.0f),
                Value = key.now.Value
            };



            // インクリメンタルなキー位置を返す。苦肉の策。
            var iKeyInPool = 0;
            Func <StreamDataUnit, int> indexResolver = stream =>
            {
                var i = iKeyInPool;
                iKeyInPool += stream.keys.Length;
                return(i);
            };

            //var baseSectionList = new [] { "m_LocalPosition", "m_LocalRotation", "m_LocalScale" };

            // ストリームスライスの構築
            var qStreamSlices =

                // モーションごとの3セクション配列を生成する。
                from motion in src.MotionData.Motions
                let sections = motion.Sections.ToDictionary(section => section.SectionName)
                               select new []
            {
                sections.GetOrDefault("m_LocalPosition"),
                sections.GetOrDefault("m_LocalRotation"),
                sections.GetOrDefault("m_LocalScale")
            }
            into sectionArray

            // セクションは空の場合がある。空セクションのストリームも確保し、すべてデフォルトスライスを配置させる。
            from section in sectionArray
            let streams = section.Streams?.ToDictionary(stream => stream.StreamPath)

                          // ストリームも空の場合がある。空はデフォルトスライス。また並び順は src.StreamPaths の通り。
                          from streamPath in src.StreamPaths
                          let stream = streams?.GetOrDefault(streamPath) ?? new StreamDataUnit()

                                       select new StreamSliceInNative
            {
                Stream = stream.keys != null
                                                ? new NativeSlice <KeyUnitInNative>(dst.pool.Keys, indexResolver(stream), stream.keys.Length)
                                                : new NativeSlice <KeyUnitInNative>()
            };



            // 実体を確保
            dst.pool.Motions      = qMotions.ToNativeArray(Allocator.Persistent);
            dst.pool.Keys         = qKeys.ToNativeArray(Allocator.Persistent);
            dst.pool.StreamSlices = qStreamSlices.ToNativeArray(Allocator.Persistent);
            dst.pool.BoneParents  = qParentBones.ToNativeArray(Allocator.Persistent);
            dst.boneLength        = src.StreamPaths.Length;
        }