private GeometryRecipe MergeGeometry()
    {
        var childGeometries   = children.Select(child => child.Geometry).ToArray();
        var childAutomorphers = children.Select(child => child.Automorpher).ToArray();

        return(GeometryRecipe.Merge(
                   reindexer,
                   parent.Geometry,
                   childGeometries, childAutomorphers));
    }
    public FigureRecipe Merge()
    {
        GeometryRecipe       mergedGeometry    = MergeGeometry();
        List <ChannelRecipe> mergedChannels    = MergeChannels();
        List <FormulaRecipe> mergedFormulas    = MergeFormulas();
        List <BoneRecipe>    mergedBones       = MergeBones();
        List <MorphRecipe>   mergedMorphs      = MergeMorphs(mergedFormulas);
        AutomorpherRecipe    mergedAutomorpher = MergeAutomorpher();
        SkinBindingRecipe    mergedSkinBinding = MergeSkinBinding();
        List <UvSetRecipe>   mergedUvSets      = MergeUvSets();

        return(new FigureRecipe {
            Name = parent.Name,
            Geometry = mergedGeometry,
            Channels = mergedChannels,
            Formulas = mergedFormulas,
            Bones = mergedBones,
            Morphs = mergedMorphs,
            Automorpher = mergedAutomorpher,
            SkinBinding = mergedSkinBinding,
            UvSets = mergedUvSets
        });
    }
 public UvSetImporter(GeometryRecipe geometry)
 {
     this.geometry = geometry;
 }
    public static IEnumerable <UvSetRecipe> ImportForFigure(DsonObjectLocator locator, FigureUris figureUris, GeometryRecipe geometry)
    {
        UvSetImporter importer = new UvSetImporter(geometry);

        foreach (DsonTypes.DsonDocument doc in locator.GetAllDocumentsUnderPath(figureUris.UvSetsBasePath))
        {
            importer.ImportFrom(doc);
        }

        return(importer.Recipes);
    }
    public static GeometryRecipe Merge(FigureRecipeMerger.Reindexer reindexer, GeometryRecipe parent, GeometryRecipe[] children, AutomorpherRecipe[] childAutomorphers)
    {
        List <Quad>    mergedFaces           = new List <Quad>();
        List <int>     mergedFaceGroupMap    = new List <int>();
        List <int>     mergedSurfaceMap      = new List <int>();
        List <Vector3> mergedVertexPositions = new List <Vector3>();
        List <string>  mergedSurfaceNames    = new List <string>();

        for (int faceIdx = 0; faceIdx < parent.Faces.Length; faceIdx++)
        {
            if (reindexer.IsParentFaceHidden(faceIdx))
            {
                continue;
            }

            mergedFaces.Add(parent.Faces[faceIdx]);
            mergedFaceGroupMap.Add(parent.FaceGroupMap[faceIdx]);
            mergedSurfaceMap.Add(parent.SurfaceMap[faceIdx]);
        }

        mergedVertexPositions.AddRange(parent.VertexPositions);
        mergedSurfaceNames.AddRange(parent.SurfaceNames);

        for (int childIdx = 0; childIdx < children.Length; ++childIdx)
        {
            GeometryRecipe    child       = children[childIdx];
            AutomorpherRecipe automorpher = childAutomorphers[childIdx];

            Dictionary <int, int> graftVertexMap = new Dictionary <int, int>();
            if (child.Graft != null)
            {
                foreach (var pair in child.Graft.VertexPairs)
                {
                    graftVertexMap[pair.Source] = pair.Target;
                }
            }

            FigureRecipeMerger.Offset offset = reindexer.ChildOffsets[childIdx];

            if (child.Type != parent.Type)
            {
                throw new InvalidOperationException("children must have same geometry type as parent");
            }

            mergedSurfaceNames.AddRange(child.SurfaceNames);

            /*
             * Children start "turned off" so instead of adding the child's base vertex positions here, I add the
             * nearest positions on the parent's surface. Later I'll add a morph that moves the child vertices
             * into place.
             */
            mergedVertexPositions.AddRange(automorpher.ParentSurfacePositions);

            foreach (Quad face in child.Faces)
            {
                mergedFaces.Add(face.Map(idx => {
                    if (graftVertexMap.TryGetValue(idx, out int graftIdx))
                    {
                        return(graftIdx);
                    }
                    else
                    {
                        return(idx + offset.Vertex);
                    }
                }));
            }

            int[] childToParentFaceGroupIdx = new int[child.FaceGroupNames.Length];
            for (int childFaceGroupIdx = 0; childFaceGroupIdx < child.FaceGroupNames.Length; ++childFaceGroupIdx)
            {
                string faceGroupName      = child.FaceGroupNames[childFaceGroupIdx];
                int    parentFaceGroupIdx = Array.FindIndex(parent.FaceGroupNames, name => name == faceGroupName);
                childToParentFaceGroupIdx[childFaceGroupIdx] = parentFaceGroupIdx;
            }

            foreach (int childFaceGroupIdx in child.FaceGroupMap)
            {
                int parentFaceGroupIdx = childToParentFaceGroupIdx[0];
                mergedFaceGroupMap.Add(parentFaceGroupIdx);
            }

            foreach (int surfaceIdx in child.SurfaceMap)
            {
                mergedSurfaceMap.Add(surfaceIdx + offset.Surface);
            }
        }

        return(new GeometryRecipe(
                   parent.Type,
                   mergedFaces.ToArray(),
                   mergedFaceGroupMap.ToArray(),
                   mergedSurfaceMap.ToArray(),
                   mergedVertexPositions.ToArray(),
                   parent.FaceGroupNames,
                   mergedSurfaceNames.ToArray(),
                   parent.DefaultUvSet,
                   null));
    }
Example #6
0
    /**
     *  Generates a morph that moves each vertex from the surface of the parent to its base position. Intended to be used to "turn on" grafts.
     */
    public MorphRecipe GenerateGraftControlMorph(string channel, int childVertexOffset, GeometryRecipe childGeometry)
    {
        var childVertexPositions = childGeometry.VertexPositions;

        MorphDelta[] deltas = new MorphDelta[childVertexPositions.Length];
        for (int childVertexIdx = 0; childVertexIdx < childVertexPositions.Length; ++childVertexIdx)
        {
            var positionDelta = childVertexPositions[childVertexIdx] - ParentSurfacePositions[childVertexIdx];
            deltas[childVertexIdx] = new MorphDelta(childVertexIdx + childVertexOffset, positionDelta);
        }

        return(new MorphRecipe {
            Channel = channel,
            Deltas = deltas
        });
    }