public override IEnumerator BeginGeneration() { var surface = surfaceInputSlot.GetAsset <Surface>(); var topology = topologyInputSlot.GetAsset <Topology>(); var vertexPositions = vertexPositionsInputSlot.GetAsset <IVertexAttribute <Vector3> >(); var faceCentroids = PositionalFaceAttribute.Create(surface, new Vector3[topology.internalFaces.Count]).SetName("Face Centroids"); yield return(executive.GenerateConcurrently(() => { if (flatten || surface is QuadrilateralSurface) { FaceAttributeUtility.CalculateFaceCentroidsFromVertexPositions(topology.internalFaces, vertexPositions, faceCentroids); } else if (surface is SphericalSurface) { var sphericalSurface = (SphericalSurface)surface; FaceAttributeUtility.CalculateSphericalFaceCentroidsFromVertexPositions(topology.internalFaces, sphericalSurface, vertexPositions, faceCentroids); } else { throw new System.NotImplementedException(); } })); faceCentroidsOutputSlot.SetAsset(faceCentroids); yield break; }
public override IEnumerator BeginGeneration() { var topology = topologyInputSlot.GetAsset <Topology>(); var vertexNormals = Vector3VertexAttribute.Create(new Vector3[topology.vertices.Count]).SetName("Vertex Normals"); yield return(executive.GenerateConcurrently(() => { switch (calculationMethod) { case CalculationMethod.FromSurfaceNormal: VertexAttributeUtility.CalculateVertexNormalsFromSurface(topology.vertices, surfaceInputSlot.GetAsset <Surface>(), vertexPositionsInputSlot.GetAsset <IVertexAttribute <Vector3> >(), vertexNormals); break; case CalculationMethod.FromVertexPositions: VertexAttributeUtility.CalculateVertexNormalsFromVertexPositions(topology.vertices, vertexPositionsInputSlot.GetAsset <IVertexAttribute <Vector3> >(), vertexNormals); break; case CalculationMethod.FromFacePositions: VertexAttributeUtility.CalculateVertexNormalsFromFacePositions(topology.vertices, facePositionsInputSlot.GetAsset <IFaceAttribute <Vector3> >(), vertexNormals); break; case CalculationMethod.FromFaceNormals: VertexAttributeUtility.CalculateVertexNormalsFromFaceNormals(topology.vertices, faceNormalsInputSlot.GetAsset <IFaceAttribute <Vector3> >(), vertexNormals); break; default: throw new System.NotImplementedException(); } })); vertexNormalsOutputSlot.SetAsset(vertexNormals); yield break; }
public override IEnumerator BeginGeneration() { var partitioning = UniversalFaceSpatialPartitioning.Create( surfaceInputSlot.GetAsset <Surface>(), topologyInputSlot.GetAsset <Topology>(), vertexPositionsInputSlot.GetAsset <IVertexAttribute <Vector3> >()); partitioningOutputSlot.SetAsset(partitioning); yield break; }
public override IEnumerator BeginGeneration() { var surface = surfaceInputSlot.GetAsset <Surface>(); var topology = topologyInputSlot.GetAsset <Topology>(); var vertexPositions = vertexPositionsInputSlot.GetAsset <IEdgeAttribute <Vector3> >(); var facePositions = facePositionsInputSlot.GetAsset <IFaceAttribute <Vector3> >(); var bisectors = Vector3EdgeAttribute.Create(topology.faceEdges.Count); EdgeAttributeUtility.CalculateFaceEdgeBisectorsFromVertexPositions(topology.internalFaces, surface, vertexPositions, facePositions, bisectors); bisectorsOutputSlot.SetAsset(bisectors); yield break; }
public override IEnumerator BeginGeneration() { var topology = topologyInputSlot.GetAsset <Topology>(); var vertexPositions = vertexPositionsInputSlot.GetAsset <IEdgeAttribute <Vector3> >(); var offsets = offsetsInputSlot.GetAsset <IEdgeAttribute <Vector3> >(); var offsetPositions = Vector3EdgeAttribute.Create(topology.faceEdges.Count); foreach (var edge in topology.faceEdges) { offsetPositions[edge] = vertexPositions[edge] + offsets[edge] * scale; } offsetVertexPositionsOutputSlot.SetAsset(offsetPositions); yield break; }
private void GenerateRandomPerFace() { var topology = topologyInputSlot.GetAsset <Topology>(); var faceColors = ColorFaceAttribute.Create(topology.internalFaces.Count); var random = randomness.GetRandom(); foreach (var face in topology.internalFaces) { #if MAKEIT_COLORFUL_2_0_OR_NEWER faceColors[face] = random.ColorRGB(); #else faceColors[face] = new Color(random.FloatCC(), random.FloatCC(), random.FloatCC()); #endif } faceColorsOutputSlot.SetAsset(faceColors); }
private void GenerateFromFaceColors() { var topology = topologyInputSlot.GetAsset <Topology>(); var faceColors = faceColorsInputSlot.GetAsset <IFaceAttribute <Color> >(); var faceEdgeColors = ColorEdgeAttribute.Create(topology.faceEdges.Count); foreach (var face in topology.internalFaces) { var faceColor = faceColors[face]; var edgeColor = Color.Lerp(constantColor, faceColor, blendWeight); foreach (var edge in face.edges) { faceEdgeColors[edge] = edgeColor; } } faceEdgeColorsOutputSlot.SetAsset(faceEdgeColors); }
private void GenerateRandomPerGroup() { var faceGroupCollection = faceGroupCollectionInputSlot.GetAsset <FaceGroupCollection>(); var faceGroups = faceGroupCollection.faceGroups; var faceGroupColorsArray = new Color[faceGroups.Length]; var random = randomness.GetRandom(); for (int i = 0; i < faceGroups.Length; ++i) { #if MAKEIT_COLORFUL_2_0_OR_NEWER faceGroupColorsArray[i] = random.ColorRGB(); #else faceGroupColorsArray[i] = new Color(random.FloatCC(), random.FloatCC(), random.FloatCC()); #endif } faceGroupColorsOutputSlot.SetAsset(ColorFaceGroupAttribute.Create(faceGroupColorsArray).SetName((faceGroupCollection.name + " Colors").TrimStart())); faceColorsOutputSlot.SetAsset(ColorFaceGroupLookupFaceAttribute.Create( faceGroupIndicesInputSlot.GetAsset <IntFaceAttribute>(), faceGroupColorsOutputSlot.GetAsset <ColorFaceGroupAttribute>()).SetName("Face Colors")); }
public override IEnumerator BeginGeneration() { var surface = surfaceInputSlot.GetAsset <Surface>(); var topology = topologyInputSlot.GetAsset <Topology>(); var vertexPositions = vertexPositionsInputSlot.source != null?vertexPositionsInputSlot.GetAsset <IVertexAttribute <Vector3> >() : null; var random = randomness.GetRandom(); System.Func <float> relaxIterationFunction = null; System.Func <bool> repairFunction = null; System.Action relaxationLoopFunction = null; if (vertexPositions != null) { if (surface is QuadrilateralSurface) { if (relaxForRegularityWeight >= 1.0f) { var relaxedVertexPositions = new Vector3[topology.vertices.Count].AsVertexAttribute(); relaxIterationFunction = () => { PlanarManifoldUtility.RelaxVertexPositionsForRegularity(topology, vertexPositions, lockBoundaryPositions, relaxedVertexPositions); var relaxationAmount = PlanarManifoldUtility.CalculateRelaxationAmount(vertexPositions, relaxedVertexPositions); for (int i = 0; i < vertexPositions.Count; ++i) { vertexPositions[i] = relaxedVertexPositions[i]; } return(relaxationAmount); }; } else if (relaxForRegularityWeight <= 0.0f) { var relaxedVertexPositions = new Vector3[topology.vertices.Count].AsVertexAttribute(); var faceCentroids = PositionalFaceAttribute.Create(surface, topology.internalFaces.Count); var vertexAreas = new float[topology.vertices.Count].AsVertexAttribute(); FaceAttributeUtility.CalculateFaceCentroidsFromVertexPositions(topology.internalFaces, vertexPositions, faceCentroids); VertexAttributeUtility.CalculateVertexAreasFromVertexPositionsAndFaceCentroids(topology.vertices, vertexPositions, faceCentroids, vertexAreas); var totalArea = 0f; foreach (var vertexArea in vertexAreas) { totalArea += vertexArea; } relaxIterationFunction = () => { PlanarManifoldUtility.RelaxVertexPositionsForEqualArea(topology, vertexPositions, totalArea, lockBoundaryPositions, relaxedVertexPositions, faceCentroids, vertexAreas); var relaxationAmount = PlanarManifoldUtility.CalculateRelaxationAmount(vertexPositions, relaxedVertexPositions); for (int i = 0; i < vertexPositions.Count; ++i) { vertexPositions[i] = relaxedVertexPositions[i]; } return(relaxationAmount); }; } else { var regularityWeight = Mathf.Clamp01(relaxForRegularityWeight); var equalAreaWeight = 1f - regularityWeight; var regularityRelaxedVertexPositions = new Vector3[topology.vertices.Count].AsVertexAttribute(); var equalAreaRelaxedVertexPositions = new Vector3[topology.vertices.Count].AsVertexAttribute(); var relaxedVertexPositions = regularityRelaxedVertexPositions; var faceCentroids = PositionalFaceAttribute.Create(surface, topology.internalFaces.Count); var vertexAreas = new float[topology.vertices.Count].AsVertexAttribute(); FaceAttributeUtility.CalculateFaceCentroidsFromVertexPositions(topology.internalFaces, vertexPositions, faceCentroids); VertexAttributeUtility.CalculateVertexAreasFromVertexPositionsAndFaceCentroids(topology.vertices, vertexPositions, faceCentroids, vertexAreas); var totalArea = 0f; foreach (var vertexArea in vertexAreas) { totalArea += vertexArea; } relaxIterationFunction = () => { PlanarManifoldUtility.RelaxVertexPositionsForRegularity(topology, vertexPositions, lockBoundaryPositions, regularityRelaxedVertexPositions); PlanarManifoldUtility.RelaxVertexPositionsForEqualArea(topology, vertexPositions, totalArea, lockBoundaryPositions, equalAreaRelaxedVertexPositions, faceCentroids, vertexAreas); for (int i = 0; i < relaxedVertexPositions.Count; ++i) { relaxedVertexPositions[i] = regularityRelaxedVertexPositions[i] * regularityWeight + equalAreaRelaxedVertexPositions[i] * equalAreaWeight; } var relaxationAmount = PlanarManifoldUtility.CalculateRelaxationAmount(vertexPositions, relaxedVertexPositions); for (int i = 0; i < vertexPositions.Count; ++i) { vertexPositions[i] = relaxedVertexPositions[i]; } return(relaxationAmount); }; } repairFunction = () => { return(PlanarManifoldUtility.ValidateAndRepair(topology, ((QuadrilateralSurface)surface).normal, vertexPositions, repairRate, lockBoundaryPositions)); }; relaxationLoopFunction = TopologyRandomizer.CreateRelaxationLoopFunction(maxRelaxIterations, maxRepairIterations, relaxRelativePrecision, relaxIterationFunction, repairFunction); } else if (surface is SphericalSurface) { var sphericalSurface = (SphericalSurface)surface; if (relaxForRegularityWeight >= 1.0f) { var relaxedVertexPositions = new Vector3[topology.vertices.Count].AsVertexAttribute(); relaxIterationFunction = () => { SphericalManifoldUtility.RelaxVertexPositionsForRegularity(sphericalSurface, topology, vertexPositions, lockBoundaryPositions, relaxedVertexPositions); var relaxationAmount = SphericalManifoldUtility.CalculateRelaxationAmount(vertexPositions, relaxedVertexPositions); for (int i = 0; i < vertexPositions.Count; ++i) { vertexPositions[i] = relaxedVertexPositions[i]; } return(relaxationAmount); }; } else if (relaxForRegularityWeight <= 0.0f) { var relaxedVertexPositions = new Vector3[topology.vertices.Count].AsVertexAttribute(); var faceCentroids = PositionalFaceAttribute.Create(surface, topology.internalFaces.Count); var faceCentroidAngles = new float[topology.faceEdges.Count].AsEdgeAttribute(); var vertexAreas = new float[topology.vertices.Count].AsVertexAttribute(); relaxIterationFunction = () => { SphericalManifoldUtility.RelaxVertexPositionsForEqualArea(sphericalSurface, topology, vertexPositions, lockBoundaryPositions, relaxedVertexPositions, faceCentroids, faceCentroidAngles, vertexAreas); var relaxationAmount = SphericalManifoldUtility.CalculateRelaxationAmount(vertexPositions, relaxedVertexPositions); for (int i = 0; i < vertexPositions.Count; ++i) { vertexPositions[i] = relaxedVertexPositions[i]; } return(relaxationAmount); }; } else { var regularityWeight = Mathf.Clamp01(relaxForRegularityWeight); var equalAreaWeight = 1f - regularityWeight; var regularityRelaxedVertexPositions = new Vector3[topology.vertices.Count].AsVertexAttribute(); var equalAreaRelaxedVertexPositions = new Vector3[topology.vertices.Count].AsVertexAttribute(); var relaxedVertexPositions = regularityRelaxedVertexPositions; var faceCentroids = PositionalFaceAttribute.Create(surface, topology.internalFaces.Count); var faceCentroidAngles = new float[topology.faceEdges.Count].AsEdgeAttribute(); var vertexAreas = new float[topology.vertices.Count].AsVertexAttribute(); relaxIterationFunction = () => { SphericalManifoldUtility.RelaxVertexPositionsForRegularity(sphericalSurface, topology, vertexPositions, lockBoundaryPositions, regularityRelaxedVertexPositions); SphericalManifoldUtility.RelaxVertexPositionsForEqualArea(sphericalSurface, topology, vertexPositions, lockBoundaryPositions, equalAreaRelaxedVertexPositions, faceCentroids, faceCentroidAngles, vertexAreas); for (int i = 0; i < relaxedVertexPositions.Count; ++i) { relaxedVertexPositions[i] = regularityRelaxedVertexPositions[i] * regularityWeight + equalAreaRelaxedVertexPositions[i] * equalAreaWeight; } var relaxationAmount = SphericalManifoldUtility.CalculateRelaxationAmount(vertexPositions, relaxedVertexPositions); for (int i = 0; i < vertexPositions.Count; ++i) { vertexPositions[i] = relaxedVertexPositions[i]; } return(relaxationAmount); }; } repairFunction = () => { return(SphericalManifoldUtility.ValidateAndRepair(sphericalSurface, topology, vertexPositions, repairRate, lockBoundaryPositions)); }; relaxationLoopFunction = TopologyRandomizer.CreateRelaxationLoopFunction(maxRelaxIterations, maxRepairIterations, relaxRelativePrecision, relaxIterationFunction, repairFunction); } } yield return(executive.GenerateConcurrently(() => { TopologyRandomizer.Randomize(topology, passCount, frequency, minVertexNeighbors, maxVertexNeighbors, minFaceNeighbors, maxFaceNeighbors, lockBoundaryPositions, random, relaxationLoopFunction); })); EditorUtility.SetDirty(topology); if (vertexPositions != null) { EditorUtility.SetDirty((Object)vertexPositions); } yield break; }
public override IEnumerator BeginGeneration() { var topology = topologyInputSlot.GetAsset <Topology>(); var vertexAttributeSources = new VertexAttributeSources(); vertexAttributeSources.ringPositions = VertexAttributeSources.GetRingAttributes <Vector3>(topology, ringVertexPositionsInputSlots); vertexAttributeSources.ringNormals = VertexAttributeSources.GetRingAttributes <Vector3>(topology, ringVertexNormalsInputSlots); vertexAttributeSources.ringColors = VertexAttributeSources.GetRingAttributes <Color>(topology, ringVertexColorsInputSlots); vertexAttributeSources.ringColor32s = VertexAttributeSources.GetRingAttributes <Color32>(topology, ringVertexColor32sInputSlots); vertexAttributeSources.ringUV1s = VertexAttributeSources.GetRingAttributes <Vector2>(topology, ringVertexUV1sInputSlots); vertexAttributeSources.ringUV2s = VertexAttributeSources.GetRingAttributes <Vector2>(topology, ringVertexUV2sInputSlots); vertexAttributeSources.ringUV3s = VertexAttributeSources.GetRingAttributes <Vector2>(topology, ringVertexUV3sInputSlots); vertexAttributeSources.ringUV4s = VertexAttributeSources.GetRingAttributes <Vector2>(topology, ringVertexUV4sInputSlots); vertexAttributeSources.ringTangents = VertexAttributeSources.GetRingAttributes <Vector4>(topology, ringVertexTangentsInputSlots); vertexAttributeSources.centerPositions = VertexAttributeSources.GetCenterAttributes <Vector3>(centerVertexPositionsInputSlots); vertexAttributeSources.centerNormals = VertexAttributeSources.GetCenterAttributes <Vector3>(centerVertexNormalsInputSlots); vertexAttributeSources.centerColors = VertexAttributeSources.GetCenterAttributes <Color>(centerVertexColorsInputSlots); vertexAttributeSources.centerColor32s = VertexAttributeSources.GetCenterAttributes <Color32>(centerVertexColor32sInputSlots); vertexAttributeSources.centerUV1s = VertexAttributeSources.GetCenterAttributes <Vector2>(centerVertexUV1sInputSlots); vertexAttributeSources.centerUV2s = VertexAttributeSources.GetCenterAttributes <Vector2>(centerVertexUV2sInputSlots); vertexAttributeSources.centerUV3s = VertexAttributeSources.GetCenterAttributes <Vector2>(centerVertexUV3sInputSlots); vertexAttributeSources.centerUV4s = VertexAttributeSources.GetCenterAttributes <Vector2>(centerVertexUV4sInputSlots); vertexAttributeSources.centerTangents = VertexAttributeSources.GetCenterAttributes <Vector4>(centerVertexTangentsInputSlots); System.Action <Topology.FaceEdge, DynamicMesh.IIndexedVertexAttributes> setRingVertexAttributes = (Topology.FaceEdge edge, DynamicMesh.IIndexedVertexAttributes va) => { for (int i = 0; i < ringDepth; ++i) { if (vertexAttributeSources.ringPositions != null) { va.position = vertexAttributeSources.ringPositions[i][edge]; } if (vertexAttributeSources.ringNormals != null) { va.normal = vertexAttributeSources.ringNormals[i][edge]; } if (vertexAttributeSources.ringColors != null) { va.color = vertexAttributeSources.ringColors[i][edge]; } if (vertexAttributeSources.ringColor32s != null) { va.color32 = vertexAttributeSources.ringColor32s[i][edge]; } if (vertexAttributeSources.ringUV1s != null) { va.uv1 = vertexAttributeSources.ringUV1s[i][edge]; } if (vertexAttributeSources.ringUV2s != null) { va.uv2 = vertexAttributeSources.ringUV2s[i][edge]; } if (vertexAttributeSources.ringUV3s != null) { va.uv3 = vertexAttributeSources.ringUV3s[i][edge]; } if (vertexAttributeSources.ringUV4s != null) { va.uv4 = vertexAttributeSources.ringUV4s[i][edge]; } if (vertexAttributeSources.ringTangents != null) { va.tangent = vertexAttributeSources.ringTangents[i][edge]; } va.Advance(); } }; System.Action <Topology.Face, DynamicMesh.IIndexedVertexAttributes> setCenterVertexAttributes = (Topology.Face face, DynamicMesh.IIndexedVertexAttributes va) => { if (vertexAttributeSources.centerPositions != null) { va.position = vertexAttributeSources.centerPositions[face]; } if (vertexAttributeSources.centerNormals != null) { va.normal = vertexAttributeSources.centerNormals[face]; } if (vertexAttributeSources.centerColors != null) { va.color = vertexAttributeSources.centerColors[face]; } if (vertexAttributeSources.centerColor32s != null) { va.color32 = vertexAttributeSources.centerColor32s[face]; } if (vertexAttributeSources.centerUV1s != null) { va.uv1 = vertexAttributeSources.centerUV1s[face]; } if (vertexAttributeSources.centerUV2s != null) { va.uv2 = vertexAttributeSources.centerUV2s[face]; } if (vertexAttributeSources.centerUV3s != null) { va.uv3 = vertexAttributeSources.centerUV3s[face]; } if (vertexAttributeSources.centerUV4s != null) { va.uv4 = vertexAttributeSources.centerUV4s[face]; } if (vertexAttributeSources.centerTangents != null) { va.tangent = vertexAttributeSources.centerTangents[face]; } va.Advance(); }; DynamicMesh.ITriangulation triangulationInstance = null; switch (triangulation) { case Triangulation.Strip: triangulationInstance = new SeparatedFacesStripTriangulation(ringDepth, setRingVertexAttributes); break; case Triangulation.Fan: triangulationInstance = new SeparatedFacesFanTriangulation(ringDepth, setRingVertexAttributes); break; case Triangulation.Umbrella: triangulationInstance = new SeparatedFacesUmbrellaTriangulation(ringDepth, setRingVertexAttributes, setCenterVertexAttributes); break; default: throw new System.NotImplementedException(); } DynamicMesh dynamicMesh; switch (sourceType) { case SourceType.InternalFaces: dynamicMesh = DynamicMesh.Create(topology.enumerableInternalFaces, vertexAttributes, triangulationInstance, maxVerticesPerSubmesh); break; case SourceType.FaceGroupCollection: dynamicMesh = DynamicMesh.Create(faceGroupCollectionInputSlot.GetAsset <FaceGroupCollection>(), vertexAttributes, triangulationInstance, maxVerticesPerSubmesh); break; case SourceType.FaceGroup: dynamicMesh = DynamicMesh.Create(faceGroupInputSlot.GetAsset <FaceGroup>(), vertexAttributes, triangulationInstance, maxVerticesPerSubmesh); break; default: throw new System.NotImplementedException(); } if (meshOutputSlots.Length != dynamicMesh.submeshCount) { var newMeshes = new OutputSlot[dynamicMesh.submeshCount]; System.Array.Copy(meshOutputSlots, newMeshes, Mathf.Min(meshOutputSlots.Length, newMeshes.Length)); for (var i = meshOutputSlots.Length; i < newMeshes.Length; ++i) { newMeshes[i] = OutputSlot.CreateGrouped <Mesh>(this, "Mesh", "Meshes"); } meshOutputSlots = newMeshes; } if (meshOutputSlots.Length == 1) { meshOutputSlots[0].name = "Mesh"; } else if (meshOutputSlots.Length > 1) { for (int i = 0; i < meshOutputSlots.Length; ++i) { meshOutputSlots[i].name = string.Format("Submesh {0}", i); } } for (int i = 0; i < meshOutputSlots.Length; ++i) { meshOutputSlots[i].SetAsset(dynamicMesh.GetSubmesh(i)); dynamicMesh.ReplaceSubmesh(i, meshOutputSlots[i].GetAsset <Mesh>()); } dynamicMeshOutputSlot.SetAsset(dynamicMesh); yield break; }
public override IEnumerator BeginGeneration() { GameObject prefab; var dynamicMesh = dynamicMeshInputSlot.GetAsset <DynamicMesh>(); if (dynamicMesh.submeshCount == 0) { if (meshPrefab == null) { prefab = new GameObject(); prefab.AddComponent <MeshFilter>(); prefab.AddComponent <MeshRenderer>(); } else { prefab = Instantiate(meshPrefab).gameObject; } } else if (dynamicMesh.submeshCount == 1) { if (meshPrefab == null) { prefab = new GameObject(); prefab.AddComponent <MeshFilter>().mesh = dynamicMesh.GetSubmesh(0); prefab.AddComponent <MeshRenderer>(); } else { var meshFilter = Instantiate(meshPrefab); meshFilter.mesh = dynamicMesh.GetSubmesh(0); prefab = meshFilter.gameObject; } } else { prefab = new GameObject(); if (meshPrefab == null) { for (int i = 0; i < dynamicMesh.submeshCount; ++i) { var submeshInstance = new GameObject(); submeshInstance.name = string.Format("Mesh {0}", i); submeshInstance.AddComponent <MeshFilter>().mesh = dynamicMesh.GetSubmesh(i); submeshInstance.AddComponent <MeshRenderer>(); submeshInstance.transform.SetParent(prefab.transform, false); } } else { for (int i = 0; i < dynamicMesh.submeshCount; ++i) { var meshFilter = Instantiate(meshPrefab); meshFilter.name = string.Format("Mesh {0}", i); meshFilter.mesh = dynamicMesh.GetSubmesh(i); meshFilter.transform.SetParent(prefab.transform, false); } } } prefab.name = name; prefabOutputSlot.SetAsset(prefab); yield break; }
public override IEnumerator BeginGeneration() { var topology = topologyInputSlot.GetAsset <Topology>(); var faceGroupIndices = new int[topology.internalFaces.Count].AsFaceAttribute(); List <int>[] faceGroupFaceIndices; var random = randomness.GetRandom(); var clampedRootCount = Mathf.Clamp(groupCount, 1, topology.internalFaces.Count); faceGroupFaceIndices = new List <int> [clampedRootCount]; var waitHandle = executive.GenerateConcurrently(() => { var rootFaces = new List <Topology.Face>(); var rootFaceEdges = new List <Topology.FaceEdge>(); for (int faceGroupIndex = 0; faceGroupIndex < clampedRootCount; ++faceGroupIndex) { faceGroupFaceIndices[faceGroupIndex] = new List <int>(); Topology.Face face; do { face = topology.internalFaces[random.Index(topology.internalFaces.Count)]; } while (rootFaces.Contains(face)); rootFaces.Add(face); foreach (var edge in face.edges) { if (edge.face.isInternal) { rootFaceEdges.Add(edge); } } faceGroupIndices[face] = faceGroupIndex; faceGroupFaceIndices[faceGroupIndex].Add(face.index); } TopologyVisitor.VisitFacesInRandomOrder( rootFaceEdges, (FaceEdgeVisitor visitor) => { var faceGroupIndex = faceGroupIndices[visitor.edge.nearFace]; faceGroupIndices[visitor.edge] = faceGroupIndex; faceGroupFaceIndices[faceGroupIndex].Add(visitor.edge.face.index); visitor.VisitInternalNeighborsExceptSource(); }, random); }); while (waitHandle.WaitOne(10) == false) { yield return(null); } faceGroupOutputSlots = GeneratorUtility.ResizeArray(faceGroupOutputSlots, faceGroupFaceIndices.Length, (int index) => { return(OutputSlot.CreateGrouped <FaceGroup>(this, string.Format("Face Group {0}", index), faceGroupCollectionOutputSlot.name, true, OutputSlot.Availability.DuringGeneration)); }, (OutputSlot output, int index) => { output.DisconnectAll(); output.path = faceGroupCollectionOutputSlot.name; return(output); }); var faceGroupCollection = FaceGroupCollection.Create(faceGroupFaceIndices.Length); for (int faceGroupIndex = 0; faceGroupIndex < faceGroupFaceIndices.Length; ++faceGroupIndex) { var faceGroup = ArrayFaceGroup.Create(topology, faceGroupFaceIndices[faceGroupIndex].ToArray()).SetName(faceGroupOutputSlots[faceGroupIndex].name); faceGroupCollection.faceGroups[faceGroupIndex] = faceGroupOutputSlots[faceGroupIndex].SetAsset(faceGroup); } faceGroupCollectionOutputSlot.SetAsset(faceGroupCollection); faceGroupIndicesOutputSlot.SetAsset(IntFaceAttribute.Create(faceGroupIndices.array)); yield break; }
public override IEnumerator BeginGeneration() { var surface = surfaceInputSlot.GetAsset <QuadrilateralSurface>(); var topology = topologyInputSlot.GetAsset <Topology>(); var facePositions = facePositionsInputSlot.GetAsset <IFaceAttribute <Vector3> >(); int groupCount = 0; var faceGroupFaceIndices = new List <int> [axisDivisions.x * axisDivisions.y]; var waitHandle = executive.GenerateConcurrently(() => { var axis0Vector = surface.axis0.vector; var axis1Vector = surface.axis1.vector; var surfaceNormal = Vector3.Cross(axis0Vector, axis1Vector).normalized; var axis0Normal = Vector3.Cross(axis0Vector, surfaceNormal).normalized; var axis1Normal = Vector3.Cross(axis1Vector, surfaceNormal).normalized; var axis0DividedVector = axis0Vector / axisDivisions.x; var axis1DividedVector = axis1Vector / axisDivisions.y; var axis0Dot = Vector3.Dot(axis1Normal, axis0DividedVector); var axis1Dot = Vector3.Dot(axis0Normal, axis1DividedVector); var origin = surface.origin; for (int i = 0; i < faceGroupFaceIndices.Length; ++i) { faceGroupFaceIndices[i] = new List <int>(); } foreach (var face in topology.internalFaces) { var facePosition = facePositions[face]; var axis0Offset = Vector3.Dot(axis1Normal, facePosition - origin) / axis0Dot; var axis1Offset = Vector3.Dot(axis0Normal, facePosition - origin) / axis1Dot; var axis0Index = Mathf.Clamp(Mathf.FloorToInt(axis0Offset), 0, axisDivisions.x - 1); var axis1Index = Mathf.Clamp(Mathf.FloorToInt(axis1Offset), 0, axisDivisions.y - 1); faceGroupFaceIndices[axis0Index + axis1Index * axisDivisions.x].Add(face.index); } foreach (var group in faceGroupFaceIndices) { if (group.Count > 0) { ++groupCount; } } }); while (waitHandle.WaitOne(10) == false) { yield return(null); } faceGroupOutputSlots = GeneratorUtility.ResizeArray(faceGroupOutputSlots, groupCount, (int index) => { return(null); }, (OutputSlot output, int index) => { output.DisconnectAll(); return(output); }); var faceGroupCollection = FaceGroupCollection.Create(groupCount); var faceGroupIndices = new int[topology.internalFaces.Count]; var groupIndex = 0; for (int axis1Index = 0; axis1Index < axisDivisions.y; ++axis1Index) { for (int axis0Index = 0; axis0Index < axisDivisions.x; ++axis0Index) { var group = faceGroupFaceIndices[axis0Index + axis1Index * axisDivisions.x]; if (group.Count > 0) { var faceGroupName = string.Format("Face Group [{0}, {1}]", axis0Index, axis1Index); var faceGroup = ArrayFaceGroup.Create(topology, group.ToArray()).SetName(faceGroupName); if (faceGroupOutputSlots[groupIndex] == null) { faceGroupOutputSlots[groupIndex] = OutputSlot.CreateGrouped <FaceGroup>(this, faceGroupName, faceGroupCollectionOutputSlot.name, true, OutputSlot.Availability.DuringGeneration); } else { faceGroupOutputSlots[groupIndex].name = faceGroupName; faceGroupOutputSlots[groupIndex].path = faceGroupCollectionOutputSlot.name; } faceGroupCollection.faceGroups[groupIndex] = faceGroupOutputSlots[groupIndex].SetAsset(faceGroup); foreach (var faceIndex in group) { faceGroupIndices[faceIndex] = groupIndex; } ++groupIndex; } } } faceGroupCollectionOutputSlot.SetAsset(faceGroupCollection); faceGroupIndicesOutputSlot.SetAsset(IntFaceAttribute.Create(faceGroupIndices)); yield break; }