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)); }
/** * 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 }); }