protected override JobHandle OnUpdate(JobHandle inputDeps) { inputDeps.Complete(); var nodeSet = World.GetExistingSystem <AnimationGraphSystem>().Set; var cmdBuffer = new EntityCommandBuffer(Allocator.TempJob); Entities .WithNone <AnimSource.HasValidRig>() .WithoutBurst() // Can be removed once NodeSets are Burst-friendly .ForEach((Entity entity, ref AnimSource.Data animSource, ref Settings settings, ref SystemState state) => { if (!EntityManager.HasComponent <SharedRigDefinition>(animSource.animStateEntity)) { return; } var sharedRigDef = EntityManager.GetSharedComponentData <SharedRigDefinition>(animSource.animStateEntity); var rig = sharedRigDef.Value; // Set the rig, bindings and values nodeSet.SendMessage(state.IkNode, TwoBoneIKNode.SimulationPorts.RigDefinition, rig); BlobAssetReference <AnimationAssetDatabase.RigMap> rigMap; AnimationAssetDatabase.GetOrCreateRigMapping(World, settings.RigAsset, rig, out rigMap); var ikData = new TwoBoneIKNode.TwoBoneIKData { // Remap the bone idx to current skeleton Root = settings.IkData.Root == -1 ? -1 : rigMap.Value.BoneMap[settings.IkData.Root], Mid = settings.IkData.Mid == -1 ? -1 : rigMap.Value.BoneMap[settings.IkData.Mid], Tip = settings.IkData.Tip == -1 ? -1 : rigMap.Value.BoneMap[settings.IkData.Tip], Hint = settings.IkData.Hint == -1 ? -1 : rigMap.Value.BoneMap[settings.IkData.Hint], Target = settings.IkData.Target == -1 ? -1 : rigMap.Value.BoneMap[settings.IkData.Target], WeightChannelIdx = settings.IkSettings.WeightCurve, LimbLengths = settings.IkData.LimbLengths, TargetOffset = settings.IkData.TargetOffset }; nodeSet.SendMessage(state.IkNode, TwoBoneIKNode.SimulationPorts.TwoBoneIKSetup, in ikData); nodeSet.SetData(state.IkNode, TwoBoneIKNode.KernelPorts.Weight, settings.IkSettings.Weight); nodeSet.SetData(state.IkNode, TwoBoneIKNode.KernelPorts.TargetPositionWeight, settings.IkSettings.TargetPositionWeight); nodeSet.SetData(state.IkNode, TwoBoneIKNode.KernelPorts.TargetRotationWeight, settings.IkSettings.TargetRotationWeight); nodeSet.SetData(state.IkNode, TwoBoneIKNode.KernelPorts.HintWeight, settings.IkSettings.HintWeight); cmdBuffer.AddComponent <AnimSource.HasValidRig>(entity); }).Run(); cmdBuffer.Playback(EntityManager); cmdBuffer.Dispose(); return(default);
protected override JobHandle OnUpdate(JobHandle inputDeps) { inputDeps.Complete(); var nodeSet = World.GetExistingSystem <AnimationGraphSystem>().Set; var cmdBuffer = new EntityCommandBuffer(Allocator.TempJob); // Handle rig change Entities .WithNone <AnimSource.HasValidRig>() .WithoutBurst() // Can be removed once NodeSets are Burst-friendly .ForEach((Entity entity, ref AnimSource.Data animSource, ref SystemState state, ref Settings settings) => { if (!EntityManager.HasComponent <SharedRigDefinition>(animSource.animStateEntity)) { return; } var sharedRigDef = EntityManager.GetSharedComponentData <SharedRigDefinition>(animSource.animStateEntity); var rig = sharedRigDef.Value; nodeSet.SendMessage(state.TwistNode, TwistNode.SimulationPorts.RigDefinition, rig); // Remap rig indexes // TODO: (sunek) Can we use the rig re-mapper from the animation package? BlobAssetReference <AnimationAssetDatabase.RigMap> rigMap; AnimationAssetDatabase.GetOrCreateRigMapping(World, settings.rigReference, rig, out rigMap); state.currentRigBoneIdx.DriverIndex = settings.boneReferences.DriverIndex != -1 ? rigMap.Value.BoneMap[settings.boneReferences.DriverIndex] : -1; state.currentRigBoneIdx.TwistJointA = settings.boneReferences.TwistJointA != -1 ? rigMap.Value.BoneMap[settings.boneReferences.TwistJointA] : -1; state.currentRigBoneIdx.TwistJointB = settings.boneReferences.TwistJointB != -1 ? rigMap.Value.BoneMap[settings.boneReferences.TwistJointB] : -1; state.currentRigBoneIdx.TwistJointC = settings.boneReferences.TwistJointC != -1 ? rigMap.Value.BoneMap[settings.boneReferences.TwistJointC] : -1; var nodeSettings = settings; nodeSettings.boneReferences = state.currentRigBoneIdx; nodeSet.SendMessage(state.TwistNode, TwistNode.SimulationPorts.Settings, nodeSettings); cmdBuffer.AddComponent <AnimSource.HasValidRig>(entity); }).Run(); cmdBuffer.Playback(EntityManager); cmdBuffer.Dispose(); return(default);
protected override JobHandle OnUpdate(JobHandle inputDeps) { // TODO (mogensh) When all rig remapping happens we animstream, we no longer need to handle rig change Profiler.BeginSample("RigAttach.HandleChange"); Entities .WithoutBurst() // EntityManager.Exists() and EntityManager.GetSharedComponentData() are not Burst-compatible .ForEach((Entity entity, ref AttachEntity attachEntity, ref AttachBone attachBone, ref State state) => { if (!EntityManager.Exists(attachEntity.Value)) { GameDebug.LogWarning(World, "Attach entity:{0}" + attachEntity.Value + " does no longer exist"); return; } // TODO (mogensh) dont check this every frame. Instead // Find bone index if (!attachBone.Value.Equals(state.LastMappedBoneRef) || attachEntity.Value != state.rigEntity) { if (attachEntity.Value != Entity.Null) { Profiler.BeginSample("GetSharedRigDef"); var sharedRigDef = EntityManager.GetSharedComponentData <SharedRigDefinition>(attachEntity.Value); Profiler.EndSample(); if (attachBone.Value.ReferenceRig.Value.GetHashCode() == sharedRigDef.Value.Value.GetHashCode()) { state.boneIndex = attachBone.Value.BoneIndex; } else { Profiler.BeginSample("GetOrCreateRigMapping"); BlobAssetReference <AnimationAssetDatabase.RigMap> rigMap; AnimationAssetDatabase.GetOrCreateRigMapping(World, attachBone.Value.ReferenceRig, sharedRigDef.Value, out rigMap); Profiler.EndSample(); state.boneIndex = rigMap.Value.BoneMap[attachBone.Value.BoneIndex]; } } else { state.boneIndex = -1; } state.LastMappedBoneRef = attachBone.Value; // new RuntimeBoneReference(attachBone.Value); state.rigEntity = attachEntity.Value; } }).Run(); Profiler.EndSample(); var AnimatedLocalToWorldFromEntity = GetBufferFromEntity <AnimatedLocalToWorld>(true); var LocalToParentFromEntity = GetComponentDataFromEntity <LocalToParent>(true); Profiler.BeginSample("RigAttach.Move"); Entities .WithReadOnly(AnimatedLocalToWorldFromEntity) .WithReadOnly(LocalToParentFromEntity) .ForEach((Entity entity, ref LocalToWorld localToWorld, ref Translation translation, ref Rotation rotation, in AttachEntity attachEntity, in AttachBone attachBone, in State state) => { if (!AnimatedLocalToWorldFromEntity.Exists(attachEntity.Value)) { //GameDebug.LogWarning(World, string.Format("RigAttacher:{0} attacheEntity:{1} has not AnimatedLocalToWorld", entity,attachEntity.Value)); return; } // Move if (state.boneIndex != -1) { var localToWorldBuffer = AnimatedLocalToWorldFromEntity[attachEntity.Value]; var boneLocalToWorld = localToWorldBuffer[state.boneIndex].Value; if (LocalToParentFromEntity.HasComponent(entity)) { var attacherLocalToParent = LocalToParentFromEntity[entity]; boneLocalToWorld = math.mul(boneLocalToWorld, attacherLocalToParent.Value); } localToWorld = new LocalToWorld { Value = boneLocalToWorld }; // TODO (mogensh) Unity.Physics uses translation+rotation as input so they also need to be set. translation = new Translation { Value = boneLocalToWorld.c3.xyz, }; rotation = new Rotation { Value = new quaternion(boneLocalToWorld), }; } }).Run();