protected override IEnumerator CreateDistanceConstraints()
        {
            // prepare an array that maps from half edge index to <batch, constraintId>
            distanceConstraintMap = new Vector2Int[topology.halfEdges.Count];
            for (int i = 0; i < distanceConstraintMap.Length; i++)
            {
                distanceConstraintMap[i] = new Vector2Int(-1, -1);
            }

            //Create distance constraints, one for each half-edge.
            distanceConstraintsData = new ObiDistanceConstraintsData();

            List <int> edges = topology.GetEdgeList();

            IEnumerator dc = CreateInitialDistanceConstraints(edges);

            while (dc.MoveNext())
            {
                yield return(dc.Current);
            }

            dc = CreatePooledDistanceConstraints(edges);
            while (dc.MoveNext())
            {
                yield return(dc.Current);
            }
        }
        protected virtual IEnumerator CreateDistanceConstraints()
        {
            //Create distance constraints:
            List <int> edges = topology.GetEdgeList();

            distanceConstraintsData = new ObiDistanceConstraintsData();

            List <int> particleIndices   = new List <int>();
            List <int> constraintIndices = new List <int>();

            for (int i = 0; i < edges.Count; i++)
            {
                HalfEdgeMesh.HalfEdge hedge = topology.halfEdges[edges[i]];

                particleIndices.Add(topology.GetHalfEdgeStartVertex(hedge));
                particleIndices.Add(hedge.endVertex);
                constraintIndices.Add(constraintIndices.Count * 2);

                if (i % 500 == 0)
                {
                    yield return(new CoroutineJob.ProgressInfo("ObiCloth: generating structural constraints...", i / (float)edges.Count));
                }
            }
            constraintIndices.Add(constraintIndices.Count * 2);

            int[] constraintColors = GraphColoring.Colorize(particleIndices.ToArray(), constraintIndices.ToArray());
            for (int i = 0; i < constraintColors.Length; ++i)
            {
                int color  = constraintColors[i];
                int cIndex = constraintIndices[i];

                // Add a new batch if needed:
                if (color >= distanceConstraintsData.GetBatchCount())
                {
                    distanceConstraintsData.AddBatch(new ObiDistanceConstraintsBatch());
                }

                HalfEdgeMesh.HalfEdge hedge       = topology.halfEdges[edges[i]];
                HalfEdgeMesh.Vertex   startVertex = topology.vertices[topology.GetHalfEdgeStartVertex(hedge)];
                HalfEdgeMesh.Vertex   endVertex   = topology.vertices[hedge.endVertex];

                distanceConstraintsData.batches[color].AddConstraint(new Vector2Int(particleIndices[cIndex], particleIndices[cIndex + 1]),
                                                                     Vector3.Distance(Vector3.Scale(scale, startVertex.position), Vector3.Scale(scale, endVertex.position)));
            }

            // Set initial amount of active constraints:
            for (int i = 0; i < distanceConstraintsData.batches.Count; ++i)
            {
                distanceConstraintsData.batches[i].activeConstraintCount = distanceConstraintsData.batches[i].constraintCount;
            }
        }
示例#3
0
        public IEnumerator Generate()
        {
            m_Empty = true;

            m_ActiveParticleCount        = 0;
            distanceConstraintsData      = null;
            bendConstraintsData          = null;
            skinConstraintsData          = null;
            tetherConstraintsData        = null;
            bendTwistConstraintsData     = null;
            stretchShearConstraintsData  = null;
            shapeMatchingConstraintsData = null;
            aerodynamicConstraintsData   = null;
            chainConstraintsData         = null;
            volumeConstraintsData        = null;

            points    = null;
            edges     = null;
            triangles = null;

            IEnumerator g = Initialize();

            while (g.MoveNext())
            {
                yield return(g.Current);
            }

            RecalculateBounds();

            m_Empty = false;
            m_InitialActiveParticleCount = m_ActiveParticleCount;

            foreach (IObiConstraints constraints in GetConstraints())
            {
                for (int i = 0; i < constraints.GetBatchCount(); ++i)
                {
                    constraints.GetBatch(i).initialActiveConstraintCount = constraints.GetBatch(i).activeConstraintCount;
                }
            }

#if UNITY_EDITOR
            EditorUtility.SetDirty(this);
#endif

            if (OnBlueprintGenerate != null)
            {
                OnBlueprintGenerate(this);
            }
        }
示例#4
0
        protected virtual IEnumerator CreateDistanceConstraints()
        {
            distanceConstraintsData = new ObiDistanceConstraintsData();

            // Add two batches: for even and odd constraints:
            distanceConstraintsData.AddBatch(new ObiDistanceConstraintsBatch());
            distanceConstraintsData.AddBatch(new ObiDistanceConstraintsBatch());

            for (int i = 0; i < totalParticles - 1; i++)
            {
                var batch = distanceConstraintsData.batches[i % 2] as ObiDistanceConstraintsBatch;

                if (i < m_ActiveParticleCount - 1)
                {
                    Vector2Int indices = new Vector2Int(i, i + 1);
                    restLengths[i] = Vector3.Distance(positions[indices.x], positions[indices.y]);
                    batch.AddConstraint(indices, restLengths[i]);
                    batch.activeConstraintCount++;
                }
                else
                {
                    restLengths[i] = m_InterParticleDistance;
                    batch.AddConstraint(Vector2Int.zero, 0);
                }

                if (i % 500 == 0)
                {
                    yield return(new CoroutineJob.ProgressInfo("ObiRope: generating structural constraints...", i / (float)(totalParticles - 1)));
                }
            }

            // if the path is closed, add the last, loop closing constraint to a new batch to avoid sharing particles.
            if (path.Closed)
            {
                var loopClosingBatch = new ObiDistanceConstraintsBatch();
                distanceConstraintsData.AddBatch(loopClosingBatch);

                Vector2Int indices = new Vector2Int(m_ActiveParticleCount - 1, 0);
                restLengths[m_ActiveParticleCount - 2] = Vector3.Distance(positions[indices.x], positions[indices.y]);
                loopClosingBatch.AddConstraint(indices, restLengths[m_ActiveParticleCount - 2]);
                loopClosingBatch.activeConstraintCount++;
            }
        }
示例#5
0
 public ObiDistanceConstraintsData(ObiActor actor = null, ObiDistanceConstraintsData source = null) : base(actor, source)
 {
 }
示例#6
0
 public ObiDistanceConstraintsBatch(ObiDistanceConstraintsData constraints = null, ObiDistanceConstraintsBatch source = null) : base(source)
 {
     m_Constraints = constraints;
 }