예제 #1
0
        public static int StringPull(Vector3[] portals, int nportalPts, Vector3[] pts, int maxPts)
        {
            // Find straight path.
            int npts = 0;
            // Init scan state
            Vector3 portalApex = portals[0];
            Vector3 portalLeft = portals[2];
            Vector3 portalRight = portals[3];
            int     apexIndex = 0, leftIndex = 0, rightIndex = 0;

            // Add start point.
            pts[0] = portalApex;
            npts++;

            for (int i = 1; ((i < (nportalPts / 2)) && (npts < maxPts)); ++i)
            {
                Vector3 left  = portals[i * 2 + 0];
                Vector3 right = portals[i * 2 + 1];

                // Update right vertex.
                if (TriArea2(portalApex, portalRight, right) <= 0.0f)
                {
                    if (PathUtils.AreVertsTheSame(portalApex, portalRight) || TriArea2(portalApex, portalLeft, right) > 0.0f)
                    {
                        // Tighten the funnel.
                        portalRight = right;
                        rightIndex  = i;
                    }
                    else
                    {
                        // Right over left, insert left to path and restart scan from portal left point.
                        pts[npts] = portalLeft;
                        npts++;
                        // Make current left the new apex.
                        portalApex = portalLeft;
                        apexIndex  = leftIndex;
                        // Reset portal
                        portalLeft  = portalApex;
                        portalRight = portalApex;
                        leftIndex   = apexIndex;
                        rightIndex  = apexIndex;
                        // Restart scan
                        i = apexIndex;
                        continue;
                    }
                }

                // Update left vertex.
                if (TriArea2(portalApex, portalLeft, left) >= 0.0f)
                {
                    if (PathUtils.AreVertsTheSame(portalApex, portalLeft) || TriArea2(portalApex, portalRight, left) < 0.0f)
                    {
                        // Tighten the funnel.
                        portalLeft = left;
                        leftIndex  = i;
                    }
                    else
                    {
                        // Left over right, insert right to path and restart scan from portal right point.
                        pts[npts] = portalRight;
                        npts++;
                        // Make current right the new apex.
                        portalApex = portalRight;
                        apexIndex  = rightIndex;
                        // Reset portal
                        portalLeft  = portalApex;
                        portalRight = portalApex;
                        leftIndex   = apexIndex;
                        rightIndex  = apexIndex;
                        // Restart scan
                        i = apexIndex;
                        continue;
                    }
                }
            }

            // Append last point to path.
            if (npts < maxPts)
            {
                pts[npts] = portals[nportalPts - 1];
                npts++;
            }

            return(npts);
        }