Пример #1
0
    private void ImportOperation(SplineOperationBuilder splineOperationBuilder, List <OperationRecipe> operations, DsonTypes.DsonDocument doc, DsonTypes.Operation operation)
    {
        if (operation.op == DsonTypes.Operator.Push)
        {
            if (operation.url != null)
            {
                splineOperationBuilder.ConfirmInactive();
                string channelRef = ConvertChannelUri(doc, operation.url);
                operations.Add(OperationRecipe.MakePushChannel(channelRef));
            }
            else
            {
                Object val = operation.val;
                switch (val)
                {
                case JArray arrayValue:
                    float[] values = arrayValue.ToObject <float[]>();
                    splineOperationBuilder.AddValueArray(values);
                    break;

                default:
                    if (splineOperationBuilder.Active)
                    {
                        splineOperationBuilder.AddSize(Convert.ToInt32(operation.val));
                    }
                    else
                    {
                        float value = Convert.ToSingle(operation.val);
                        operations.Add(OperationRecipe.MakePushConstant(value));
                    }
                    break;
                }
            }
        }
        else if (operation.op == DsonTypes.Operator.Add)
        {
            splineOperationBuilder.ConfirmInactive();
            operations.Add(OperationRecipe.Make(OperationRecipe.OperationKind.Add));
        }
        else if (operation.op == DsonTypes.Operator.Sub)
        {
            splineOperationBuilder.ConfirmInactive();
            operations.Add(OperationRecipe.Make(OperationRecipe.OperationKind.Sub));
        }
        else if (operation.op == DsonTypes.Operator.Mult)
        {
            splineOperationBuilder.ConfirmInactive();
            operations.Add(OperationRecipe.Make(OperationRecipe.OperationKind.Mul));
        }
        else if (operation.op == DsonTypes.Operator.Div)
        {
            splineOperationBuilder.ConfirmInactive();
            operations.Add(OperationRecipe.Make(OperationRecipe.OperationKind.Div));
        }
        else if (operation.op == DsonTypes.Operator.SplineTcb)
        {
            operations.Add(splineOperationBuilder.Build());
        }
    }
Пример #2
0
    public FormulaRecipe SynthesizeFormula()
    {
        var rootBoneScaleChannelName = bones[0].Name + "?scale/general";

        return(new FormulaRecipe {
            Output = rootBoneScaleChannelName,
            Stage = FormulaRecipe.FormulaStage.Multiply,
            Operations = new List <OperationRecipe> {
                OperationRecipe.MakePushChannel(ChannelName),
                OperationRecipe.MakePushConstant(1),
                OperationRecipe.Make(OperationRecipe.OperationKind.Add)
            }
        });
    }
    private List <MorphRecipe> MergeMorphs(List <FormulaRecipe> mergedFormulas)
    {
        var parentMorphsByName = parent.Morphs.ToDictionary(morph => morph.Channel, morph => morph);
        var childMorphsByName  = children.Select(child => child.Morphs.ToDictionary(morph => morph.Channel, morph => morph)).ToList();

        var allMorphNames = parentMorphsByName.Keys.Concat(childMorphsByName.SelectMany(dict => dict.Keys)).Distinct().ToList();

        var childAutomorphers = children.Select(child => child.Automorpher).ToArray();

        List <MorphRecipe> mergedMorphs = new List <MorphRecipe>();

        foreach (string morphName in allMorphNames)
        {
            parentMorphsByName.TryGetValue(morphName, out var parentMorph);

            var childMorphs = new MorphRecipe[childMorphsByName.Count];
            for (int childIdx = 0; childIdx < childMorphsByName.Count; ++childIdx)
            {
                childMorphsByName[childIdx].TryGetValue(morphName, out childMorphs[childIdx]);
            }

            var mergedMorph = MorphRecipe.Merge(morphName, reindexer, parentMorph, childMorphs, childAutomorphers);
            mergedMorphs.Add(mergedMorph);
        }

        for (int childIdx = 0; childIdx < children.Length; ++childIdx)
        {
            var    child               = children[childIdx];
            int    childVertexOffset   = reindexer.ChildOffsets[childIdx].Vertex;
            string childControlChannel = childControlChannels[childIdx].Name;

            //Add a morph that moves each child vertex from the parent surface to its active position
            mergedMorphs.Add(child.Automorpher.GenerateGraftControlMorph(childControlChannel, childVertexOffset, child.Geometry));

            //Add a formula that disables each child morph when when the child control channel is 0
            foreach (var childMorph in child.Morphs)
            {
                if (parentMorphsByName.ContainsKey(childMorph.Channel))
                {
                    /*
                     * Skip child morphs that are following a parent morph.
                     *
                     * In principle, I should disable these to and replace them with automorpher-generated
                     * morphs. But in practice, these morphs are already very similar to the automorphs so it's
                     * OK to leave them as is.
                     */
                    continue;
                }

                mergedFormulas.Add(new FormulaRecipe {
                    Output     = childMorph.Channel,
                    Stage      = FormulaRecipe.FormulaStage.Multiply,
                    Operations = new List <OperationRecipe> {
                        OperationRecipe.MakePushChannel(childControlChannel)
                    }
                });
            }
        }

        return(mergedMorphs);
    }