예제 #1
0
        protected override void OnUpdate()
        {
            // Initialize
            Entities.WithNone <Initialized>().WithAll <Base>().ForEach((Entity entity, ref RigDefinitionSetup rigDefSetup) =>
            {
                // TODO (mogensh) make this an option. If we remap content to another rigentity we dont want to update rig here
                RigEntityBuilder.SetupRigEntity(entity, EntityManager, rigDefSetup.Value);
                if (EntityManager.HasComponent <SkinnedMeshRenderer>(entity))
                {
                    var animatedSkinMatricesArray = EntityManager.AddBuffer <AnimatedLocalToRig>(entity);
                    animatedSkinMatricesArray.ResizeUninitialized(rigDefSetup.Value.Value.Skeleton.BoneCount);
                }

                EntityManager.SetSharedComponentData(entity, new SharedRigDefinition {
                    Value = rigDefSetup.Value
                });

                PostUpdateCommands.AddComponent(entity, new Initialized());
            });

            // Deinitialize
            Entities.WithNone <Base>().WithAll <Initialized>().ForEach((Entity entity) =>
            {
                PostUpdateCommands.RemoveComponent <Initialized>(entity);
            });
        }
        public void CanInstantiatePrefabEntity()
        {
            var instanceCount = 100;
            var skeletonNodes = new SkeletonNode[] {
                new SkeletonNode {
                    ParentIndex = -1, Id = "Root", AxisIndex = -1
                },
                new SkeletonNode {
                    ParentIndex = 0, Id = "Hips", AxisIndex = -1
                },
                new SkeletonNode {
                    ParentIndex = 1, Id = "LeftUpLeg", AxisIndex = -1
                },
                new SkeletonNode {
                    ParentIndex = 1, Id = "RightUpLeg", AxisIndex = -1
                }
            };

            var rigDefinition = RigBuilder.CreateRigDefinition(skeletonNodes);

            var prefab = RigEntityBuilder.CreatePrefabEntity(m_Manager, rigDefinition);

            var entities = new NativeArray <Entity>(instanceCount, Allocator.Temp);

            m_Manager.Instantiate(prefab, entities);

            foreach (var entity in entities)
            {
                CheckEntityHasRigComponentTypeAndBufferResized(entity, rigDefinition, RigEntityBuilder.RigComponentTypes, skeletonNodes.Length);
            }
        }
예제 #3
0
파일: Spawner.cs 프로젝트: Rud156/TDDots
    protected override void OnUpdate()
    {
        Entities.ForEach((Entity e, ref RigSpawner spawner) =>
        {
            if (EntityManager.HasComponent <RigDefinitionSetup>(spawner.RigPrefab))
            {
                var rigDefinition = EntityManager.GetComponentData <RigDefinitionSetup>(spawner.RigPrefab);
                if (!rigDefinition.Value.IsCreated)
                {
                    throw new System.ObjectDisposedException("RigDefinition is not Created");
                }

                RigEntityBuilder.SetupRigEntity(spawner.RigPrefab, EntityManager, rigDefinition.Value);
            }

            for (var x = 0; x < spawner.CountX; x++)
            {
                for (var y = 0; y < spawner.CountY; ++y)
                {
                    var rigInstance = EntityManager.Instantiate(spawner.RigPrefab);
                    var position    = new float3(x * 1.3F, 0, y * 1.3F);
                    EntityManager.SetComponentData(rigInstance, new Translation {
                        Value = position
                    });

                    if (m_Input != null)
                    {
                        m_Input.RegisterEntity(rigInstance);
                    }
                }
            }

            EntityManager.DestroyEntity(e);
        });
    }
예제 #4
0
        protected override JobHandle OnUpdate(JobHandle inputDependencies)
        {
            inputDependencies.Complete();

            var animGraphSys = World.GetExistingSystem <AnimationGraphSystem>();

            // Initialize
            Entities
            .WithStructuralChanges()
            .WithNone <LOD>()
            .WithAll <Settings>()
            .ForEach((Entity entity) =>
            {
                GameDebug.Log(World, ShowLifetime, "InitSys: Initialize DotsAnimStateCtrl:{0}", entity);

                // Setup lowest LOD rig
                var rigDataBuffer = EntityManager.GetBuffer <RigData>(entity);
//                var lowestLod = rigDataBuffer.Length - 1;
                // TODO (mogensh) for now we only use Rig LOD for selecting low lod on server
                var isServer = World.GetExistingSystem <ServerSimulationSystemGroup>() != null;// TODO (mogensh) cant we find better way to test for server?
                var lod      = isServer ? 1 : 0;
                var rigData  = rigDataBuffer[lod];
                RigEntityBuilder.SetupRigEntity(entity, EntityManager, rigData.Rig);

                var animLocalToRigBuffer = EntityManager.AddBuffer <AnimatedLocalToRig>(entity);
                animLocalToRigBuffer.ResizeUninitialized(rigData.Rig.Value.Skeleton.Ids.Length);

                // Create root animsource
                var settings             = EntityManager.GetComponentData <Settings>(entity);
                var rootAnimSourceEntity = PrefabAssetManager.CreateEntity(EntityManager, settings.RootAnimSource);
#if UNITY_EDITOR
                var name = EntityManager.GetName(rootAnimSourceEntity) + " -> Entity " + entity.Index + ".DotsAnimStateController.RootAnimSource";
                EntityManager.SetName(rootAnimSourceEntity, name);
#endif
                AnimSource.SetAnimStateEntityOnPrefab(EntityManager, rootAnimSourceEntity, entity);

                var rootAnimSource   = RootAnimSource.Default;
                rootAnimSource.Value = rootAnimSourceEntity;
                EntityManager.AddComponentData(entity, rootAnimSource);

                EntityManager.AddComponentData(entity, new LOD {
                    Value = lod,
                });
            }).Run();


            // Deinitialize
            Entities
            .WithStructuralChanges()
            .WithNone <Settings>()
            .WithAll <LOD>()
            .ForEach((Entity entity, ref RootAnimSource rootAnimSource, ref OutputNode outputNode, ref GraphOutput graphOutput) =>
            {
                Deinitialize(EntityManager, entity, animGraphSys);
            }).Run();

            return(default);
예제 #5
0
 protected override void OnUpdate()
 {
     Entities.ForEach((RigComponent rigComponent) =>
     {
         var rigEntity     = GetPrimaryEntity(rigComponent);
         var skeletonNodes = RigGenerator.ExtractSkeletonNodesFromRigComponent(rigComponent);
         var channels      = RigGenerator.ExtractAnimationChannelFromRigComponent(rigComponent);
         var rigDefinition = RigBuilder.CreateRigDefinition(skeletonNodes, null, channels);
         RigEntityBuilder.SetupRigEntity(rigEntity, DstEntityManager, rigDefinition);
     });
 }
예제 #6
0
        public void CanApplyInPlaceNode()
        {
            var entity = m_Manager.CreateEntity();

            RigEntityBuilder.SetupRigEntity(entity, m_Manager, m_Rig);

            var clipNode = CreateNode <ClipNode>();

            Set.SendMessage(clipNode, ClipNode.SimulationPorts.Rig, m_Rig);
            Set.SendMessage(clipNode, ClipNode.SimulationPorts.Clip, m_Clip);
            Set.SetData(clipNode, ClipNode.KernelPorts.Time, 1.0f);

            var inPlaceNode = CreateNode <InPlaceMotionNode>();

            Set.SendMessage(inPlaceNode, InPlaceMotionNode.SimulationPorts.Rig, m_Rig);
            Set.SendMessage(inPlaceNode, InPlaceMotionNode.SimulationPorts.Configuration, new ClipConfiguration {
                MotionID = new StringHash("Motion")
            });

            Set.Connect(clipNode, ClipNode.KernelPorts.Output, inPlaceNode, InPlaceMotionNode.KernelPorts.Input);

            var entityNode = CreateComponentNode(entity);

            Set.Connect(inPlaceNode, InPlaceMotionNode.KernelPorts.Output, entityNode);

            m_Manager.AddComponent <PreAnimationGraphTag>(entity);

            m_AnimationGraphSystem.Update();

            var translation  = m_StopTranslation;
            var rotation     = m_StopRotation;
            var projRotation = math.normalize(new quaternion(0, rotation.value.y / rotation.value.w, 0, 1));

            var streamECS = AnimationStream.CreateReadOnly(
                m_Rig,
                m_Manager.GetBuffer <AnimatedData>(entity).AsNativeArray()
                );

            // validate projection of motion on root
            var rootTranslation = streamECS.GetLocalToParentTranslation(0);

            Assert.That(rootTranslation, Is.EqualTo(new float3(translation.x, 0, translation.z)).Using(TranslationComparer));
            var rootRotation = streamECS.GetLocalToParentRotation(0);

            Assert.That(rootRotation, Is.EqualTo(projRotation).Using(RotationComparer));

            // validate that motion is now in place
            var motionTranslation = streamECS.GetLocalToParentTranslation(2);

            Assert.That(motionTranslation, Is.EqualTo(new float3(0, translation.y, 0)).Using(TranslationComparer));
            var motionRotation = streamECS.GetLocalToParentRotation(2);

            Assert.That(motionRotation, Is.EqualTo(mathex.mul(math.conjugate(projRotation), rotation)).Using(RotationComparer));
        }
        public void CanCreatePrefabEntity()
        {
            var skeletonNodes = new SkeletonNode[] {
                new SkeletonNode {
                    ParentIndex = -1, Id = "Root", AxisIndex = -1
                }
            };

            var rigDefinition = RigBuilder.CreateRigDefinition(skeletonNodes);

            var prefab = RigEntityBuilder.CreatePrefabEntity(m_Manager, rigDefinition);

            CheckEntityHasRigComponentTypeAndBufferResized(prefab, rigDefinition, RigEntityBuilder.RigPrefabComponentTypes, skeletonNodes.Length);
        }
        protected override void SetUp()
        {
            base.SetUp();

            m_RigComputeMatricesSystem = World.GetOrCreateSystem <RigComputeMatricesSystem>();
            // Force and update to kick burst compilation
            m_RigComputeMatricesSystem.Update();

            Set.RendererModel = DataFlowGraph.NodeSet.RenderExecutionModel.Islands;

            // Force and update to kick burst compilation
            m_AnimationGraphSystem.Update();

            m_RigPrefab = RigEntityBuilder.CreatePrefabEntity(m_Manager, m_RigDefinition);

            m_Manager.AddComponentData(m_RigPrefab, new Translation {
                Value = float3.zero
            });
            m_Manager.AddComponentData(m_RigPrefab, new Rotation {
                Value = quaternion.identity
            });
        }
예제 #9
0
        public void CanEvaluateCycleRootClipNode(float time)
        {
            var entity = m_Manager.CreateEntity();

            RigEntityBuilder.SetupRigEntity(entity, m_Manager, m_Rig);

            var clipNode = CreateNode <ConfigurableClipNode>();

            Set.SendMessage(clipNode, ConfigurableClipNode.SimulationPorts.Configuration, new ClipConfiguration {
                Mask = ClipConfigurationMask.CycleRootMotion, MotionID = new StringHash("Motion")
            });
            Set.SendMessage(clipNode, ConfigurableClipNode.SimulationPorts.Rig, m_Rig);
            Set.SendMessage(clipNode, ConfigurableClipNode.SimulationPorts.Clip, m_Clip);
            Set.SetData(clipNode, ConfigurableClipNode.KernelPorts.Time, time);

            var entityNode = CreateComponentNode(entity);

            Set.Connect(clipNode, ConfigurableClipNode.KernelPorts.Output, entityNode);

            m_Manager.AddComponent <PreAnimationGraphTag>(entity);

            m_AnimationGraphSystem.Update();

            var normalizedTime    = time;
            var normalizedTimeInt = (int)normalizedTime;
            var cycle             = math.select(normalizedTimeInt, normalizedTimeInt - 1, normalizedTime < 0);

            normalizedTime = math.select(normalizedTime - normalizedTimeInt, normalizedTime - normalizedTimeInt + 1, normalizedTime < 0);

            // start and stop root transform
            var startTProj = new float3(m_StartTranslation.x, 0, m_StartTranslation.z);
            var startRProj = math.normalize(new quaternion(0, m_StartRotation.value.y / m_StartRotation.value.w, 0, 1));

            var stopTProj = new float3(m_StopTranslation.x, 0, m_StopTranslation.z);
            var stopRProj = math.normalize(new quaternion(0, m_StopRotation.value.y / m_StopRotation.value.w, 0, 1));

            // current root transform
            var translation = m_StopTranslation * normalizedTime + m_StartTranslation * (1f - normalizedTime);
            var rotation    = math.normalize(new quaternion(math.normalize(m_StopRotation).value *normalizedTime + math.normalize(m_StartRotation).value *(1f - normalizedTime)));

            var tProj = new float3(translation.x, 0, translation.z);
            var rProj = math.normalize(new quaternion(0, rotation.value.y / rotation.value.w, 0, 1));

            // cycled root transform
            var startX = cycle >= 0 ? new RigidTransform(startRProj, startTProj) : new RigidTransform(stopRProj, stopTProj);
            var stopX  = cycle >= 0 ? new RigidTransform(stopRProj, stopTProj) : new RigidTransform(startRProj, startTProj);

            var            x      = new RigidTransform(rProj, tProj);
            RigidTransform cycleX = mathex.rigidPow(math.mul(stopX, math.inverse(startX)), math.asuint(math.abs(cycle)));

            x = math.mul(cycleX, x);


            var streamECS = AnimationStream.CreateReadOnly(
                m_Rig,
                m_Manager.GetBuffer <AnimatedData>(entity).AsNativeArray()
                );

            // validate
            var rootTranslation = streamECS.GetLocalToParentTranslation(0);

            Assert.That(rootTranslation, Is.EqualTo(x.pos));
            var rootRotation = streamECS.GetLocalToParentRotation(0);

            Assert.That(rootRotation, Is.EqualTo(x.rot).Using(RotationComparer));
        }
예제 #10
0
        public void CanRemapAllIntChannel()
        {
            var sourceChannels = new IAnimationChannel[]
            {
                new IntChannel {
                    Id = "Root", DefaultValue = m_ExpectedSourceInt
                },
                new IntChannel {
                    Id = "Child1", DefaultValue = m_ExpectedSourceInt
                },
                new IntChannel {
                    Id = "Child2", DefaultValue = m_ExpectedSourceInt
                },
            };

            var sourceRig = new Rig {
                Value = RigBuilder.CreateRigDefinition(sourceChannels)
            };

            var destinationChannels = new IAnimationChannel[]
            {
                new IntChannel {
                    Id = "AnotherRoot", DefaultValue = 0
                },
                new IntChannel {
                    Id = "AnotherChild1", DefaultValue = 0
                },
                new IntChannel {
                    Id = "AnotherChild2", DefaultValue = 0
                },
            };
            var destinationRig = new Rig {
                Value = RigBuilder.CreateRigDefinition(destinationChannels)
            };
            var rigEntity = m_Manager.CreateEntity();

            RigEntityBuilder.SetupRigEntity(rigEntity, m_Manager, destinationRig);

            var rigRemapQuery = new RigRemapQuery
            {
                AllChannels = new [] {
                    new ChannelMap {
                        SourceId = "Root", DestinationId = "AnotherRoot"
                    },
                    new ChannelMap {
                        SourceId = "Child1", DestinationId = "AnotherChild1"
                    },
                    new ChannelMap {
                        SourceId = "Child2", DestinationId = "AnotherChild2"
                    }
                }
            };
            var remapTable = rigRemapQuery.ToRigRemapTable(sourceRig, destinationRig);

            // Here I'm using a layerMixer with no inputs connected
            // the expected result is to inject the default pose into Graph samples buffer
            var layerMixer = CreateNode <LayerMixerNode>();

            Set.SendMessage(layerMixer, LayerMixerNode.SimulationPorts.Rig, sourceRig);

            var rigRemapper = CreateNode <RigRemapperNode>();

            Set.Connect(layerMixer, LayerMixerNode.KernelPorts.Output, rigRemapper, RigRemapperNode.KernelPorts.Input);

            Set.SendMessage(rigRemapper, RigRemapperNode.SimulationPorts.SourceRig, sourceRig);
            Set.SendMessage(rigRemapper, RigRemapperNode.SimulationPorts.DestinationRig, destinationRig);
            Set.SendMessage(rigRemapper, RigRemapperNode.SimulationPorts.RemapTable, remapTable);

            var entityNode = CreateComponentNode(rigEntity);

            Set.Connect(rigRemapper, RigRemapperNode.KernelPorts.Output, entityNode);

            m_Manager.AddComponent <PreAnimationGraphTag>(rigEntity);

            m_AnimationGraphSystem.Update();

            var streamECS = AnimationStream.CreateReadOnly(
                destinationRig,
                m_Manager.GetBuffer <AnimatedData>(rigEntity).AsNativeArray()
                );

            Assert.That(streamECS.GetInt(0), Is.EqualTo(m_ExpectedSourceInt), "Channel int 0 doesn't match source rig default value");
            Assert.That(streamECS.GetInt(1), Is.EqualTo(m_ExpectedSourceInt), "Channel int 1 doesn't match source rig default value");
            Assert.That(streamECS.GetInt(2), Is.EqualTo(m_ExpectedSourceInt), "Channel int 2 doesn't match source rig default value");
        }
예제 #11
0
        public void CanRemapRigRotationOffset()
        {
            var sourceChannels = new IAnimationChannel[]
            {
                new LocalRotationChannel {
                    Id = "Root", DefaultValue = m_ExpectedSourceRotation
                },
                new LocalRotationChannel {
                    Id = "Child", DefaultValue = m_ExpectedSourceRotation
                },
            };

            var sourceRig = new Rig {
                Value = RigBuilder.CreateRigDefinition(sourceChannels)
            };

            var destinationChannels = new IAnimationChannel[]
            {
                new LocalRotationChannel {
                    Id = "AnotherRoot", DefaultValue = quaternion.identity
                },
                new LocalRotationChannel {
                    Id = "AnotherChild", DefaultValue = quaternion.identity
                },
            };

            var destinationRig = new Rig {
                Value = RigBuilder.CreateRigDefinition(destinationChannels)
            };
            var rigEntity = m_Manager.CreateEntity();

            RigEntityBuilder.SetupRigEntity(rigEntity, m_Manager, destinationRig);

            var rigRemapQuery = new RigRemapQuery
            {
                RotationChannels = new []
                {
                    new ChannelMap {
                        SourceId = "Root", DestinationId = "AnotherRoot"
                    },
                    new ChannelMap {
                        SourceId = "Child", DestinationId = "AnotherChild", OffsetIndex = 1
                    }
                },

                RotationOffsets = new []
                {
                    new RigRotationOffset(),
                    new RigRotationOffset {
                        PreRotation = math.normalize(math.quaternion(1, 2, 3, 4)), PostRotation = math.normalize(math.quaternion(5, 6, 7, 8))
                    }
                }
            };

            var remapTable = rigRemapQuery.ToRigRemapTable(sourceRig, destinationRig);

            // Here I'm using a layerMixer with no inputs connected
            // the expected result is to inject the default pose into Graph samples buffer
            var layerMixer = CreateNode <LayerMixerNode>();

            Set.SendMessage(layerMixer, LayerMixerNode.SimulationPorts.Rig, sourceRig);

            var rigRemapper = CreateNode <RigRemapperNode>();

            Set.Connect(layerMixer, LayerMixerNode.KernelPorts.Output, rigRemapper, RigRemapperNode.KernelPorts.Input);

            Set.SendMessage(rigRemapper, RigRemapperNode.SimulationPorts.SourceRig, sourceRig);
            Set.SendMessage(rigRemapper, RigRemapperNode.SimulationPorts.DestinationRig, destinationRig);
            Set.SendMessage(rigRemapper, RigRemapperNode.SimulationPorts.RemapTable, remapTable);

            var entityNode = CreateComponentNode(rigEntity);

            Set.Connect(rigRemapper, RigRemapperNode.KernelPorts.Output, entityNode);

            m_Manager.AddComponent <PreAnimationGraphTag>(rigEntity);

            m_AnimationGraphSystem.Update();

            var streamECS = AnimationStream.CreateReadOnly(
                destinationRig,
                m_Manager.GetBuffer <AnimatedData>(rigEntity).AsNativeArray()
                );

            Assert.That(streamECS.GetLocalToParentRotation(1), Is.EqualTo(math.mul(rigRemapQuery.RotationOffsets[1].PreRotation, math.mul(m_ExpectedSourceRotation, rigRemapQuery.RotationOffsets[1].PostRotation))).Using(RotationComparer), "Channel localRotation doesn't match destination rig default value with rig rotation offset");
        }