public InverseKinematicsPerformanceDemo()
    {
        var figureDir = UnpackedArchiveDirectory.Make(new System.IO.DirectoryInfo("work/figures/genesis-3-female"));

        var channelSystemRecipe = Persistance.Load <ChannelSystemRecipe>(figureDir.File("channel-system-recipe.dat"));

        channelSystem = channelSystemRecipe.Bake(null);

        var boneSystemRecipe = Persistance.Load <BoneSystemRecipe>(figureDir.File("bone-system-recipe.dat"));

        boneSystem = boneSystemRecipe.Bake(channelSystem.ChannelsByName);

        var inverterParameters = Persistance.Load <InverterParameters>(figureDir.File("inverter-parameters.dat"));

        rigidBoneSystem = new RigidBoneSystem(boneSystem);

        goalProvider = new DemoInverseKinematicsGoalProvider(rigidBoneSystem);
        solver       = new HarmonicInverseKinematicsSolver(rigidBoneSystem, inverterParameters.BoneAttributes);

        var pose          = Persistance.Load <List <Pose> >(figureDir.File("animations/idle.dat"))[0];
        var channelInputs = channelSystem.MakeDefaultChannelInputs();

        new Poser(channelSystem, boneSystem).Apply(channelInputs, pose, DualQuaternion.Identity);
        var channelOutputs = channelSystem.Evaluate(null, channelInputs);

        rigidBoneSystem.Synchronize(channelOutputs);
        initialInputs = rigidBoneSystem.ReadInputs(channelOutputs);
    }
コード例 #2
0
    public void Run()
    {
        var channelOutputs = channelSystem.Evaluate(null, channelInputs);

        rigidBoneSystem.Synchronize(channelOutputs);
        var inputs = rigidBoneSystem.ReadInputs(channelOutputs);

        CheckConsistency(channelOutputs);

        var stopwatch  = Stopwatch.StartNew();
        int trialCount = 0;

        while (true)
        {
            rigidBoneSystem.GetBoneTransforms(inputs);

            trialCount += 1;
            if (trialCount == 1000)
            {
                Console.WriteLine(stopwatch.Elapsed.TotalMilliseconds / trialCount);

                trialCount = 0;
                stopwatch.Restart();
            }
        }
    }
コード例 #3
0
    public void Update(FrameUpdateParameters updateParameters, ChannelInputs inputs)
    {
        var outputs            = channelSystem.Evaluate(null, inputs);
        var chestBoneTransform = chestBone.GetChainedTransform(outputs);
        var chestBoneRotation  = chestBoneTransform.RotationStage.Rotation;

        chestBoneRotation.Invert();
        var gravity = Vector3.Transform(Vector3.Down, chestBoneRotation);

        float xRotation = -5 - gravity.Y * 5;

        lPectoralBone.Rotation.X.SetValue(inputs, xRotation);
        rPectoralBone.Rotation.X.SetValue(inputs, xRotation);

        float yRotationInput = gravity.X;

        //Console.WriteLine(yRotation);
        lPectoralBone.Rotation.Y.SetValue(inputs, 5 * ExpandNegative(yRotationInput));
        rPectoralBone.Rotation.Y.SetValue(inputs, 5 * ExpandPositive(yRotationInput));

        float flatten     = Max(-gravity.Z, 0);
        float hangForward = Max(+gravity.Z, 0);

        flattenChannel.SetValue(inputs, flatten);
        hangForwardChannel.SetValue(inputs, hangForward);
    }
    public void Update(FrameUpdateParameters updateParameters, ChannelInputs channelInputs, ControlVertexInfo[] previousFrameControlVertexInfos)
    {
        var channelOutputs = channelSystem.Evaluate(null, channelInputs);

        boneSystem.Synchronize(channelOutputs);
        var baseInputs   = boneSystem.ReadInputs(channelOutputs);
        var resultInputs = boneSystem.ApplyDeltas(baseInputs, poseDeltas);

        List <InverseKinematicsGoal> goals = goalProvider.GetGoals(updateParameters, resultInputs, previousFrameControlVertexInfos);

        solver.Solve(boneSystem, goals, resultInputs);
        poseDeltas = boneSystem.CalculateDeltas(baseInputs, resultInputs);

        boneSystem.WriteInputs(channelInputs, channelOutputs, resultInputs);
    }
コード例 #5
0
    public void Update(FrameUpdateParameters updateParameters, ChannelInputs inputs)
    {
        headPositionForecaster.Update(updateParameters.Time, updateParameters.HeadPosition);

        var forecastHeadPosition = headPositionForecaster.Forecast;

        if (!behaviorModel.LookAtPlayer)
        {
            return;
        }

        var outputs = channelSystem.Evaluate(null, inputs);
        var eyeParentTotalTransform = eyeParentBone.GetChainedTransform(outputs);

        UpdateEye(outputs, eyeParentTotalTransform, inputs, leftEyeBone, forecastHeadPosition);
        UpdateEye(outputs, eyeParentTotalTransform, inputs, rightEyeBone, forecastHeadPosition);
    }
コード例 #6
0
    private void Update3dAudioPosition(FrameUpdateParameters updateParameters, ChannelInputs inputs)
    {
        TrackedDevicePose_t gamePose = updateParameters.GamePoses[OpenVR.k_unTrackedDeviceIndex_Hmd];
        Matrix hmdToWorldTransform   = gamePose.mDeviceToAbsoluteTracking.Convert();

        hmdToWorldTransform.Invert();

        var outputs            = channelSystem.Evaluate(null, inputs);
        var headTotalTransform = headBone.GetChainedTransform(outputs);

        var     headBindPoseCenter = headBone.CenterPoint.GetValue(outputs);
        Vector3 headWorldPosition  = headTotalTransform.Transform(headBindPoseCenter) / 100;

        Vector3 headHmdPosition = Vector3.TransformCoordinate(headWorldPosition, hmdToWorldTransform);

        phononStream.HeadRelativePosition = headHmdPosition;
    }
コード例 #7
0
    public void Update(FrameUpdateParameters updateParameters, ChannelInputs inputs)
    {
        headPositionForecaster.Update(updateParameters.Time, updateParameters.HeadPosition);
        var forecastHeadPosition = headPositionForecaster.Forecast;

        var outputs            = channelSystem.Evaluate(null, inputs);
        var neckTotalTransform = headBone.Parent.GetChainedTransform(outputs);

        var figureEyeCenter          = (leftEyeBone.CenterPoint.GetValue(outputs) + rightEyeBone.CenterPoint.GetValue(outputs)) / 2;
        var figureEyeWorldPosition   = neckTotalTransform.Transform(figureEyeCenter);
        var lookPointWorldPosition   = neckTotalTransform.Transform(figureEyeCenter + Vector3.BackwardRH);
        var lookWorldDirection       = Vector3.Normalize(lookPointWorldPosition - figureEyeWorldPosition);
        var targetLookWorldDirection = Vector3.Normalize(forecastHeadPosition * 100 - figureEyeWorldPosition);

        var worldRotationCorrection = QuaternionExtensions.RotateBetween(lookWorldDirection, targetLookWorldDirection);

        var targetLocalRotationCorrection = Quaternion.Invert(neckTotalTransform.RotationStage.Rotation) * worldRotationCorrection * neckTotalTransform.RotationStage.Rotation;

        headBone.SetEffectiveRotation(inputs, outputs, targetLocalRotationCorrection);
    }
コード例 #8
0
    public void Run()
    {
        var outputs = channelSystem.Evaluate(null, inputs);

        var stopwatch  = Stopwatch.StartNew();
        int trialCount = 0;

        while (true)
        {
            boneSystem.GetBoneTransforms(outputs);

            trialCount += 1;
            if (trialCount == 1000)
            {
                Console.WriteLine(stopwatch.Elapsed.TotalMilliseconds / trialCount);

                trialCount = 0;
                stopwatch.Restart();
            }
        }
    }
コード例 #9
0
 public ChannelOutputs Evaluate(ChannelOutputs parentOutputs, ChannelInputs inputs)
 {
     return(channelSystem.Evaluate(parentOutputs, inputs));
 }