コード例 #1
0
    public void TestTransformConsistency()
    {
        var builder       = new BoneSystemBuilder();
        var bone0         = builder.AddBone("bone0", null, new Vector3(1, 0, 0), new Vector3(2, 0, 0), Vector3.Zero);
        var bone1         = builder.AddBone("bone1", bone0, new Vector3(2, 0, 0), new Vector3(3, 0, 0), Vector3.Zero);
        var bone2         = builder.AddBone("bone2", bone1, new Vector3(3, 0, 0), new Vector3(4, 0, 0), Vector3.Zero);
        var channelSystem = builder.BuildChannelSystem();
        var boneSystem    = builder.BuildBoneSystem();

        var rigidBoneSystem = new RigidBoneSystem(boneSystem);

        var baseInputs = channelSystem.MakeDefaultChannelInputs();

        bone1.Scale.SetValue(baseInputs, new Vector3(2, 3, 4));
        bone1.Translation.SetValue(baseInputs, new Vector3(4, 5, 6));
        bone2.Translation.SetValue(baseInputs, new Vector3(5, 6, 7));

        var baseOutputs = channelSystem.Evaluate(null, baseInputs);

        rigidBoneSystem.Synchronize(baseOutputs);
        var rigidBaseInputs = rigidBoneSystem.ReadInputs(baseOutputs);

        var rigidInputs = new RigidBoneSystemInputs(rigidBaseInputs);

        rigidBoneSystem.Bones[0].SetRotation(rigidInputs, Quaternion.RotationYawPitchRoll(0.1f, 0.2f, 0.3f));
        rigidBoneSystem.Bones[1].SetRotation(rigidInputs, Quaternion.RotationYawPitchRoll(0.2f, 0.3f, 0.4f));
        rigidBoneSystem.Bones[2].SetRotation(rigidInputs, Quaternion.RotationYawPitchRoll(0.3f, 0.4f, 0.5f));

        var inputs = new ChannelInputs(baseInputs);

        rigidBoneSystem.WriteInputs(inputs, baseOutputs, rigidInputs);
        var outputs = channelSystem.Evaluate(null, inputs);

        var baseTransforms = boneSystem.GetBoneTransforms(baseOutputs);
        var transforms     = boneSystem.GetBoneTransforms(outputs);

        var rigidBaseTransforms = rigidBoneSystem.GetBoneTransforms(rigidBaseInputs);
        var rigidTransforms     = rigidBoneSystem.GetBoneTransforms(rigidInputs);

        for (int transformIdx = 0; transformIdx < transforms.Length; ++transformIdx)
        {
            var baseTransform = baseTransforms[transformIdx];
            var transform     = transforms[transformIdx];

            var rigidBaseTransform = rigidBaseTransforms[transformIdx];
            var rigidTransform     = rigidTransforms[transformIdx];

            foreach (var testPoint in new [] { Vector3.Zero, Vector3.UnitX, Vector3.UnitY, Vector3.UnitZ })
            {
                var unposedPoint = baseTransform.InverseTransform(testPoint);
                var posedPoint   = transform.Transform(unposedPoint);

                var unposedRigidPoint = rigidBaseTransform.InverseTransform(testPoint);
                var posedRigidPoint   = rigidTransform.Transform(unposedRigidPoint);

                float distance = Vector3.Distance(posedPoint, posedRigidPoint);
                Assert.AreEqual(0, distance, 1e-3);
            }
        }
    }
    public NormalMapRenderer MakeNormalMapRenderer(Figure figureWithGrafts, UvSet uvSetWithGrafts, ChannelInputs shapeInputsWithGrafts)
    {
        /*
         * HUGE HACKS:
         * This class only works on figures without grafts whereas everything else works on figures with grafts.
         * So I have to convert the uvSet and shapeInputs the with-grafts figure to the without-grafts figure.
         */

        var uvSet = figure.UvSets[uvSetWithGrafts.Name];

        ChannelInputs ldInputs = figure.MakeDefaultChannelInputs();
        ChannelInputs hdInputs = figure.MakeDefaultChannelInputs();

        string hdCorrectionMorphChannelName = HdCorrectionMorphSynthesizer.CalcChannelName(figure.Name);

        foreach (var channel in figure.Channels)
        {
            var channelWithGrafts = figureWithGrafts.ChannelsByName[channel.Name];

            double value = channelWithGrafts.GetInputValue(shapeInputsWithGrafts);
            channel.SetValue(ldInputs, value);
            if (channel.Name != hdCorrectionMorphChannelName)
            {
                channel.SetValue(hdInputs, value);
            }
        }

        return(MakeNormalMapRenderer(ldInputs, hdInputs, uvSet));
    }
コード例 #3
0
    private void DumpInputs(DirectoryInfo shapeDirectory, ChannelInputs shapeInputs)
    {
        FileInfo shapeFile = shapeDirectory.File("channel-inputs.dat");

        if (shapeFile.Exists)
        {
            return;
        }

        //persist
        Dictionary <string, double> shapeInputsByName = new Dictionary <string, double>();

        foreach (var channel in figure.Channels)
        {
            double defaultValue = channel.InitialValue;
            double value        = channel.GetInputValue(shapeInputs);
            if (value != defaultValue)
            {
                shapeInputsByName.Add(channel.Name, value);
            }
        }

        shapeDirectory.CreateWithParents();
        Persistance.Save(shapeFile, shapeInputsByName);
    }
コード例 #4
0
    public void Update(FrameUpdateParameters updateParameters, ChannelInputs inputs)
    {
        double elapsed = updateParameters.TimeDelta;

        if (blinking)
        {
            eyesClosedAmount += elapsed / CloseDuration;
            if (eyesClosedAmount < MaximumCloseAmount)
            {
                elapsed = 0;
            }
            else
            {
                //set elapsed to time remaining after close completion
                elapsed            = (eyesClosedAmount - 1) * CloseDuration;      //set elapsed to time as
                eyesClosedAmount   = 1;
                blinking           = false;
                timeUntilNextBlink = GenerateTimeUntilNextBlink();
            }
        }

        if (!blinking)
        {
            eyesClosedAmount *= Math.Pow(0.5, elapsed / OpenHalflife);

            timeUntilNextBlink -= elapsed;
            if (timeUntilNextBlink < 0)
            {
                blinking = true;
            }
        }

        eyesClosedChannel.SetValue(inputs, MaximumCloseAmount * eyesClosedAmount);
    }
コード例 #5
0
 public Shape(string label, IArchiveDirectory directory, ChannelInputs channelInputs, ParentOverride[] parentOverrides)
 {
     Label           = label;
     Directory       = directory;
     ChannelInputs   = channelInputs;
     ParentOverrides = parentOverrides;
 }
 public void Update(FrameUpdateParameters updateParameters, ChannelInputs inputs)
 {
     foreach (var animator in animators)
     {
         animator.Update(updateParameters, inputs);
     }
 }
コード例 #7
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);
    }
コード例 #8
0
 public ChannelInputsGroup(ChannelInputsGroup group)
 {
     ParentInputs = new ChannelInputs(group.ParentInputs);
     ChildInputs  = group.ChildInputs
                    .Select(inputs => new ChannelInputs(inputs))
                    .ToArray();
 }
コード例 #9
0
 public Vector3 GetInputValue(ChannelInputs inputs)
 {
     return(new Vector3(
                (float)X.GetInputValue(inputs),
                (float)Y.GetInputValue(inputs),
                (float)Z.GetInputValue(inputs)
                ));
 }
コード例 #10
0
    public ChannelOutputs Evaluate(ChannelOutputs parentOutputs, ChannelInputs inputs)
    {
        double[] valuesOut = new double[channelCount];

        eval(parentOutputs?.Values, inputs.RawValues, valuesOut, splines);

        return(new ChannelOutputs(parentOutputs, valuesOut));
    }
コード例 #11
0
    public OccluderParametersCalculator(ContentFileLocator fileLocator, Device device, ShaderCache shaderCache, Figure figure, float[] faceTransparencies, ChannelInputs shapeInputs)
    {
        this.figure      = figure;
        this.shapeInputs = shapeInputs;
        figureGroup      = new FigureGroup(figure);
        var faceTransparenciesGroup = new FaceTransparenciesGroup(faceTransparencies);

        occlusionCalculator = new FigureOcclusionCalculator(fileLocator, device, shaderCache, figureGroup, faceTransparenciesGroup);
    }
コード例 #12
0
    private ChannelInputs MakePosedShapeInputs()
    {
        var inputs = new ChannelInputs(shapeInputs);

        figure.ChannelsByName["pCTRLArmsUpDwn?value"].SetValue(inputs, -1 / 4d);
        figure.ChannelsByName["pCTRLArmsFrntBck?value"].SetValue(inputs, 1 / 4d);
        figure.ChannelsByName["pCTRLKneesUp?value"].SetValue(inputs, 1 / 4d);
        figure.ChannelsByName["pCTRLLegsOut?value"].SetValue(inputs, 1 / 4d);
        return(inputs);
    }
コード例 #13
0
 public void WriteInputs(ChannelInputs channelInputs, ChannelOutputs channelOutputs, RigidBoneSystemInputs inputs)
 {
     source.RootBone.Translation.SetEffectiveValue(channelInputs, channelOutputs, inputs.RootTranslation, SetMask.ApplyClampAndVisibleOnly);
     for (int boneIdx = 0; boneIdx < bones.Length; ++boneIdx)
     {
         var bone           = bones[boneIdx];
         var rotation       = inputs.Rotations[boneIdx];
         var rotationAngles = MathExtensions.RadiansToDegrees(bone.RotationOrder.ToTwistSwingAngles(rotation));
         bone.Source.Rotation.SetEffectiveValue(channelInputs, channelOutputs, rotationAngles, SetMask.ApplyClampAndVisibleOnly);
     }
 }
コード例 #14
0
 public void BlendIn(ChannelInputs inputs, float weight)
 {
     if (inputs.RawValues.Length != this.RawValues.Length)
     {
         throw new ArgumentException("length mismatch");
     }
     for (int i = 0; i < RawValues.Length; ++i)
     {
         RawValues[i] += weight * inputs.RawValues[i];
     }
 }
コード例 #15
0
    public void ApplyOverrides(ChannelInputs parentInputs)
    {
        if (ParentOverrides == null)
        {
            return;
        }

        foreach (var parentOverride in ParentOverrides)
        {
            parentOverride.channel.SetValue(parentInputs, parentOverride.value);
        }
    }
コード例 #16
0
ファイル: ActorModel.cs プロジェクト: smygarn/virtually-naked
    public ActorModel(FigureDefinition mainDefinition, AnimationModel animation, BehaviorModel behavior)
    {
        this.mainDefinition = mainDefinition;

        this.animation = animation;
        this.behavior  = behavior;

        inputs = mainDefinition.ChannelSystem.MakeZeroChannelInputs();

        //hack to turn on eCTRLConfident at start
        mainDefinition.ChannelSystem.ChannelsByName["eCTRLConfident?value"].SetValue(inputs, 1);
    }
コード例 #17
0
    public void TestRawValue()
    {
        Channel        channel  = new Channel("foo", 0, null, 0, 0, 0, false, false, null);
        List <Channel> channels = new List <Channel> {
            channel
        };
        var evaluator = new ChannelEvaluator(channels);
        var inputs    = new ChannelInputs(new double[] { 42 });
        var outputs   = evaluator.Evaluate(null, inputs);

        Assert.AreEqual(42, outputs.Values[0], Acc);
    }
コード例 #18
0
    private void DumpSimpleOcclusion(DirectoryInfo shapeDirectory, ChannelInputs shapeInputs, float[] faceTransparencies)
    {
        FileInfo occlusionInfosFile       = shapeDirectory.File("occlusion-infos.array");
        FileInfo parentOcclusionInfosFile = shapeDirectory.File("parent-occlusion-infos.array");

        if (occlusionInfosFile.Exists)
        {
            return;
        }

        Console.WriteLine("Calculating occlusion...");

        if (faceTransparencies == null)
        {
            faceTransparencies = FaceTransparencies.For(figure);
        }

        FigureGroup             figureGroup;
        FaceTransparenciesGroup faceTransparenciesGroup;

        if (figure == parentFigure)
        {
            figureGroup             = new FigureGroup(figure);
            faceTransparenciesGroup = new FaceTransparenciesGroup(faceTransparencies);
        }
        else
        {
            var parentFaceTransparencies = FaceTransparencies.For(parentFigure);

            figureGroup             = new FigureGroup(parentFigure, figure);
            faceTransparenciesGroup = new FaceTransparenciesGroup(parentFaceTransparencies, faceTransparencies);
        }

        var inputs  = new ChannelInputsGroup(parentFigure.MakeDefaultChannelInputs(), new ChannelInputs[] { shapeInputs });
        var outputs = figureGroup.Evaluate(inputs);

        FigureOcclusionCalculator.Result occlusionResult;
        using (var occlusionCalculator = new FigureOcclusionCalculator(fileLocator, device, shaderCache, figureGroup, faceTransparenciesGroup)) {
            occlusionResult = occlusionCalculator.CalculateOcclusionInformation(outputs);
        }

        shapeDirectory.Create();
        if (figure == parentFigure)
        {
            occlusionInfosFile.WriteArray(OcclusionInfo.PackArray(occlusionResult.ParentOcclusion));
        }
        else
        {
            occlusionInfosFile.WriteArray(OcclusionInfo.PackArray(occlusionResult.ChildOcclusions[0]));
            parentOcclusionInfosFile.WriteArray(OcclusionInfo.PackArray(occlusionResult.ParentOcclusion));
        }
    }
コード例 #19
0
    public void SetValue(ChannelInputs inputs, double value, SetMask mask = SetMask.Any)
    {
        if (Locked)
        {
            return;
        }
        if (mask.HasFlag(SetMask.ApplyClamp) && Clamped)
        {
            value = EvaluatorHelperMethods.Clamp(value, Min, Max);
        }

        inputs.RawValues[this.Index] = value;
    }
コード例 #20
0
    public void Apply(ChannelInputs inputs, Pose pose, DualQuaternion rootTransform)
    {
        foreach (Bone bone in boneSystem.Bones)
        {
            bone.AddRotation(orientationOutputs, inputs, pose.BoneRotations[bone.Index]);
        }

        var rescaledRootTransform = DualQuaternion.FromRotationTranslation(rootTransform.Rotation, rootTransform.Translation * 100);

        boneSystem.RootBone.SetRotation(orientationOutputs, inputs, rescaledRootTransform.Rotation);
        boneSystem.RootBone.SetTranslation(inputs, rescaledRootTransform.Translation);

        boneSystem.Bones[1].SetTranslation(inputs, pose.RootTranslation);
    }
コード例 #21
0
    private static ChannelInputs LoadChannelInputs(ChannelSystem channelSystem, IArchiveFile channelInputsFile)
    {
        var shapeInputsByName = Persistance.Load <Dictionary <string, double> >(channelInputsFile);

        ChannelInputs channelInputs = channelSystem.MakeDefaultChannelInputs();

        foreach (var entry in shapeInputsByName)
        {
            Channel channel = channelSystem.ChannelsByName[entry.Key];
            channel.SetValue(channelInputs, entry.Value);
        }

        return(channelInputs);
    }
コード例 #22
0
    private void AssertFormulaEquals(double expectedResult, Formula formula)
    {
        Channel channel = new Channel("foo", 0, null, 0, 0, 0, false, false, null);

        channel.AttachSumFormula(formula);
        List <Channel> channels = new List <Channel> {
            channel
        };
        var evaluator = new ChannelEvaluator(channels);
        var inputs    = new ChannelInputs(new double[] { 0 });
        var outputs   = evaluator.Evaluate(null, inputs);

        Assert.AreEqual(expectedResult, outputs.Values[0], Acc);
    }
    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);
    }
コード例 #24
0
    public void SetEffectiveValue(ChannelInputs inputs, ChannelOutputs outputsForDelta, double value, SetMask mask = SetMask.Any)
    {
        if (Locked)
        {
            return;
        }

        if (mask.HasFlag(SetMask.ApplyClamp) && Clamped)
        {
            value = EvaluatorHelperMethods.Clamp(value, Min, Max);
        }

        double delta = value - outputsForDelta.Values[this.Index];

        inputs.RawValues[this.Index] += delta;
    }
コード例 #25
0
    public BoneSystemPerformanceDemo()
    {
        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 pose = Persistance.Load <List <Pose> >(figureDir.File("animations/idle.dat"))[0];

        inputs = channelSystem.MakeDefaultChannelInputs();
        new Poser(channelSystem, boneSystem).Apply(inputs, pose, DualQuaternion.Identity);
    }
コード例 #26
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;
    }
コード例 #27
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);
    }
コード例 #28
0
    public void Update(FrameUpdateParameters updateParameters, ChannelInputs inputs)
    {
        Update3dAudioPosition(updateParameters, inputs);

        currentTime = updateParameters.Time;
        if (synth.State == SynthesizerState.Ready)
        {
            synth.SpeakAsync(Text);
        }

        float visimeProgress = MathUtil.Clamp((updateParameters.Time - visemeStartTime) / visemeDuration, 0, 1);

        Channel currentChannel = visemeChannels[currentViseme];
        Channel nextChannel    = visemeChannels[nextViseme];

        currentChannel?.SetValue(inputs, 1 - visimeProgress);
        nextChannel?.SetValue(inputs, visimeProgress);
    }
コード例 #29
0
    public OccluderParameters CalculateOccluderParameters()
    {
        var baseInputs         = MakePosedShapeInputs();
        var baseOutputs        = figure.Evaluate(null, baseInputs);
        var baseOcclusionInfos = CalculateOcclusion(baseOutputs);

        List <Channel> channels = new List <Channel>();
        List <List <OcclusionDelta> > perVertexDeltas = new List <List <OcclusionDelta> >();

        for (int i = 0; i < baseOcclusionInfos.Length; ++i)
        {
            perVertexDeltas.Add(new List <OcclusionDelta>());
        }

        foreach (var channel in GetChannelsForOcclusionSystem())
        {
            Console.WriteLine($"\t{channel.Name}...");

            int occlusionChannelIdx = channels.Count;
            channels.Add(channel);

            var inputs = new ChannelInputs(baseInputs);
            channel.SetValue(inputs, 1);
            var outputs        = figure.Evaluate(null, inputs);
            var occlusionInfos = CalculateOcclusion(outputs);

            for (int vertexIdx = 0; vertexIdx < occlusionInfos.Length; ++vertexIdx)
            {
                if (Math.Abs(occlusionInfos[vertexIdx].Front - baseOcclusionInfos[vertexIdx].Front) > OcclusionDifferenceThreshold)
                {
                    var delta = new OcclusionDelta(occlusionChannelIdx, OcclusionInfo.Pack(occlusionInfos[vertexIdx]));
                    perVertexDeltas[vertexIdx].Add(delta);
                }
            }
        }

        var parameters = new OccluderParameters(
            OcclusionInfo.PackArray(baseOcclusionInfos),
            channels.Select(channel => channel.Name).ToList(),
            PackedLists <OcclusionDelta> .Pack(perVertexDeltas));

        return(parameters);
    }
コード例 #30
0
    public void TestPushChannel()
    {
        Channel channel0 = new Channel("foo", 0, null, 0, 0, 0, false, false, null);
        Channel channel1 = new Channel("bar", 1, null, 0, 0, 0, false, false, null);

        channel0.AttachSumFormula(new Formula(new IOperation[] {
            new PushChannelOperation(channel1)
        }));

        List <Channel> channels = new List <Channel> {
            channel0, channel1
        };

        var evaluator = new ChannelEvaluator(channels);
        var inputs    = new ChannelInputs(new double[] { 0, 42 });
        var outputs   = evaluator.Evaluate(null, inputs);

        Assert.AreEqual(42, outputs.Values[0], Acc);
    }