Ejemplo n.º 1
0
 public Vertex FindVertexUnder(Vector3 vPosition)
 {
     for (int v = mlVertices.Count - 1; v >= 0; v--)
     {
         Vertex vertex = mlVertices[v];
         if (vertex.IsUnder(vPosition))
         {
             return(vertex);
         }
     }
     return(null);
 }
Ejemplo n.º 2
0
        private IEnumerator PunchOutStep2(XZPolygon polygon)
        {
            Profiler.BeginSample("PunchOutStep2");

            float fTimeWhenStartedChunk = Time.realtimeSinceStartup;

            // (2) Create additional mesh lines corresponding to the polygon lines
            int    iSegmentIndex    = 0;
            Vertex currentVertex    = FindVertexUnder(polygon.maPoints[0]);
            int    iSecurityCounter = 0;

            while (iSegmentIndex < polygon.maPoints.Length - 1 && iSecurityCounter++ < 10000)
            {
                // Coroutine time management
                if (Time.realtimeSinceStartup - fTimeWhenStartedChunk > MAX_TIME_CHUNK)
                {
                    // Enough done this frame, go on holiday
                    yield return(null);

                    // Back from holyday
                    fTimeWhenStartedChunk = Time.realtimeSinceStartup;
                }


                //                            P---------------R
                //                          /  \ triangle2  //
                //                        /     \         / /
                //                \     /        \     /   /
                //                 \  / triangle1 \  /    /
                //    currentVertex * -------------X--   /
                //                  |\ ' -  _       \   /
                //                  | \        -  _  \ /
                //                                  - Q
                //



                Vector3 vPosition  = currentVertex.mvPos;
                Vector3 vDirection = polygon.maPoints[iSegmentIndex + 1] - vPosition;

                // A saveguard for some nasty infinitely-go-and-fro-between-two-vertices cases
                while (Vector3.Dot(vDirection, polygon.maPoints[iSegmentIndex + 1] - polygon.maPoints[iSegmentIndex]) < 0)
                {
                    Debug.Log("Wait, wait, we're going into the wrong direction");
                    iSegmentIndex++;
                    vDirection = polygon.maPoints[iSegmentIndex + 1] - vPosition;
                }
                vDirection.y = 0.0f;

                if (iSecurityCounter == 9999)
                {
                    Debug.DrawLine(vPosition - Vector3.up, vPosition + Vector3.up, Color.magenta, 1000.0f);
                    Debug.Log("Endless loop?");
                    Debug.Break();
                }

                if (iSecurityCounter > 9980)
                {
                    Debug.DrawLine(vPosition - Vector3.up * 0.5f, vPosition + Vector3.up * 0.5f, Color.white, 1000.0f);
                    currentVertex.DebugLogInfo("Current vertex", Vector3.zero);
                }

                if (vDirection * 1.0e6f == Vector3.zero)
                {
                    Debug.LogError("vDirection is zero. ");
                }


                if (iSegmentIndex + 1 < maVerticesUnderPolygonPoints.Length && maVerticesUnderPolygonPoints[iSegmentIndex + 1].IsNeighbourOf(currentVertex))
                {
                    currentVertex = maVerticesUnderPolygonPoints[iSegmentIndex + 1];
                    iSegmentIndex++;
                }
                else
                {
                    // Check if there is a neighbor vertex just in this direction
                    Vertex N = currentVertex.GetNeighbourVertexInDirection(vDirection);


                    if (N != null)
                    {
                        // No subdivision required, just procede to vertex N

                        if (N.IsUnder(polygon.maPoints[iSegmentIndex + 1]))
                        {
                            // We reach a corner
                            iSegmentIndex++;
                        }

                        currentVertex = N;
                    }
                    else
                    {
                        // Search the vertices P, Q and the triangles triangle1 and triangle2
                        Vertex   P;
                        Vertex   Q;
                        Triangle triangle1 = currentVertex.GetAdjacentTriangleInDirection(vDirection, out P, out Q);
                        if (triangle1 == null)
                        {
                            Debug.LogError("Couldn't find triangle under polygon.");
                            currentVertex.DebugLogInfo("Current vertex ", Vector3.zero);
                            currentVertex.DebugDrawAdjacentTriangles(Color.red);
                            iSegmentIndex = polygon.maPoints.Length;
                            break;
                        }
                        Triangle triangle2 = triangle1.GetNeighbourTriangleBehind(P, Q);
                        if (triangle2 == null)
                        {
                            Debug.LogError("Couldn't find triangle 'behind' the one under polygon");
                            currentVertex.DebugDrawAdjacentTriangles(Color.yellow);
                            iSegmentIndex = polygon.maPoints.Length;
                            break;
                        }
                        Vertex R = triangle2.GetThirdCorner(P, Q);

                        //Compute X
                        float   fCutRatio;
                        Vector3 vX = GeometryToolbox.CutSegmentByLine(P.mvPos, Q.mvPos, vPosition, vPosition + vDirection, out fCutRatio);


                        // Sometimes the cut ratio is very close to 0 or 1, even if this should theoretically not happen. In this case we do the same thing as above in the case "N != null"
                        if (fCutRatio < 0.001f)
                        {
                            // Don't need a new point, P is fine
                            if (P.IsUnder(polygon.maPoints[iSegmentIndex + 1]))
                            {
                                // We reach a corner
                                iSegmentIndex++;
                            }
                            currentVertex = P;
                        }
                        else if (fCutRatio > 0.999f)
                        {
                            // Same for Q
                            if (Q.IsUnder(polygon.maPoints[iSegmentIndex + 1]))
                            {
                                // We reach a corner
                                iSegmentIndex++;
                            }
                            currentVertex = Q;
                        }
                        else
                        {
                            // Add vertex
                            Vertex X = AddVertex(vX);
                            X.mvUV = Vector2.Lerp(P.mvUV, Q.mvUV, fCutRatio);

#if UNITY_EDITOR
                            X.DEBUG_INFO = "added on line in step 2, fCutRatio = " + fCutRatio;
#endif

                            // Replace triangle1
                            RemoveTriangle(triangle1);
                            AddTriangle(currentVertex, X, P);
                            AddTriangle(currentVertex, Q, X);

                            // Replace triangle2
                            RemoveTriangle(triangle2);
                            AddTriangle(X, Q, R);
                            AddTriangle(X, R, P);


                            // Go on
                            if ((currentVertex.mvPos - P.mvPos).magnitude < 0.00001f)
                            {
                                //currentVertex vertex is very near to P - goto on.
                                currentVertex = P;
                            }
                            else if ((currentVertex.mvPos - Q.mvPos).magnitude < 0.00001f)
                            {
                                // Idem for Q
                                currentVertex = Q;
                            }
                            else if (R.IsUnder(polygon.maPoints[iSegmentIndex + 1]))
                            {
                                // We reach a corner
                                currentVertex = R;
                                iSegmentIndex++;
                            }
                            else
                            {
                                currentVertex = X;
                            }

                            while (iSegmentIndex + 1 < polygon.maPoints.Length && currentVertex.IsUnder(polygon.maPoints[iSegmentIndex + 1]))
                            {
                                iSegmentIndex++;
                            }
                        }
                    }
                }
                //  Debug.DrawLine( vPosition, currentVertex.mvPos, Color.red, 1000.0f);
            }

            // maVerticesUnderPolygonPoints is not needed anymore
            maVerticesUnderPolygonPoints = new Vertex[0];


            Profiler.EndSample();
        }