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)); }
public void Dump(string name, UvSet uvSet) { DirectoryInfo uvSetDirectory = uvSetsDirectory.Subdirectory(name); if (uvSetDirectory.Exists) { return; } Console.WriteLine($"Dumping uv-set {name}..."); MultisurfaceQuadTopology spatialTopology = figure.Geometry.AsTopology(); MultisurfaceQuadTopology texturedControlTopology = ExtractTexturedTopology(spatialTopology, uvSet); var texturedRefinementResult = texturedControlTopology.Refine(surfaceProperties.SubdivisionLevel); var texturedTopology = texturedRefinementResult.Mesh.Topology; var texturedTopologyInfo = texturedRefinementResult.TopologyInfo; var derivStencils = texturedRefinementResult.Mesh.Stencils; var stencils = derivStencils.Map(stencil => new WeightedIndex(stencil.Index, stencil.Weight)); var duStencils = derivStencils.Map(stencil => new WeightedIndex(stencil.Index, stencil.DuWeight)); var dvStencils = derivStencils.Map(stencil => new WeightedIndex(stencil.Index, stencil.DvWeight)); Vector2[] controlTextureCoords = uvSet.Uvs; Vector2[] textureCoords = new Subdivider(stencils).Refine(controlTextureCoords, new Vector2Operators()); Vector2[] textureCoordDus = new Subdivider(duStencils).Refine(controlTextureCoords, new Vector2Operators()); Vector2[] textureCoordDvs = new Subdivider(dvStencils).Refine(controlTextureCoords, new Vector2Operators()); int[] spatialIdxMap = CalculateTextureToSpatialIndexMap(texturedTopology, spatialFaces); TexturedVertexInfo[] texturedVertexInfos = Enumerable.Range(0, textureCoords.Length) .Select(idx => { int spatialVertexIdx = spatialIdxMap[idx]; Vector2 textureCoord = textureCoords[idx]; Vector2 du = textureCoordDus[idx]; Vector2 dv = textureCoordDvs[idx]; List <int> spatialNeighbours = spatialTopologyInfo.AdjacentVertices.GetElements(spatialVertexIdx).ToList(); var spatialVertexRule = spatialTopologyInfo.VertexRules[spatialVertexIdx]; List <int> neighbours = texturedTopologyInfo.AdjacentVertices.GetElements(idx).Select(i => spatialIdxMap[i]).ToList(); var vertexRule = texturedTopologyInfo.VertexRules[idx]; Tuple <Vector2, Vector2> remappedTangents = RemapTangents(spatialNeighbours, spatialVertexRule, neighbours, vertexRule, du, dv); return(new TexturedVertexInfo( spatialVertexIdx, textureCoord, remappedTangents.Item1, remappedTangents.Item2)); }) .ToArray(); uvSetDirectory.CreateWithParents(); uvSetDirectory.File("textured-faces.array").WriteArray(texturedTopology.Faces); uvSetDirectory.File("textured-vertex-infos.array").WriteArray(texturedVertexInfos); }
public Figure Bake(Figure parentFigure) { if (Channels == null) { Channels = new List <ChannelRecipe>(); } if (Formulas == null) { Formulas = new List <FormulaRecipe>(); } if (Morphs == null) { Morphs = new List <MorphRecipe>(); } Geometry geometry = Geometry.Bake(); Dictionary <string, UvSet> uvSets = new Dictionary <string, UvSet>(); UvSets.ForEach(recipe => recipe.Bake(geometry, uvSets)); UvSet defaultUvSet = uvSets[Geometry.DefaultUvSet]; ChannelSystem channelSystem = new ChannelSystemRecipe(Channels, Formulas).Bake(parentFigure?.ChannelSystem); int graftVertexOffset = Geometry.VertexPositions.Length; List <MorphRecipe> rewrittenMorphRecipes = Automorpher != null?Automorpher.Rewrite(Morphs, parentFigure) : Morphs; List <Morph> morphs = rewrittenMorphRecipes.Select(recipe => recipe.Bake(channelSystem.ChannelsByName)).ToList(); Morpher morpher = new Morpher(morphs); Automorpher automorpher = Automorpher?.Bake(); BoneSystem selfBoneSystem = new BoneSystemRecipe(Bones).Bake(channelSystem.ChannelsByName); BoneSystem boneSystem; RigidTransform[] childToParentBindPoseTransforms; if (parentFigure != null) { boneSystem = parentFigure.BoneSystem; childToParentBindPoseTransforms = MakeChildToParentBindPoseTransforms(channelSystem, selfBoneSystem, boneSystem); } else { boneSystem = selfBoneSystem; childToParentBindPoseTransforms = null; } SkinBinding skinBinding = SkinBinding.Bake(boneSystem.BonesByName, selfBoneSystem.BonesByName); OcclusionBinding occlusionBinding = OcclusionBinding.MakeForFigure(Name, geometry, boneSystem, skinBinding); return(new Figure(Name, parentFigure, this, geometry, channelSystem, boneSystem, childToParentBindPoseTransforms, morpher, automorpher, skinBinding, uvSets, defaultUvSet, occlusionBinding)); }
private UvSet RemapToDefault(UvSet uvSet) { var defaultUvSet = figure.DefaultUvSet; var defaultUvSetTopology = new QuadTopology(defaultUvSet.Uvs.Length, defaultUvSet.Faces); var indexMap = QuadTopology.CalculateVertexIndexMap(defaultUvSetTopology, uvSet.Faces); Vector2[] remappedUvs = indexMap .Select(idx => uvSet.Uvs[idx]) .ToArray(); return(new UvSet(uvSet.Name, remappedUvs, defaultUvSet.Faces)); }
public Figure(string name, Figure parent, FigureRecipe recipe, Geometry geometry, ChannelSystem channelSystem, BoneSystem boneSystem, RigidTransform[] childToParentBindPoseTransforms, Morpher morpher, Automorpher automorpher, SkinBinding skinBinding, Dictionary <string, UvSet> uvSets, UvSet defaultUvSet, OcclusionBinding occlusionBinding) { this.name = name; this.parent = parent; this.recipe = recipe; this.geometry = geometry; this.channelSystem = channelSystem; this.boneSystem = boneSystem; this.childToParentBindPoseTransforms = childToParentBindPoseTransforms; this.morpher = morpher; this.automorpher = automorpher; this.skinBinding = skinBinding; this.uvSets = uvSets; this.defaultUvSet = defaultUvSet; this.occlusionBinding = occlusionBinding; }
public void Bake(Geometry geometry, Dictionary <string, UvSet> uvSets) { var uvSet = new UvSet(Name, Uvs, Faces); uvSets.Add(Name, uvSet); }
public static TextureMask Make(UvSet uvSet, int[] surfaceMap, int surfaceIdx) { return(new TextureMask(uvSet, surfaceMap, surfaceIdx)); }
public TextureMask(UvSet uvSet, int[] surfaceMap, int surfaceIdx) { this.uvSet = uvSet; this.surfaceMap = surfaceMap; surfaceIdxs.Add(surfaceIdx); }
private MultisurfaceQuadTopology ExtractTexturedTopology(MultisurfaceQuadTopology spatialTopology, UvSet uvSet) { Quad[] texuredFaces = uvSet.Faces; int texturedVertexCount = uvSet.Uvs.Length; return(new MultisurfaceQuadTopology( spatialTopology.Type, texturedVertexCount, spatialTopology.SurfaceCount, texuredFaces, spatialTopology.SurfaceMap)); }
public NormalMapRenderer MakeNormalMapRenderer(ChannelInputs ldChannelInputs, ChannelInputs hdChannelInputs, UvSet uvSet) { var ldChannelOutputs = figure.Evaluate(null, ldChannelInputs); var hdChannelOutputs = figure.Evaluate(null, hdChannelInputs); var ldControlPositions = figure.Geometry.VertexPositions.Select(p => p).ToArray(); figure.Morpher.Apply(ldChannelOutputs, ldControlPositions); var hdControlPositions = figure.Geometry.VertexPositions.Select(p => p).ToArray(); figure.Morpher.Apply(hdChannelOutputs, hdControlPositions); var activeHdMorphs = figure.Morpher.LoadActiveHdMorphs(hdChannelOutputs); int maxLevel = activeHdMorphs.Max(morph => morph.Morph.MaxLevel) + ExtraRefinementLevels; var controlTopology = new QuadTopology(figure.Geometry.VertexCount, figure.Geometry.Faces); var applier = HdMorphApplier.Make(controlTopology, hdControlPositions); var controlUvTopology = new QuadTopology(uvSet.Uvs.Length, uvSet.Faces); var controlUvs = uvSet.Uvs; var refinement = new Refinement(controlTopology, maxLevel); var uvRefinement = new Refinement(controlUvTopology, maxLevel, BoundaryInterpolation.EdgeAndCorner); var topology = controlTopology; var ldPositions = ldControlPositions; var hdPositions = hdControlPositions; var uvTopology = controlUvTopology; var uvs = controlUvs; var texturedLdPositions = ExtractTexturedPositions(topology, uvTopology, ldPositions); for (int levelIdx = 1; levelIdx <= maxLevel; ++levelIdx) { topology = refinement.GetTopology(levelIdx); ldPositions = refinement.Refine(levelIdx, ldPositions); hdPositions = refinement.Refine(levelIdx, hdPositions); foreach (var activeHdMorph in activeHdMorphs) { applier.Apply(activeHdMorph.Morph, activeHdMorph.Weight, levelIdx, topology, hdPositions); } uvTopology = uvRefinement.GetTopology(levelIdx); uvs = uvRefinement.Refine(levelIdx, uvs); texturedLdPositions = uvRefinement.Refine(levelIdx, texturedLdPositions); } var ldLimit = refinement.Limit(ldPositions); var hdLimit = refinement.Limit(hdPositions); var uvLimit = uvRefinement.Limit(uvs); var texturedLdLimit = uvRefinement.Limit(texturedLdPositions); int[] faceMap = refinement.GetFaceMap(); refinement.Dispose(); uvRefinement.Dispose(); var hdNormals = CalculateNormals(hdLimit); var ldNormals = CalculateNormals(ldLimit); var ldTangents = CalculateTangents(uvLimit, texturedLdLimit); int[] controlSurfaceMap = figure.Geometry.SurfaceMap; int[] surfaceMap = faceMap .Select(controlFaceIdx => controlSurfaceMap[controlFaceIdx]) .ToArray(); var renderer = new NormalMapRenderer(device, shaderCache, hdNormals, ldNormals, topology.Faces, uvLimit.values, ldTangents, uvTopology.Faces, surfaceMap); return(renderer); }
public void Dump(string name, UvSet uvSet) { DirectoryInfo uvSetDirectory = uvSetsDirectory.Subdirectory(name); if (uvSetDirectory.Exists) { return; } Console.WriteLine($"Dumping uv-set {name}..."); int subdivisionLevel = surfaceProperties.SubdivisionLevel; var geometry = figure.Geometry; var spatialControlTopology = new QuadTopology(geometry.VertexCount, geometry.Faces); var spatialControlPositions = geometry.VertexPositions; QuadTopology spatialTopology; LimitValues <Vector3> spatialLimitPositions; using (var refinement = new Refinement(spatialControlTopology, subdivisionLevel)) { spatialTopology = refinement.GetTopology(); spatialLimitPositions = refinement.LimitFully(spatialControlPositions); } uvSet = RemapToDefault(uvSet); var texturedControlTopology = new QuadTopology(uvSet.Uvs.Length, uvSet.Faces); Vector2[] controlTextureCoords = uvSet.Uvs; int[] controlSpatialIdxMap = QuadTopology.CalculateVertexIndexMap(texturedControlTopology, spatialControlTopology.Faces); Vector3[] texturedControlPositions = controlSpatialIdxMap .Select(spatialIdx => spatialControlPositions[spatialIdx]) .ToArray(); QuadTopology texturedTopology; LimitValues <Vector3> texturedLimitPositions; LimitValues <Vector2> limitTextureCoords; using (var refinement = new Refinement(texturedControlTopology, surfaceProperties.SubdivisionLevel, BoundaryInterpolation.EdgeAndCorner)) { texturedTopology = refinement.GetTopology(); texturedLimitPositions = refinement.LimitFully(texturedControlPositions); limitTextureCoords = refinement.LimitFully(controlTextureCoords); } Vector2[] textureCoords; if (geometry.Type == GeometryType.SubdivisionSurface) { textureCoords = limitTextureCoords.values; } else { if (subdivisionLevel != 0) { throw new InvalidOperationException("polygon meshes cannot be subdivided"); } Debug.Assert(limitTextureCoords.values.Length == controlTextureCoords.Length); textureCoords = controlTextureCoords; } int[] spatialIdxMap = QuadTopology.CalculateVertexIndexMap(texturedTopology, spatialTopology.Faces); TexturedVertexInfo[] texturedVertexInfos = Enumerable.Range(0, textureCoords.Length) .Select(idx => { int spatialVertexIdx = spatialIdxMap[idx]; Vector2 textureCoord = textureCoords[idx]; Vector3 positionDu = TangentSpaceUtilities.CalculatePositionDu( limitTextureCoords.tangents1[idx], limitTextureCoords.tangents2[idx], texturedLimitPositions.tangents1[idx], texturedLimitPositions.tangents2[idx]); Vector3 spatialPositionTan1 = spatialLimitPositions.tangents1[spatialVertexIdx]; Vector3 spatialPositionTan2 = spatialLimitPositions.tangents2[spatialVertexIdx]; Vector2 tangentUCoeffs = TangentSpaceUtilities.CalculateTangentSpaceRemappingCoeffs(spatialPositionTan1, spatialPositionTan2, positionDu); DebugUtilities.AssertFinite(tangentUCoeffs.X); DebugUtilities.AssertFinite(tangentUCoeffs.Y); return(new TexturedVertexInfo( textureCoord, tangentUCoeffs)); }) .ToArray(); uvSetDirectory.CreateWithParents(); uvSetDirectory.File("textured-vertex-infos.array").WriteArray(texturedVertexInfos); }