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;
        }
예제 #2
0
        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;
        }
예제 #3
0
        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;
        }