static public void TransformKeyDataToWorld(this MotionDataInNative motionData)
        {
            var rotationKeyLength = motionData.StreamPool
                                    .Buffer(3)
                                    .Select(x => x[(int)KeyStreamSection.rotations].Stream.Length)
                                    .Sum()
            ;
            var dst = new NativeArray <KeyUnitInNative>(rotationKeyLength * 2, Allocator.Persistent);

            var qKeysPerMotions =
                from ma in motionData.pool.Motions.Select((x, i) => motionData.CreateAccessor(i))
                from ibone in Enumerable.Range(0, motionData.BoneLength)
                select(ma, ime: ibone, iparent: ma.GetParentBoneIndex(ibone))
            ;

            foreach (var(ma, ime, iparent) in qKeysPerMotions)
            {
                //if( iparent == -1 ) continue;
                if (iparent == -1)
                {
                }

                Debug.Log($"bone {ime} {iparent}");
                var thisPositions   = ma.GetStreamSlice(ime, KeyStreamSection.positions).Stream;
                var parentPositions = ma.GetStreamSlice(iparent, KeyStreamSection.positions).Stream;
                var thisRotations   = ma.GetStreamSlice(ime, KeyStreamSection.rotations).Stream;
                var parentRotations = ma.GetStreamSlice(iparent, KeyStreamSection.rotations).Stream;

                var posNearKeys = new StreamNearKeysCacheData();
                var posShifter  = new StreamKeyShiftData()
                {
                    Keys = parentPositions
                };
                var rotNearKeys = new StreamNearKeysCacheData();
                var rotShifter  = new StreamKeyShiftData()
                {
                    Keys = parentRotations
                };

                StreamExtentions.InitializeKeys(ref rotNearKeys, ref rotShifter);

                for (var i = 0; i < thisRotations.Length; i++)
                {
                    var thisRot = thisRotations[i];

                    rotNearKeys.TimeProgress = thisRot.Time.x;
                    do
                    {
                        StreamExtentions.ShiftKeysIfOverKeyTime(ref rotNearKeys, ref rotShifter);
                    }while(rotNearKeys.TimeProgress > rotNearKeys.Time_To);

                    var lrot = new quaternion(thisRot.Value);
                    var prot = new quaternion(rotNearKeys.Interpolate(rotNearKeys.CaluclateTimeNormalized()));

                    thisRot.Value    = math.mul(prot, lrot).value;
                    thisRotations[i] = thisRot;
                    //	Debug.Log($"{thisRot.Time} {thisRot.Value}");
                }
            }
        }
        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;
        }
        static public void TransformKeyDataToWorld_(this MotionDataInNative motionData)
        {
            var qKeysPerMotions =
                from ma in motionData.pool.Motions.Select((x, i) => motionData.CreateAccessor(i))
                from ibone in Enumerable.Range(0, motionData.BoneLength)
                select(ma, ime: ibone, iparent: ma.GetParentBoneIndex(ibone))
            ;

            foreach (var(ma, ime, iparent) in qKeysPerMotions)
            {
                if (iparent == -1)
                {
                    continue;
                }

                Debug.Log($"bone {ime} {iparent}");
                var thisPositions   = ma.GetStreamSlice(ime, KeyStreamSection.positions).Stream;
                var parentPositions = ma.GetStreamSlice(iparent, KeyStreamSection.positions).Stream;
                var thisRotations   = ma.GetStreamSlice(ime, KeyStreamSection.rotations).Stream;
                var parentRotations = ma.GetStreamSlice(iparent, KeyStreamSection.rotations).Stream;

                var posNearKeys = new StreamNearKeysCacheData();
                var posShifter  = new StreamKeyShiftData()
                {
                    Keys = parentPositions
                };
                var rotNearKeys = new StreamNearKeysCacheData();
                var rotShifter  = new StreamKeyShiftData()
                {
                    Keys = parentRotations
                };

                StreamExtentions.InitializeKeys(ref rotNearKeys, ref rotShifter);

                for (var i = 0; i < thisRotations.Length; i++)
                {
                    var thisRot = thisRotations[i];

                    rotNearKeys.TimeProgress = thisRot.Time.x;
                    do
                    {
                        StreamExtentions.ShiftKeysIfOverKeyTime(ref rotNearKeys, ref rotShifter);
                    }while(rotNearKeys.TimeProgress > rotNearKeys.Time_To);

                    var lrot = new quaternion(thisRot.Value);
                    var prot = new quaternion(rotNearKeys.Interpolate(rotNearKeys.CaluclateTimeNormalized()));

                    thisRot.Value    = math.mul(prot, lrot).value;
                    thisRotations[i] = thisRot;
                    //	Debug.Log($"{thisRot.Time} {thisRot.Value}");
                }

                StreamExtentions.InitializeKeys(ref posNearKeys, ref posShifter);
                StreamExtentions.InitializeKeys(ref rotNearKeys, ref rotShifter);

                for (var i = 0; i < thisPositions.Length; i++)
                {
                    var thisPos = thisPositions[i];

                    posNearKeys.TimeProgress = thisPos.Time.x;
                    do
                    {
                        StreamExtentions.ShiftKeysIfOverKeyTime(ref posNearKeys, ref posShifter);
                    }while(posNearKeys.TimeProgress > posNearKeys.Time_To);

                    rotNearKeys.TimeProgress = thisPos.Time.x;
                    do
                    {
                        StreamExtentions.ShiftKeysIfOverKeyTime(ref rotNearKeys, ref rotShifter);
                    }while(rotNearKeys.TimeProgress > rotNearKeys.Time_To);

                    var lpos = thisPos.Value.As_float3();
                    var ppos = posNearKeys.Interpolate(posNearKeys.CaluclateTimeNormalized());
                    var prot = new quaternion(rotNearKeys.Interpolate(rotNearKeys.CaluclateTimeNormalized()));

                    thisPos.Value    = math.mul(prot, lpos).As_float4() + ppos;
                    thisPositions[i] = thisPos;
                    //Debug.Log( $"{thisPos.Time} {thisPos.Value}" );
                }
            }
        }
Beispiel #4
0
        //private async void Awake()
        private void Start()
        {
            var md = new MotionDataInNative();

            md.ConvertFrom(MotionClipData);
            //	md.TransformKeyDataToWorld_();



            // メッシュの加工

            var newmesh = new Mesh();

            newmesh.vertices    = meshSetting.mesh.vertices;
            newmesh.boneWeights = meshSetting.mesh.boneWeights;
            newmesh.bindposes   = meshSetting.mesh.bindposes;
            newmesh.normals     = meshSetting.mesh.normals;
            newmesh.uv          = meshSetting.mesh.uv;
            newmesh.triangles   = meshSetting.mesh.triangles;
            meshSetting.mesh    = newmesh.ConvertForMotionable(useUvChannel: 1, MotionClipData);


            var bindposes = meshSetting.mesh.bindposes;

            meshSetting.material.SetMatrixArray("mts", bindposes);
            meshSetting.material.SetInt("boneLength", bindposes.Length);

            meshSetting.material.SetVectorArray("positions", new Vector4 [1023]);
            meshSetting.material.SetVectorArray("rotations", new Vector4 [1023]);



            // アーキタイプ

            var em = World.Active.GetOrCreateManager <EntityManager>();

            var streamArch = em.CreateArchetype(
                typeof(StreamInitialLabel),
                typeof(StreamKeyShiftData),
                typeof(StreamNearKeysCacheData),
                typeof(StreamInterpolatedData)
                );
            var boneArch = em.CreateArchetype(
                typeof(DrawBoneTargetLabel),
                typeof(BoneEntityLinkData),
                typeof(BoneIndexData),
                typeof(BonePostureData)
                );
            var motionArch = em.CreateArchetype(
                typeof(MotionInitializeData),
                typeof(MotionComponentData)
                );

            var rendererArch = em.CreateArchetype(
                typeof(MeshInstanceRenderer)
                );


            // レンダラ

            var rent = em.CreateEntity(rendererArch);

            em.SetSharedComponentData(rent, meshSetting);

            var drawOrderId     = 0;
            var boneSerialIndex = 0;


            //	Enumerable.Range(0,num).ForEach( x => create( Random.Range( 0, 15 ) ) );//.AddTo( gameObject );
            Observable.EveryGameObjectUpdate().Take(num).Subscribe(x => create(Random.Range(0, 15))).AddTo(gameObject);
            //	motionIndex.Subscribe( x => create(x) ).AddTo( gameObject );


            void create(int motionIndex)
            {
                var ma = md.CreateAccessor(motionIndex);



                // ボーン&ストリーム

                var    nowTime = Time.time;
                Entity boneTop;

                using (var boneEntities = new NativeArray <Entity>(ma.boneLength, Allocator.Temp))
                    using (var streamEntities = new NativeArray <Entity>(ma.boneLength * 2, Allocator.Temp))
                    {
                        em.CreateEntity(boneArch, boneEntities);
                        em.CreateEntity(streamArch, streamEntities);

                        boneTop = boneEntities[0];

                        Enumerable.Zip(boneEntities, streamEntities.Buffer(2), (bone, streams) => (bone, streams))
                        .ForEach((ents, ibone) =>
                        {
                            var parentIndex  = ma.GetParentBoneIndex(ibone);
                            var siblingIndex = ibone + 1;

                            em.SetComponentData(ents.bone,
                                                new BoneEntityLinkData
                            {
                                Self    = ents.bone,
                                Sibling = siblingIndex <ma.boneLength?boneEntities[siblingIndex] : Entity.Null,
                                                        Parent = parentIndex> -1 ? boneEntities[parentIndex] : Entity.Null,
                                positionEntity = ents.streams[0],
                                rotationEntity = ents.streams[1],
                                ParentIndex    = parentIndex,                                         //
                            }
                                                );
                            em.SetComponentData(ents.bone,
                                                new BoneIndexData
                            {
                                Index       = ibone,
                                ParentIndex = parentIndex,
                            }
                                                );
                            em.SetComponentData(ents.bone,
                                                new DrawBoneTargetLabel
                            {
                                drawingOrder = drawOrderId,
                                boneIndex    = ibone,
                            }
                                                );
                            //em.SetComponentData( ents.bone,
                            //	new BonePostureData
                            //	{
                            //		boneSerialIndex = boneSerialIndex++,//
                            //		boneIndex = ibone,
                            //		parentBoneIndex = parentIndex//
                            //	}
                            //);

                            //	em.AddComponentData( ents.streams[0], new StreamInitialData() );
                            //	if( ibone != 0 ) em.AddComponentData( ents.streams[0], new StreamInitialDataFor1pos() );

                            createStreamSectionEntity(KeyStreamSection.positions, 0.1f);
                            createStreamSectionEntity(KeyStreamSection.rotations, 0.1f);

                            void createStreamSectionEntity(KeyStreamSection streamSection, float timeScale)
                            {
                                //	em.AddComponentData( ents.streams[(int)streamSection], new StreamInitialData() );
                                em.SetComponentData(ents.streams[(int)streamSection],
                                                    new StreamKeyShiftData
                                {
                                    Self = ents.streams[(int)streamSection],
                                    Keys = ma.GetStreamSlice(ibone, streamSection).Stream
                                }
                                                    );
                                em.SetComponentData(ents.streams[(int)streamSection],
                                                    new StreamNearKeysCacheData
                                {
                                    TimeLength = ma.TimeLength,
                                    TimeScale  = 0.1f
                                }
                                                    );
                            }
                        });
                    }


                // モーション

                var motionEntity = em.CreateEntity(motionArch);

                //	em.AddComponent( motionEntity, typeof(MotionInitializeData) );

                em.AddComponentData <DrawTargetLabel>(motionEntity,
                                                      new DrawTargetLabel
                {
                    orderId = drawOrderId++
                }
                                                      );
                em.SetComponentData <MotionComponentData>(motionEntity,
                                                          new MotionComponentData
                {
                    MotionIndex  = motionIndex,
                    DataAccessor = ma,
                    Self         = motionEntity,
                    BoneTop      = boneTop
                }
                                                          );
                em.SetComponentData <MotionInitializeData>(motionEntity,
                                                           new MotionInitializeData
                {
                    Self        = motionEntity,
                    BoneArche   = boneArch,
                    StreamArche = streamArch
                }
                                                           );
            }

            this.motionData = md;

            //await this.OnDestroyAsObservable();
        }