public ArraySegment Add(ImporterOcclusionSurrogate surrogate) { int dummyVertexCount = surrogate.SampleCount; var dummyMesh = new SubdivisionMesh( 0, new QuadTopology(dummyVertexCount, new Quad[0]), PackedLists <WeightedIndexWithDerivatives> .MakeEmptyLists(dummyVertexCount)); var dummyFaceTransparencies = new float[0]; var segment = Add(dummyMesh, dummyFaceTransparencies); //apply mask int maskIdx = nextMaskIdx++; uint mask = 1u << maskIdx; for (int i = 0; i < segment.Count; ++i) { int vertexIdx = i + segment.Offset; vertexMasks[vertexIdx] |= mask; } foreach (int faceIdx in surrogate.AttachedFaces) { faceMasks[faceIdx] |= mask; } return(segment); }
public FigureRenderer Load(IArchiveDirectory figureDir, MaterialSetAndVariantOption materialSetOption) { SurfaceProperties surfaceProperties = Persistance.Load <SurfaceProperties>(figureDir.File("surface-properties.dat")); var refinementDirectory = figureDir.Subdirectory("refinement"); var controlMeshDirectory = refinementDirectory.Subdirectory("control"); int[] surfaceMap = controlMeshDirectory.File("surface-map.array").ReadArray <int>(); var refinedMeshDirectory = refinementDirectory.Subdirectory("level-" + surfaceProperties.SubdivisionLevel); SubdivisionMesh mesh = SubdivisionMeshPersistance.Load(refinedMeshDirectory); int[] controlFaceMap = refinedMeshDirectory.File("control-face-map.array").ReadArray <int>(); var materialSet = MaterialSet.LoadActive(device, shaderCache, textureCache, dataDir, figureDir, materialSetOption, surfaceProperties); var materials = materialSet.Materials; Scatterer scatterer = surfaceProperties.PrecomputeScattering ? Scatterer.Load(device, shaderCache, figureDir, materialSetOption.MaterialSet.Label) : null; var uvSetName = materials[0].UvSet; IArchiveDirectory uvSetDirectory = figureDir.Subdirectory("uv-sets").Subdirectory(uvSetName); var texturedVertexInfos = uvSetDirectory.File("textured-vertex-infos.array").ReadArray <TexturedVertexInfo>(); Quad[] texturedFaces = uvSetDirectory.File("textured-faces.array").ReadArray <Quad>(); var vertexRefiner = new VertexRefiner(device, shaderCache, mesh, texturedVertexInfos); FigureSurface[] surfaces = FigureSurface.MakeSurfaces(device, materials.Length, texturedFaces, controlFaceMap, surfaceMap, materialSet.FaceTransparencies); HashSet <int> visitedSurfaceIndices = new HashSet <int>(); List <int> surfaceOrder = new List <int>(surfaces.Length); bool[] areUnorderedTransparent = new bool[surfaces.Length]; //first add surfaces with an explicity-set render order foreach (int surfaceIdx in surfaceProperties.RenderOrder) { visitedSurfaceIndices.Add(surfaceIdx); surfaceOrder.Add(surfaceIdx); areUnorderedTransparent[surfaceIdx] = false; } //then add any remaining surfaces for (int surfaceIdx = 0; surfaceIdx < surfaces.Length; ++surfaceIdx) { if (visitedSurfaceIndices.Contains(surfaceIdx)) { continue; } surfaceOrder.Add(surfaceIdx); areUnorderedTransparent[surfaceIdx] = true; } var isOneSided = figureDir.Name == "genesis-3-female"; //hack return(new FigureRenderer(device, shaderCache, scatterer, vertexRefiner, materialSet, surfaces, isOneSided, surfaceOrder.ToArray(), areUnorderedTransparent)); }
private static void Subdivide(SubdivisionMesh subdivisionMesh, TriangleIndicesUnsignedInt triangle, int level) { if (level > 0) { IList <Vector3D> positions = subdivisionMesh.Positions; Vector3D n01 = ((positions[triangle.I0] + positions[triangle.I1]) * 0.5).Normalize(); Vector3D n12 = ((positions[triangle.I1] + positions[triangle.I2]) * 0.5).Normalize(); Vector3D n20 = ((positions[triangle.I2] + positions[triangle.I0]) * 0.5).Normalize(); Vector3D p01 = n01.MultiplyComponents(subdivisionMesh.Ellipsoid.Radii); Vector3D p12 = n12.MultiplyComponents(subdivisionMesh.Ellipsoid.Radii); Vector3D p20 = n20.MultiplyComponents(subdivisionMesh.Ellipsoid.Radii); positions.Add(p01); positions.Add(p12); positions.Add(p20); int i01 = positions.Count - 3; int i12 = positions.Count - 2; int i20 = positions.Count - 1; if ((subdivisionMesh.Normals != null) || (subdivisionMesh.TextureCoordinate != null)) { Vector3D d01 = subdivisionMesh.Ellipsoid.GeodeticSurfaceNormal(p01); Vector3D d12 = subdivisionMesh.Ellipsoid.GeodeticSurfaceNormal(p12); Vector3D d20 = subdivisionMesh.Ellipsoid.GeodeticSurfaceNormal(p20); if (subdivisionMesh.Normals != null) { subdivisionMesh.Normals.Add(d01.ToVector3H()); subdivisionMesh.Normals.Add(d12.ToVector3H()); subdivisionMesh.Normals.Add(d20.ToVector3H()); } if (subdivisionMesh.TextureCoordinate != null) { subdivisionMesh.TextureCoordinate.Add(SubdivisionUtility.ComputeTextureCoordinate(d01)); subdivisionMesh.TextureCoordinate.Add(SubdivisionUtility.ComputeTextureCoordinate(d12)); subdivisionMesh.TextureCoordinate.Add(SubdivisionUtility.ComputeTextureCoordinate(d20)); } } // // Subdivide input triangle into four triangles // --level; Subdivide(subdivisionMesh, new TriangleIndicesUnsignedInt(triangle.I0, i01, i20), level); Subdivide(subdivisionMesh, new TriangleIndicesUnsignedInt(i01, triangle.I1, i12), level); Subdivide(subdivisionMesh, new TriangleIndicesUnsignedInt(i01, i12, i20), level); Subdivide(subdivisionMesh, new TriangleIndicesUnsignedInt(i20, i12, triangle.I2), level); } else { subdivisionMesh.Indices.AddTriangle(triangle); } }
public static SubdivisionMesh Combine(SubdivisionMesh meshA, SubdivisionMesh meshB) { int offset = meshA.ControlVertexCount; return(new SubdivisionMesh( meshA.ControlVertexCount + meshB.ControlVertexCount, QuadTopology.Combine(meshA.Topology, meshB.Topology), PackedLists <WeightedIndexWithDerivatives> .Concat( meshA.Stencils, meshB.Stencils.Map(w => w.Reindex(offset))))); }
public static RefinementResult Combine(RefinementResult resultA, RefinementResult resultB) { SubdivisionMesh combinedMesh = SubdivisionMesh.Combine( resultA.Mesh, resultB.Mesh); int[] combinedControlFaceMap = Enumerable.Concat( resultA.ControlFaceMap, resultB.ControlFaceMap).ToArray(); return(new RefinementResult(combinedMesh, combinedControlFaceMap)); }
public static Scatterer Load(Device device, ShaderCache shaderCache, IArchiveDirectory figureDir, String materialSetName) { var l0GeometryDir = figureDir.Subdirectory("refinement").Subdirectory("level-0"); SubdivisionMesh level0Mesh = SubdivisionMeshPersistance.Load(l0GeometryDir); var scatteringDir = figureDir.Subdirectory("scattering").Subdirectory(materialSetName); var formFactorSegments = scatteringDir.File(FormFactorSegmentsFilename).ReadArray <ArraySegment>(); var formFactorElements = scatteringDir.File(FormFactoryElementsFilename).ReadArray <Vector3WeightedIndex>(); var formFactors = new PackedLists <Vector3WeightedIndex>(formFactorSegments, formFactorElements); return(new Scatterer(device, shaderCache, level0Mesh, formFactors)); }
public Scatterer(Device device, ShaderCache shaderCache, SubdivisionMesh mesh, PackedLists <Vector3WeightedIndex> formFactors) { vertexCount = mesh.Stencils.Count; stencilSegments = BufferUtilities.ToStructuredBufferView(device, mesh.Stencils.Segments); stencilElems = BufferUtilities.ToStructuredBufferView(device, mesh.Stencils.Elems); formFactorSegments = BufferUtilities.ToStructuredBufferView(device, formFactors.Segments); formFactorElements = BufferUtilities.ToStructuredBufferView(device, formFactors.Elems); samplingShader = shaderCache.GetComputeShader <Scatterer>("figure/scattering/SampleVertexIrradiances"); scatteringShader = shaderCache.GetComputeShader <Scatterer>("figure/scattering/ScatterIrradiances"); sampledIrrandiancesBufferManager = new InOutStructuredBufferManager <Vector3>(device, vertexCount); scatteredIrrandiancesBufferManager = new InOutStructuredBufferManager <Vector3>(device, vertexCount); }
public static RefinementResult Make(QuadTopology controlTopology, int[] controlSurfaceMap, int refinementLevel, bool derivativesOnly) { if (controlTopology.Faces.Length == 0 && controlTopology.VertexCount == 0) { return(RefinementResult.Empty); } PackedLists <WeightedIndex> limitStencils, limitDuStencils, limitDvStencils; QuadTopology refinedTopology; SubdivisionTopologyInfo refinedTopologyInfo; int[] controlFaceMap; using (var refinement = new Refinement(controlTopology, refinementLevel)) { limitStencils = refinement.GetStencils(StencilKind.LimitStencils); limitDuStencils = refinement.GetStencils(StencilKind.LimitDuStencils); limitDvStencils = refinement.GetStencils(StencilKind.LimitDvStencils); refinedTopology = refinement.GetTopology(); var adjacentVertices = refinement.GetAdjacentVertices(); var rules = refinement.GetVertexRules(); refinedTopologyInfo = new SubdivisionTopologyInfo(adjacentVertices, rules); controlFaceMap = refinement.GetFaceMap(); } if (derivativesOnly) { if (refinementLevel != 0) { throw new InvalidOperationException("derivatives-only mode can only be used at refinement level 0"); } limitStencils = PackedLists <WeightedIndex> .Pack(Enumerable.Range(0, controlTopology.VertexCount) .Select(vertexIdx => { var selfWeight = new WeightedIndex(vertexIdx, 1); return(new List <WeightedIndex> { selfWeight }); }).ToList()); } PackedLists <WeightedIndexWithDerivatives> stencils = WeightedIndexWithDerivatives.Merge(limitStencils, limitDuStencils, limitDvStencils); var refinedMesh = new SubdivisionMesh(controlTopology.VertexCount, refinedTopology, stencils); return(new RefinementResult(refinedMesh, refinedTopologyInfo, controlFaceMap)); }
private static void Subdivide(SubdivisionMesh subdivisionMesh, TriangleIndicesUnsignedInt triangle, int level) { if (level > 0) { IList <Vector3D> positions = subdivisionMesh.Positions; Vector3D p01 = ((positions[triangle.I0] + positions[triangle.I1]) * 0.5).Normalize(); Vector3D p12 = ((positions[triangle.I1] + positions[triangle.I2]) * 0.5).Normalize(); Vector3D p20 = ((positions[triangle.I2] + positions[triangle.I0]) * 0.5).Normalize(); positions.Add(p01); positions.Add(p12); positions.Add(p20); int i01 = positions.Count - 3; int i12 = positions.Count - 2; int i20 = positions.Count - 1; if (subdivisionMesh.Normals != null) { subdivisionMesh.Normals.Add(p01.ToVector3H()); subdivisionMesh.Normals.Add(p12.ToVector3H()); subdivisionMesh.Normals.Add(p20.ToVector3H()); } if (subdivisionMesh.TextureCoordinate != null) { subdivisionMesh.TextureCoordinate.Add(SubdivisionUtility.ComputeTextureCoordinate(p01)); subdivisionMesh.TextureCoordinate.Add(SubdivisionUtility.ComputeTextureCoordinate(p12)); subdivisionMesh.TextureCoordinate.Add(SubdivisionUtility.ComputeTextureCoordinate(p20)); } // // Subdivide input triangle into four triangles // --level; Subdivide(subdivisionMesh, new TriangleIndicesUnsignedInt(triangle.I0, i01, i20), level); Subdivide(subdivisionMesh, new TriangleIndicesUnsignedInt(i01, triangle.I1, i12), level); Subdivide(subdivisionMesh, new TriangleIndicesUnsignedInt(i01, i12, i20), level); Subdivide(subdivisionMesh, new TriangleIndicesUnsignedInt(i20, i12, triangle.I2), level); } else { subdivisionMesh.Indices.AddTriangle(triangle); } }
public ArraySegment Add(SubdivisionMesh mesh, float[] faceTransparencies) { if (mesh.Topology.Faces.Length != faceTransparencies.Length) { throw new ArgumentException("face count mismatch"); } int startingOffset = combinedMesh.Topology.VertexCount; combinedMesh = SubdivisionMesh.Combine(this.combinedMesh, mesh); combinedFaceTransparencies = this.combinedFaceTransparencies.Concat(faceTransparencies).ToArray(); Array.Resize(ref faceMasks, combinedMesh.Topology.Faces.Count()); Array.Resize(ref vertexMasks, combinedMesh.Topology.VertexCount); int count = mesh.Topology.VertexCount; return(new ArraySegment(startingOffset, count)); }
private readonly Buffer refinedVertexBuffer; // stream-out | vertex public VertexRefiner(Device device, ShaderCache shaderCache, SubdivisionMesh mesh, TexturedVertexInfo[] texturedVertexInfos) { this.refinedVertexCount = texturedVertexInfos.Length; var vertexRefinerShaderAndBytecode = shaderCache.GetVertexShader <FigureRenderer>("figure/rendering/VertexRefiner"); this.vertexRefinerShader = vertexRefinerShaderAndBytecode; this.vertexRefinerGeometryShader = new GeometryShader(device, vertexRefinerShaderAndBytecode.Bytecode, StreamOutputElements, new int[] { StreamStride }, GeometryShader.StreamOutputNoRasterizedStream); this.shaderResources = new ShaderResourceView[] { BufferUtilities.ToStructuredBufferView(device, mesh.Stencils.Segments), BufferUtilities.ToStructuredBufferView(device, mesh.Stencils.Elems), BufferUtilities.ToStructuredBufferView(device, texturedVertexInfos) }; this.refinedVertexBuffer = new Buffer(device, new BufferDescription { SizeInBytes = refinedVertexCount * StreamStride, Usage = ResourceUsage.Default, BindFlags = BindFlags.StreamOutput | BindFlags.VertexBuffer }); }
public static Mesh Compute(Ellipsoid ellipsoid, int numberOfSubdivisions, SubdivisionEllipsoidVertexAttributes vertexAttributes) { if (numberOfSubdivisions < 0) { throw new ArgumentOutOfRangeException("numberOfSubdivisions"); } if ((vertexAttributes & SubdivisionEllipsoidVertexAttributes.Position) != SubdivisionEllipsoidVertexAttributes.Position) { throw new ArgumentException("Positions must be provided.", "vertexAttributes"); } Mesh mesh = new Mesh(); mesh.PrimitiveType = PrimitiveType.Triangles; mesh.FrontFaceWindingOrder = WindingOrder.Counterclockwise; int numberOfVertices = SubdivisionUtility.NumberOfVertices(numberOfSubdivisions); VertexAttributeDoubleVector3 positionsAttribute = new VertexAttributeDoubleVector3("position", numberOfVertices); mesh.Attributes.Add(positionsAttribute); IndicesUnsignedInt indices = new IndicesUnsignedInt(3 * SubdivisionUtility.NumberOfTriangles(numberOfSubdivisions)); mesh.Indices = indices; SubdivisionMesh subdivisionMesh = new SubdivisionMesh(); subdivisionMesh.Ellipsoid = ellipsoid; subdivisionMesh.Positions = positionsAttribute.Values; subdivisionMesh.Indices = indices; if ((vertexAttributes & SubdivisionEllipsoidVertexAttributes.Normal) == SubdivisionEllipsoidVertexAttributes.Normal) { VertexAttributeHalfFloatVector3 normalsAttribute = new VertexAttributeHalfFloatVector3("normal", numberOfVertices); mesh.Attributes.Add(normalsAttribute); subdivisionMesh.Normals = normalsAttribute.Values; } if ((vertexAttributes & SubdivisionEllipsoidVertexAttributes.TextureCoordinate) == SubdivisionEllipsoidVertexAttributes.TextureCoordinate) { VertexAttributeHalfFloatVector2 textureCoordinateAttribute = new VertexAttributeHalfFloatVector2("textureCoordinate", numberOfVertices); mesh.Attributes.Add(textureCoordinateAttribute); subdivisionMesh.TextureCoordinate = textureCoordinateAttribute.Values; } // // Initial tetrahedron // double negativeRootTwoOverThree = -Math.Sqrt(2.0) / 3.0; const double negativeOneThird = -1.0 / 3.0; double rootSixOverThree = Math.Sqrt(6.0) / 3.0; Vector3D n0 = new Vector3D(0, 0, 1); Vector3D n1 = new Vector3D(0, (2.0 * Math.Sqrt(2.0)) / 3.0, negativeOneThird); Vector3D n2 = new Vector3D(-rootSixOverThree, negativeRootTwoOverThree, negativeOneThird); Vector3D n3 = new Vector3D(rootSixOverThree, negativeRootTwoOverThree, negativeOneThird); Vector3D p0 = n0.MultiplyComponents(ellipsoid.Radii); Vector3D p1 = n1.MultiplyComponents(ellipsoid.Radii); Vector3D p2 = n2.MultiplyComponents(ellipsoid.Radii); Vector3D p3 = n3.MultiplyComponents(ellipsoid.Radii); subdivisionMesh.Positions.Add(p0); subdivisionMesh.Positions.Add(p1); subdivisionMesh.Positions.Add(p2); subdivisionMesh.Positions.Add(p3); if ((subdivisionMesh.Normals != null) || (subdivisionMesh.TextureCoordinate != null)) { Vector3D d0 = ellipsoid.GeodeticSurfaceNormal(p0); Vector3D d1 = ellipsoid.GeodeticSurfaceNormal(p1); Vector3D d2 = ellipsoid.GeodeticSurfaceNormal(p2); Vector3D d3 = ellipsoid.GeodeticSurfaceNormal(p3); if (subdivisionMesh.Normals != null) { subdivisionMesh.Normals.Add(d0.ToVector3H()); subdivisionMesh.Normals.Add(d1.ToVector3H()); subdivisionMesh.Normals.Add(d2.ToVector3H()); subdivisionMesh.Normals.Add(d3.ToVector3H()); } if (subdivisionMesh.TextureCoordinate != null) { subdivisionMesh.TextureCoordinate.Add(SubdivisionUtility.ComputeTextureCoordinate(d0)); subdivisionMesh.TextureCoordinate.Add(SubdivisionUtility.ComputeTextureCoordinate(d1)); subdivisionMesh.TextureCoordinate.Add(SubdivisionUtility.ComputeTextureCoordinate(d2)); subdivisionMesh.TextureCoordinate.Add(SubdivisionUtility.ComputeTextureCoordinate(d3)); } } Subdivide(subdivisionMesh, new TriangleIndicesUnsignedInt(0, 1, 2), numberOfSubdivisions); Subdivide(subdivisionMesh, new TriangleIndicesUnsignedInt(0, 2, 3), numberOfSubdivisions); Subdivide(subdivisionMesh, new TriangleIndicesUnsignedInt(0, 3, 1), numberOfSubdivisions); Subdivide(subdivisionMesh, new TriangleIndicesUnsignedInt(1, 3, 2), numberOfSubdivisions); return(mesh); }
public static void Save(System.IO.DirectoryInfo directory, SubdivisionMesh mesh) { directory.File(StencilSegmentsFilename).WriteArray(mesh.Stencils.Segments); directory.File(StencilElementsFilename).WriteArray(mesh.Stencils.Elems); directory.File(StencilFacesFilename).WriteArray(mesh.Topology.Faces); }
public RefinementResult(SubdivisionMesh mesh, int[] controlFaceMap) { Mesh = mesh; ControlFaceMap = controlFaceMap; }
public static Mesh Compute(Ellipsoid ellipsoid, int numberOfSubdivisions, SubdivisionEllipsoidVertexAttributes vertexAttributes) { if (numberOfSubdivisions < 0) { throw new ArgumentOutOfRangeException("numberOfSubdivisions"); } if ((vertexAttributes & SubdivisionEllipsoidVertexAttributes.Position) != SubdivisionEllipsoidVertexAttributes.Position) { throw new ArgumentException("Positions must be provided.", "vertexAttributes"); } Mesh mesh = new Mesh(); mesh.PrimitiveType = PrimitiveType.Triangles; mesh.FrontFaceWindingOrder = WindingOrder.Counterclockwise; int numberOfVertices = SubdivisionUtility.NumberOfVertices(numberOfSubdivisions); VertexAttributeDoubleVector3 positionsAttribute = new VertexAttributeDoubleVector3("position", numberOfVertices); mesh.Attributes.Add(positionsAttribute); IndicesUnsignedInt indices = new IndicesUnsignedInt(3 * SubdivisionUtility.NumberOfTriangles(numberOfSubdivisions)); mesh.Indices = indices; SubdivisionMesh subdivisionMesh = new SubdivisionMesh(); subdivisionMesh.Ellipsoid = ellipsoid; subdivisionMesh.Positions = positionsAttribute.Values; subdivisionMesh.Indices = indices; if ((vertexAttributes & SubdivisionEllipsoidVertexAttributes.Normal) == SubdivisionEllipsoidVertexAttributes.Normal) { VertexAttributeHalfFloatVector3 normalsAttribute = new VertexAttributeHalfFloatVector3("normal", numberOfVertices); mesh.Attributes.Add(normalsAttribute); subdivisionMesh.Normals = normalsAttribute.Values; } if ((vertexAttributes & SubdivisionEllipsoidVertexAttributes.TextureCoordinate) == SubdivisionEllipsoidVertexAttributes.TextureCoordinate) { VertexAttributeHalfFloatVector2 textureCoordinateAttribute = new VertexAttributeHalfFloatVector2("textureCoordinate", numberOfVertices); mesh.Attributes.Add(textureCoordinateAttribute); subdivisionMesh.TextureCoordinate = textureCoordinateAttribute.Values; } // // Initial tetrahedron // double negativeRootTwoOverThree = -Math.Sqrt(2.0) / 3.0; const double negativeOneThird = -1.0 / 3.0; double rootSixOverThree = Math.Sqrt(6.0) / 3.0; Vector3D n0 = new Vector3D(0, 0, 1); Vector3D n1 = new Vector3D(0, (2.0 * Math.Sqrt(2.0)) / 3.0, negativeOneThird); Vector3D n2 = new Vector3D(-rootSixOverThree, negativeRootTwoOverThree, negativeOneThird); Vector3D n3 = new Vector3D(rootSixOverThree, negativeRootTwoOverThree, negativeOneThird); Vector3D p0 = n0.MultiplyComponents(ellipsoid.Radii); Vector3D p1 = n1.MultiplyComponents(ellipsoid.Radii); Vector3D p2 = n2.MultiplyComponents(ellipsoid.Radii); Vector3D p3 = n3.MultiplyComponents(ellipsoid.Radii); subdivisionMesh.Positions.Add(p0); subdivisionMesh.Positions.Add(p1); subdivisionMesh.Positions.Add(p2); subdivisionMesh.Positions.Add(p3); if ((subdivisionMesh.Normals != null) || (subdivisionMesh.TextureCoordinate != null)) { Vector3D d0 = ellipsoid.GeodeticSurfaceNormal(p0); Vector3D d1 = ellipsoid.GeodeticSurfaceNormal(p1); Vector3D d2 = ellipsoid.GeodeticSurfaceNormal(p2); Vector3D d3 = ellipsoid.GeodeticSurfaceNormal(p3); if (subdivisionMesh.Normals != null) { subdivisionMesh.Normals.Add(d0.ToVector3H()); subdivisionMesh.Normals.Add(d1.ToVector3H()); subdivisionMesh.Normals.Add(d2.ToVector3H()); subdivisionMesh.Normals.Add(d3.ToVector3H()); } if (subdivisionMesh.TextureCoordinate != null) { subdivisionMesh.TextureCoordinate.Add(SubdivisionUtility.ComputeTextureCoordinate(d0)); subdivisionMesh.TextureCoordinate.Add(SubdivisionUtility.ComputeTextureCoordinate(d1)); subdivisionMesh.TextureCoordinate.Add(SubdivisionUtility.ComputeTextureCoordinate(d2)); subdivisionMesh.TextureCoordinate.Add(SubdivisionUtility.ComputeTextureCoordinate(d3)); } } Subdivide(subdivisionMesh, new TriangleIndicesUnsignedInt(0, 1, 2), numberOfSubdivisions); Subdivide(subdivisionMesh, new TriangleIndicesUnsignedInt(0, 2, 3), numberOfSubdivisions); Subdivide(subdivisionMesh, new TriangleIndicesUnsignedInt(0, 3, 1), numberOfSubdivisions); Subdivide(subdivisionMesh, new TriangleIndicesUnsignedInt(1, 3, 2), numberOfSubdivisions); return mesh; }
private static void Subdivide(SubdivisionMesh subdivisionMesh, TriangleIndicesUnsignedInt triangle, int level) { if (level > 0) { IList<Vector3D> positions = subdivisionMesh.Positions; Vector3D p01 = ((positions[triangle.I0] + positions[triangle.I1]) * 0.5).Normalize(); Vector3D p12 = ((positions[triangle.I1] + positions[triangle.I2]) * 0.5).Normalize(); Vector3D p20 = ((positions[triangle.I2] + positions[triangle.I0]) * 0.5).Normalize(); positions.Add(p01); positions.Add(p12); positions.Add(p20); int i01 = positions.Count - 3; int i12 = positions.Count - 2; int i20 = positions.Count - 1; if (subdivisionMesh.Normals != null) { subdivisionMesh.Normals.Add(p01.ToVector3H()); subdivisionMesh.Normals.Add(p12.ToVector3H()); subdivisionMesh.Normals.Add(p20.ToVector3H()); } if (subdivisionMesh.TextureCoordinate != null) { subdivisionMesh.TextureCoordinate.Add(SubdivisionUtility.ComputeTextureCoordinate(p01)); subdivisionMesh.TextureCoordinate.Add(SubdivisionUtility.ComputeTextureCoordinate(p12)); subdivisionMesh.TextureCoordinate.Add(SubdivisionUtility.ComputeTextureCoordinate(p20)); } // // Subdivide input triangle into four triangles // --level; Subdivide(subdivisionMesh, new TriangleIndicesUnsignedInt(triangle.I0, i01, i20), level); Subdivide(subdivisionMesh, new TriangleIndicesUnsignedInt(i01, triangle.I1, i12), level); Subdivide(subdivisionMesh, new TriangleIndicesUnsignedInt(i01, i12, i20), level); Subdivide(subdivisionMesh, new TriangleIndicesUnsignedInt(i20, i12, triangle.I2), level); } else { subdivisionMesh.Indices.AddTriangle(triangle); } }
private static void Subdivide(SubdivisionMesh subdivisionMesh, TriangleIndicesUnsignedInt triangle, int level) { if (level > 0) { IList<Vector3D> positions = subdivisionMesh.Positions; Vector3D n01 = ((positions[triangle.I0] + positions[triangle.I1]) * 0.5).Normalize(); Vector3D n12 = ((positions[triangle.I1] + positions[triangle.I2]) * 0.5).Normalize(); Vector3D n20 = ((positions[triangle.I2] + positions[triangle.I0]) * 0.5).Normalize(); Vector3D p01 = n01.MultiplyComponents(subdivisionMesh.Ellipsoid.Radii); Vector3D p12 = n12.MultiplyComponents(subdivisionMesh.Ellipsoid.Radii); Vector3D p20 = n20.MultiplyComponents(subdivisionMesh.Ellipsoid.Radii); positions.Add(p01); positions.Add(p12); positions.Add(p20); int i01 = positions.Count - 3; int i12 = positions.Count - 2; int i20 = positions.Count - 1; if ((subdivisionMesh.Normals != null) || (subdivisionMesh.TextureCoordinate != null)) { Vector3D d01 = subdivisionMesh.Ellipsoid.GeodeticSurfaceNormal(p01); Vector3D d12 = subdivisionMesh.Ellipsoid.GeodeticSurfaceNormal(p12); Vector3D d20 = subdivisionMesh.Ellipsoid.GeodeticSurfaceNormal(p20); if (subdivisionMesh.Normals != null) { subdivisionMesh.Normals.Add(d01.ToVector3H()); subdivisionMesh.Normals.Add(d12.ToVector3H()); subdivisionMesh.Normals.Add(d20.ToVector3H()); } if (subdivisionMesh.TextureCoordinate != null) { subdivisionMesh.TextureCoordinate.Add(SubdivisionUtility.ComputeTextureCoordinate(d01)); subdivisionMesh.TextureCoordinate.Add(SubdivisionUtility.ComputeTextureCoordinate(d12)); subdivisionMesh.TextureCoordinate.Add(SubdivisionUtility.ComputeTextureCoordinate(d20)); } } // // Subdivide input triangle into four triangles // --level; Subdivide(subdivisionMesh, new TriangleIndicesUnsignedInt(triangle.I0, i01, i20), level); Subdivide(subdivisionMesh, new TriangleIndicesUnsignedInt(i01, triangle.I1, i12), level); Subdivide(subdivisionMesh, new TriangleIndicesUnsignedInt(i01, i12, i20), level); Subdivide(subdivisionMesh, new TriangleIndicesUnsignedInt(i20, i12, triangle.I2), level); } else { subdivisionMesh.Indices.AddTriangle(triangle); } }
public RefinementResult(SubdivisionMesh mesh, SubdivisionTopologyInfo topologyInfo, int[] controlFaceMap) { Mesh = mesh; TopologyInfo = topologyInfo; ControlFaceMap = controlFaceMap; }