public void Execute(RenderContext context, KernelData data, ref KernelDefs ports)
            {
                if (data.RigDefinition == BlobAssetReference <RigDefinition> .Null)
                {
                    return;
                }

                data.ProfileMarker.Begin();

                var inputStream  = AnimationStream.CreateReadOnly(data.RigDefinition, context.Resolve(ports.Input));
                var outputStream = AnimationStream.Create(data.RigDefinition, context.Resolve(ref ports.Output));

                AnimationStreamUtils.MemCpy(ref outputStream, ref inputStream);

                var deltaRootX = new RigidTransform(inputStream.GetLocalToParentRotation(0), inputStream.GetLocalToParentTranslation(0));

                context.Resolve(ref ports.DeltaRootX) = math.float4x4(deltaRootX);

                RigidTransform prevRootX = new RigidTransform(context.Resolve(ports.PrevRootX));

                prevRootX.rot = math.normalizesafe(prevRootX.rot);
                context.Resolve(ref ports.RootX) = math.float4x4(math.mul(prevRootX, deltaRootX));

                var defaultStream = AnimationStream.FromDefaultValues(outputStream.Rig);

                outputStream.SetLocalToParentTranslation(0, defaultStream.GetLocalToParentTranslation(0));
                outputStream.SetLocalToParentRotation(0, defaultStream.GetLocalToParentRotation(0));

                data.ProfileMarker.End();
            }
            public void Execute(RenderContext context, KernelData data, ref KernelDefs ports)
            {
                if (data.RigDefinition == default)
                {
                    return;
                }

                data.ProfileMarker.Begin();

                // Fill the destination stream with default values.
                var inputStream  = AnimationStream.CreateReadOnly(data.RigDefinition, context.Resolve(ports.Input));
                var outputStream = AnimationStream.Create(data.RigDefinition, context.Resolve(ref ports.Output));

                AnimationStreamUtils.MemCpy(ref outputStream, ref inputStream);

                var defaultStream     = AnimationStream.FromDefaultValues(data.RigDefinition);
                var motionTranslation = outputStream.GetLocalToRootTranslation(data.TranslationIndex);
                var motionRotation    = outputStream.GetLocalToRootRotation(data.RotationIndex);

                var defaultRotation = defaultStream.GetLocalToRootRotation(data.RotationIndex);

                defaultRotation = mathex.mul(motionRotation, math.conjugate(defaultRotation));
                defaultRotation = mathex.select(quaternion.identity, defaultRotation, math.dot(defaultRotation, defaultRotation) > math.FLT_MIN_NORMAL);

                ProjectMotionNode(motionTranslation, defaultRotation, out float3 motionProjTranslation, out quaternion motionProjRotation, (data.Configuration.Mask & ClipConfigurationMask.BankPivot) != 0);

                outputStream.SetLocalToRootTranslation(0, motionProjTranslation);
                outputStream.SetLocalToRootRotation(0, motionProjRotation);

                outputStream.SetLocalToRootTranslation(data.TranslationIndex, motionTranslation);
                outputStream.SetLocalToRootRotation(data.RotationIndex, motionRotation);

                data.ProfileMarker.End();
            }
Esempio n. 3
0
    protected override IKGraphData CreateGraph(Entity entity, ref Rig rig, PostAnimationGraphSystem graphSystem, ref IKGraphSetup setup)
    {
        var set = graphSystem.Set;

        var data = new IKGraphData();

        data.EntityNode     = set.CreateComponentNode(entity);
        data.LeftArmIKNode  = set.Create <TwoBoneIKNode>();
        data.RightArmIKNode = set.Create <TwoBoneIKNode>();
        data.HeadLookAtNode = set.Create <AimConstraintNode>();

        set.Connect(data.EntityNode, data.LeftArmIKNode, TwoBoneIKNode.KernelPorts.Input, NodeSet.ConnectionType.Feedback);
        set.Connect(data.LeftArmIKNode, TwoBoneIKNode.KernelPorts.Output, data.RightArmIKNode, TwoBoneIKNode.KernelPorts.Input);
        set.Connect(data.RightArmIKNode, TwoBoneIKNode.KernelPorts.Output, data.HeadLookAtNode, AimConstraintNode.KernelPorts.Input);
        set.Connect(data.HeadLookAtNode, AimConstraintNode.KernelPorts.Output, data.EntityNode);

        var stream    = AnimationStream.FromDefaultValues(rig);
        var leftArmIK = new TwoBoneIKNode.SetupMessage
        {
            RootIndex    = setup.LeftArmIK.x,
            MidIndex     = setup.LeftArmIK.y,
            TipIndex     = setup.LeftArmIK.z,
            TargetOffset = math.RigidTransform(math.inverse(stream.GetLocalToRootRotation(setup.LeftArmIK.z)), float3.zero),
            LimbLengths  = math.float2(
                math.distance(stream.GetLocalToRootTranslation(setup.LeftArmIK.x), stream.GetLocalToRootTranslation(setup.LeftArmIK.y)),
                math.distance(stream.GetLocalToRootTranslation(setup.LeftArmIK.y), stream.GetLocalToRootTranslation(setup.LeftArmIK.z))
                )
        };

        var rightArmIK = new TwoBoneIKNode.SetupMessage
        {
            RootIndex    = setup.RightArmIK.x,
            MidIndex     = setup.RightArmIK.y,
            TipIndex     = setup.RightArmIK.z,
            TargetOffset = math.RigidTransform(math.inverse(stream.GetLocalToRootRotation(setup.RightArmIK.z)), float3.zero),
            LimbLengths  = math.float2(
                math.distance(stream.GetLocalToRootTranslation(setup.RightArmIK.x), stream.GetLocalToRootTranslation(setup.RightArmIK.y)),
                math.distance(stream.GetLocalToRootTranslation(setup.RightArmIK.y), stream.GetLocalToRootTranslation(setup.RightArmIK.z))
                )
        };

        var headAim = new AimConstraintNode.SetupMessage
        {
            Index         = setup.HeadIndex,
            LocalAimAxis  = setup.HeadLocalAimAxis,
            LocalAxesMask = math.bool3(true)
        };

        // Apply static corrections to the left and right arms but this data
        // could be coming from other entities or the AnimationStream itself
        set.SendMessage(data.LeftArmIKNode, TwoBoneIKNode.SimulationPorts.Rig, rig);
        set.SendMessage(data.LeftArmIKNode, TwoBoneIKNode.SimulationPorts.ConstraintSetup, leftArmIK);
        set.SetData(data.LeftArmIKNode, TwoBoneIKNode.KernelPorts.Target, math.float4x4(quaternion.AxisAngle(math.up(), math.radians(60f)), math.float3(-0.45f, 1.1f, 0.2f)));

        set.SendMessage(data.RightArmIKNode, TwoBoneIKNode.SimulationPorts.Rig, rig);
        set.SendMessage(data.RightArmIKNode, TwoBoneIKNode.SimulationPorts.ConstraintSetup, rightArmIK);
        set.SetData(data.RightArmIKNode, TwoBoneIKNode.KernelPorts.Target, math.float4x4(quaternion.AxisAngle(math.up(), math.radians(-60f)), math.float3(0.45f, 1.1f, 0.2f)));

        // Same as above but now applying static corrections to the head bone for a look at
        set.SendMessage(data.HeadLookAtNode, AimConstraintNode.SimulationPorts.Rig, rig);
        set.SendMessage(data.HeadLookAtNode, AimConstraintNode.SimulationPorts.ConstraintSetup, headAim);
        set.SetPortArraySize(data.HeadLookAtNode, AimConstraintNode.KernelPorts.SourcePositions, 1);
        set.SetPortArraySize(data.HeadLookAtNode, AimConstraintNode.KernelPorts.SourceOffsets, 1);
        set.SetPortArraySize(data.HeadLookAtNode, AimConstraintNode.KernelPorts.SourceWeights, 1);
        set.SetData(data.HeadLookAtNode, AimConstraintNode.KernelPorts.SourcePositions, 0, stream.GetLocalToRootTranslation(headAim.Index) + math.float3(0f, -2f, 0.5f));
        set.SetData(data.HeadLookAtNode, AimConstraintNode.KernelPorts.SourceOffsets, 0, quaternion.identity);
        set.SetData(data.HeadLookAtNode, AimConstraintNode.KernelPorts.SourceWeights, 0, 1f);

        PostUpdateCommands.AddComponent(entity, graphSystem.Tag);

        return(data);
    }