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 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() { 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; }