コード例 #1
0
ファイル: HalfEdge.cs プロジェクト: Fabbseh/CuteHorrorGame
 private bool ShouldRemoveEdge(HEEdge edge, bool pairInOtherSide)
 {
     HEEdge pair = heEdges[edge.pair];
     return !pairInOtherSide || (pairInOtherSide && (pair.startVertex != edge.endVertex || pair.endVertex != edge.startVertex));
 }
コード例 #2
0
ファイル: HalfEdge.cs プロジェクト: Fabbseh/CuteHorrorGame
        /**
         * Analyzes the input mesh and populates the half-edge structure. Can be called as many times you want (for examples if the original mesh is modified).
         */
        public IEnumerator Generate()
        {
            if (input != null){

            heFaces.Clear();
            heVertices.Clear();
            heEdges.Clear();
            _area = 0;
            _modified = false;

            Dictionary<Vector3, HEVertex> vertexBuffer = new Dictionary<Vector3, HEVertex>();
            Dictionary<KeyValuePair<int,int>,HEEdge> edgeBuffer = new Dictionary<KeyValuePair<int,int>,HEEdge>();

            // Get copies of vertex and triangle buffers:
            Vector3[] vertices = input.vertices;
            int[] triangles = input.triangles;

            // first, create vertices:
            for(int i = 0; i < vertices.Length; i++){

                //if the vertex already exists, add physical vertex index to it.
                HEVertex vertex;
                if (vertexBuffer.TryGetValue(vertices[i], out vertex)){
                    vertex.physicalIDs.Add(i);
                }else{
                    vertex = new HEVertex(i);
                }

                vertexBuffer[vertices[i]] = vertex;

                if (i % 200 == 0)
                    yield return new CoroutineJob.ProgressInfo("Half-edge: analyzing vertices...",i/(float)vertices.Length);
            }

            // assign unique indices to vertices:
            int index = 0;
            foreach(KeyValuePair<Vector3,HEVertex> pair in vertexBuffer){
                ((HEVertex)pair.Value).index = index;
                heVertices.Add(pair.Value);
                if (index % 200 == 0)
                    yield return new CoroutineJob.ProgressInfo("Half-edge: assigning indices...",index/(float)vertices.Length);
                index++;
            }

            // build half edge structure:
            for(int i = 0; i<triangles.Length;i+=3){

                Vector3 pos1 = vertices[triangles[i]];
                Vector3 pos2 = vertices[triangles[i+1]];
                Vector3 pos3 = vertices[triangles[i+2]];

                HEVertex v1 = vertexBuffer[pos1];
                HEVertex v2 = vertexBuffer[pos2];
                HEVertex v3 = vertexBuffer[pos3];

                // create half edges:
                HEEdge e1 = new HEEdge();
                e1.index = heEdges.Count;
                e1.indexOnFace = 0;
                e1.faceIndex = heFaces.Count;
                e1.endVertex = v1.index;
                e1.startVertex = v2.index;

                HEEdge e2 = new HEEdge();
                e2.index = heEdges.Count+1;
                e2.indexOnFace = 1;
                e2.faceIndex = heFaces.Count;
                e2.endVertex = v2.index;
                e2.startVertex = v3.index;

                HEEdge e3 = new HEEdge();
                e3.index = heEdges.Count+2;
                e3.indexOnFace = 2;
                e3.faceIndex = heFaces.Count;
                e3.endVertex = v3.index;
                e3.startVertex = v1.index;

                // link half edges together:
                e1.nextEdgeIndex = e3.index;
                e2.nextEdgeIndex = e1.index;
                e3.nextEdgeIndex = e2.index;

                // vertex outgoing half edge indices:
                v1.halfEdgeIndex = e3.index;
                v2.halfEdgeIndex = e1.index;
                v3.halfEdgeIndex = e2.index;

                // add edges:
                heEdges.Add(e1);
                heEdges.Add(e2);
                heEdges.Add(e3);

                // populate and add face:
                HEFace face = new HEFace();
                face.edges[0] = e1.index;
                face.edges[1] = e2.index;
                face.edges[2] = e3.index;
                face.area = ObiUtils.TriangleArea(pos1,pos2,pos3);
                _area += face.area;
                _volume += Vector3.Dot(Vector3.Cross(pos1,pos2),pos3)/6f;
                face.index = heFaces.Count;
                heFaces.Add(face);

                try{
                    edgeBuffer.Add(new KeyValuePair<int,int>(v1.index,v2.index),e1);
                    edgeBuffer.Add(new KeyValuePair<int,int>(v2.index,v3.index),e2);
                    edgeBuffer.Add(new KeyValuePair<int,int>(v3.index,v1.index),e3);
                }catch{
                    Debug.LogError("Your mesh is non manifold, and thus cannot be processed by Obi: more than 1 edge joining the same pair of vertices.");
                    heFaces.Clear();
                    heVertices.Clear();
                    heEdges.Clear();
                    _area = 0;
                    yield break;
                }

                if (i % 500 == 0)
                    yield return new CoroutineJob.ProgressInfo("Half-edge: generating edges and faces...",i/(float)triangles.Length);

            }

            List<HEEdge> borderEdges = new List<HEEdge>();		//edges belonging to a mesh border.

            // stitch half edge pairs together:
            index = 0;
            foreach(KeyValuePair<KeyValuePair<int,int>,HEEdge> pair in edgeBuffer){

                KeyValuePair<int,int> edgeKey = new KeyValuePair<int,int>(pair.Key.Value,pair.Key.Key);

                HEEdge edge = null;
                if (edgeBuffer.TryGetValue(edgeKey, out edge)){
                    ((HEEdge)pair.Value).pair = edge.index;
                }else{

                    //create border edge:
                    HEEdge e = new HEEdge();
                    e.index = heEdges.Count;
                    e.endVertex = ((HEEdge)pair.Value).startVertex;
                    e.startVertex = ((HEEdge)pair.Value).endVertex;
                    heVertices[e.startVertex].halfEdgeIndex = e.index;
                    e.pair = ((HEEdge)pair.Value).index;
                    ((HEEdge)pair.Value).pair = e.index;
                    heEdges.Add(e);

                    borderEdges.Add(e);
                }

                if (index % 1000 == 0)
                    yield return new CoroutineJob.ProgressInfo("Half-edge: stitching half-edges...",index/(float)edgeBuffer.Count);

                index++;

            }

            _closed = borderEdges.Count == 0;

            // link together border edges:
            foreach(HEEdge edge in borderEdges){
                edge.nextEdgeIndex = heVertices[edge.endVertex].halfEdgeIndex;
            }

            }else{
            Debug.LogWarning("Tried to generate adjacency info for an empty mesh.");
            }
        }