Beispiel #1
0
        public void TestUnorderedPairGetters()
        {
            IPair a = new UnorderedPair(1, 2);

            Assert.IsTrue(a.First.Equals(1));
            Assert.IsTrue(a.Second.Equals(2));
        }
Beispiel #2
0
        private void DeleteEdge(UnorderedPair <ISceneNode> key)
        {
            var gizmo = edgeGizmos[key];

            edgeGizmos.Remove(key);
            Node.ChildNodes.Remove(gizmo);
        }
Beispiel #3
0
        public void TestInterPairEquals()
        {
            IPair a = new OrderedPair(1, 2);
            IPair b = new UnorderedPair(1, 2);

            Assert.IsTrue(!a.Equals(b));
            Assert.IsTrue(!b.Equals(a));
        }
Beispiel #4
0
        private void AddNewEdge(UnorderedPair <ISceneNode> key, IStandardMaterial material, IStandardRenderState renderState)
        {
            var gizmo = AmFactory.Factory.CreateWorldNodeWithComponent <StoryFlowchartEdgeGizmoComponent>(out var component);

            gizmo.Name            = $"EdgeGizmo({key.First}->{key.Second})";
            component.Material    = material;
            component.RenderState = renderState;
            edgeGizmos.Add(key, gizmo);
            Node.ChildNodes.Add(gizmo);
        }
        public override bool Equals(object obj)
        {
            if (obj is UnorderedPair <FirstType, SecondType> )
            {
                UnorderedPair <FirstType, SecondType> pair = (UnorderedPair <FirstType, SecondType>)obj;
                return(base.Equals(pair) || (EqualsFirstSecond(pair) && EqualsSecondFirst(pair)));
            }

            return(false);
        }
Beispiel #6
0
        public void SelectEdgeLoop(ICollection <UnorderedPair <int> > edges, UnorderedPair <int> start, bool recurses = true)
        {
            UpdateGraph();
            edges.Add(start);

            int prev = start.Item1;
            int cur  = start.Item2;

            while (true)
            {
                UnorderedPair <int> curEdge = new UnorderedPair <int>(prev, cur);

                if (vertexNeighbors[cur].Count != 4)
                {
                    break;
                }

                bool found = false;
                foreach (var v in vertexNeighbors[cur])
                {
                    var e = new UnorderedPair <int>(cur, v);

                    bool ok = true;
                    foreach (int f in edgeFaces[e])
                    {
                        if (edgeFaces[curEdge].Contains(f))
                        {
                            ok = false;
                            break;
                        }
                    }

                    if (ok)
                    {
                        found = true;
                        edges.Add(e);
                        prev = cur;
                        cur  = e.Not(cur);
                        break;
                    }
                }

                if (!found || cur == start.Item1)
                {
                    break;
                }
            }

            if (recurses && cur != start.Item1)
            {
                SelectEdgeLoop(edges, new UnorderedPair <int>(start.Item2, start.Item1), false);
            }
        }
Beispiel #7
0
        private bool IsNotInnerEdge(UnorderedPair <int> edge, ICollection <int> faceIndices)
        {
            foreach (var neighbor in edgeFaces[edge])
            {
                if (!faceIndices.Contains(neighbor))
                {
                    return(true);
                }
            }

            return(false);
        }
Beispiel #8
0
        public void TestUnorderedPairEquals()
        {
            IPair a = new UnorderedPair(1, 2);

            Assert.IsTrue(a.Equals(a));
            Assert.IsTrue(!a.Equals(null));
            IPair b = new UnorderedPair(1, 2);

            Assert.IsTrue(a.Equals(b));
            Assert.IsTrue(b.Equals(a));
            Assert.IsTrue(a.GetHashCode() == b.GetHashCode());
            IPair c = new UnorderedPair(2, 1);

            Assert.IsTrue(a.Equals(c));
            Assert.IsTrue(c.Equals(a));
            Assert.IsTrue(a.GetHashCode() == c.GetHashCode());
        }
Beispiel #9
0
        public void unordered_pair_pinning_test()
        {
            var pair1        = new UnorderedPair <Point>(new Point(0, 1), new Point(5, 5));
            var sameAsPair1  = new UnorderedPair <Point>(new Point(0, 1), new Point(5, 5));
            var p1           = new Point(5, 5);
            var p2           = new Point(0, 1);
            var pair1Flipped = new UnorderedPair <Point>(p1, p2);
            var pair2        = new UnorderedPair <Point>(new Point(0, -5), new Point(5, 5));

            Assert.True(pair1.Equals(pair1), "UnorderedPair.Equals works on self");
            Assert.True(pair1.Equals(sameAsPair1), "UnorderedPair.Equals works on identical set");
            Assert.True(pair1.Equals(pair1Flipped), "UnorderedPair.Equals works on flipped set");
            Assert.False(pair1.Equals(pair2), "UnorderedPair.Equals should be false for 2 different pairs");

            Assert.True(pair1 == sameAsPair1, "UnorderedPair == works on identical set");
            Assert.True(pair1 == pair1Flipped, "UnorderedPair == works on flipped set");
            Assert.False(pair1 == pair2, "UnorderedPair == should be false for 2 different pairs");
        }
Beispiel #10
0
        private void InsertVertex(Face face, UnorderedPair <int> edge, int vertex)
        {
            int i1 = face.vertices.IndexOf(edge.Item1);
            int i2 = face.vertices.IndexOf(edge.Item2);

            if (i2 == (i1 + 1) % face.vertices.Count)
            {
                face.vertices.Insert(i1 + 1, vertex);
                graphDirty = true;
            }
            else if (i1 == (i2 + 1) % face.vertices.Count)
            {
                face.vertices.Insert(i2 + 1, vertex);
                graphDirty = true;
            }
            else
            {
                Debug.Log("Vertex not inserted!");
            }
        }
Beispiel #11
0
        public List <UnorderedPair <int> > GetEdges()
        {
            List <UnorderedPair <int> > edges = new List <UnorderedPair <int> >();

            foreach (var f in faces)
            {
                for (int i = 0; i < f.vertices.Count; i++)
                {
                    int j = (i + 1) % f.vertices.Count;

                    UnorderedPair <int> edge = new UnorderedPair <int>(f.vertices[i], f.vertices[j]);

                    if (!edges.Contains(edge))
                    {
                        edges.Add(edge);
                    }
                }
            }

            return(edges);
        }
Beispiel #12
0
        private bool IsOuterEdge(UnorderedPair <int> edge, ICollection <int> faceIndices)
        {
            bool outer = false, inner = false;

            foreach (var neighbor in edgeFaces[edge])
            {
                if (!faceIndices.Contains(neighbor))
                {
                    outer = true;
                }
                else
                {
                    inner = true;
                }

                if (outer && inner)
                {
                    return(true);
                }
            }

            return(false);
        }
Beispiel #13
0
        private bool GetEdgeOrder(UnorderedPair <int> edge, out int t1, out int t2)
        {
            UpdateGraph();

            var n = edgeFaces[edge];

            if (n.Count != 1)
            {
                t1 = -1;
                t2 = -1;
                return(false);
            }

            Face f = faces[n[0]];

            int ind1 = f.vertices.IndexOf(edge.Item1);
            int ind2 = f.vertices.IndexOf(edge.Item2);

            if (ind2 == (ind1 + 1) % f.vertices.Count)
            {
                t1 = edge.Item2;
                t2 = edge.Item1;
                return(true);
            }
            else if (ind1 == (ind2 + 1) % f.vertices.Count)
            {
                t1 = edge.Item1;
                t2 = edge.Item2;
                return(true);
            }
            else
            {
                t1 = -1;
                t2 = -1;
                return(false);
            }
        }
Beispiel #14
0
        public bool InsertLoop(ICollection <UnorderedPair <int> > edges)
        {
            if (edges.Count != 1)
            {
                return(false);
            }

            UpdateGraph();

            var iter = edges.GetEnumerator();

            iter.MoveNext();
            var edge = iter.Current;

            iter.Dispose();

            List <UnorderedPair <int> > edgeLoop = new List <UnorderedPair <int> > {
                edge
            };
            List <int> faceLoop = new List <int> {
                edgeFaces[edge][0]
            };

            bool oneSide = false;

            while (true)
            {
                int cnt = faceLoop.Count;
                int cur = faceLoop[cnt - 1];

                foreach (var e in faceEdges[cur])
                {
                    if (!e.Adjacent(edgeLoop[edgeLoop.Count - 1]))
                    {
                        edgeLoop.Add(e);

                        if (e == edgeLoop[0])
                        {
                            break;
                        }

                        var ef = edgeFaces[e];

                        foreach (int f in ef)
                        {
                            if (f != cur && faceEdges[f].Count == 4 && f != faceLoop[0])
                            {
                                faceLoop.Add(f);
                                break;
                            }
                        }

                        break;
                    }
                }

                if (faceLoop.Count == cnt || edgeLoop[edgeLoop.Count - 1] == edgeLoop[0])
                {
                    oneSide = edgeLoop[edgeLoop.Count - 1] != edgeLoop[0];
                    break;
                }
            }

            if (oneSide)
            {
                while (true)
                {
                    int cnt = faceLoop.Count;
                    var cur = edgeLoop[0];

                    foreach (int f in edgeFaces[cur])
                    {
                        if (f != faceLoop[0] && faceEdges[f].Count == 4)
                        {
                            faceLoop.Insert(0, f);

                            foreach (var e in faceEdges[f])
                            {
                                if (!e.Adjacent(cur))
                                {
                                    edgeLoop.Insert(0, e);
                                    break;
                                }
                            }

                            break;
                        }
                    }

                    if (faceLoop.Count == cnt)
                    {
                        break;
                    }
                }
            }

            List <int> addedVerts = new List <int>();

            for (int i = 0; i < faceLoop.Count; i++)
            {
                Face face = faces[faceLoop[i]];
                UnorderedPair <int> edge1 = edgeLoop[i];
                UnorderedPair <int> edge2 = edgeLoop[i + 1];

                int v1, v2;

                if (i == 0)
                {
                    v1 = AddVertex(GetEdgeCenter(edge1));
                    addedVerts.Add(v1);
                }
                else
                {
                    v1 = addedVerts[addedVerts.Count - 1];
                }

                if (i == faceLoop.Count - 1 && edge2 == edgeLoop[0])
                {
                    v2 = addedVerts[0];
                }
                else
                {
                    v2 = AddVertex(GetEdgeCenter(edge2));
                    addedVerts.Add(v2);
                }

                Face newFace = new Face();
                newFace.vertices = new List <int>();

                InsertVertex(face, edge1, v1);
                InsertVertex(face, edge2, v2);

                int ind1 = face.vertices.IndexOf(v1);
                int ind2 = face.vertices.IndexOf(v2);

                if (ind1 == -1 || ind2 == -1)
                {
                    Debug.LogError("Could not insert vertex");
                    continue;
                }

                for (int j = ind1; j != (ind2 + 1) % face.vertices.Count; j = (j + 1) % face.vertices.Count)
                {
                    newFace.vertices.Add(face.vertices[j]);

                    if (j != ind1 && j != ind2)
                    {
                        face.vertices[j] = -1;
                    }
                }

                face.vertices.RemoveAll(v => v < 0);
                faces.Add(newFace);
            }

            graphDirty = true;
            return(true);
        }
Beispiel #15
0
 public Vector3 GetEdgeCenter(UnorderedPair <int> edge)
 {
     return((vertices[edge.Item1].position + vertices[edge.Item2].position) / 2.0f);
 }
Beispiel #16
0
        private bool EdgesAreContiguous(ICollection <UnorderedPair <int> > edges, out List <int> vertices)
        {
            UpdateGraph();
            var iter = edges.GetEnumerator();

            iter.MoveNext();
            var edge = iter.Current;

            iter.Dispose();

            int t1, t2;

            if (!GetEdgeOrder(edge, out t1, out t2))
            {
                vertices = null;
                return(false);
            }

            vertices = new List <int> {
                t1, t2
            };

            for (int i = 1; i < edges.Count; i++)
            {
                int prev = vertices[vertices.Count - 2];
                int cur  = vertices[vertices.Count - 1];

                var curEdge = new UnorderedPair <int>(prev, cur);

                if (edgeFaces[curEdge].Count > 1)
                {
                    vertices = null;
                    return(false);
                }

                bool found = false;
                foreach (var e in edges)
                {
                    if (e == curEdge || (e.Item1 != cur && e.Item2 != cur))
                    {
                        continue;
                    }
                    int next = e.Not(cur);

                    if (next == vertices[0])
                    {
                        if (i == edges.Count - 1)
                        {
                            return(true);
                        }
                        else
                        {
                            vertices = null;
                            return(false);
                        }
                    }

                    vertices.Add(next);
                    found = true;
                    break;
                }

                if (found)
                {
                    continue;
                }
                vertices = null;
                return(false);
            }

            vertices = null;
            return(false);
        }
Beispiel #17
0
        private void UpdateGraph()
        {
            if (!graphDirty)
            {
                return;
            }
            edgeFaces       = new Dictionary <UnorderedPair <int>, List <int> >();
            vertexNeighbors = new Dictionary <int, HashSet <int> >();
            vertexFaces     = new Dictionary <int, HashSet <int> >();
            faceEdges       = new Dictionary <int, HashSet <UnorderedPair <int> > >();

            for (int i = 0; i < faces.Count; i++)
            {
                Face face = faces[i];

                for (int j = 0; j < face.vertices.Count; j++)
                {
                    int next = face.vertices[(j + 1) % face.vertices.Count];
                    int prev = face.vertices[((j - 1) + face.vertices.Count) % face.vertices.Count];

                    int vert = face.vertices[j];
                    if (!vertexFaces.ContainsKey(vert))
                    {
                        vertexFaces[vert] = new HashSet <int>();
                    }

                    vertexFaces[vert].Add(i);

                    if (!vertexNeighbors.ContainsKey(vert))
                    {
                        vertexNeighbors[vert] = new HashSet <int>();
                    }

                    vertexNeighbors[vert].Add(prev);
                    vertexNeighbors[vert].Add(next);

                    UnorderedPair <int> edge1 = new UnorderedPair <int>(prev, vert);

                    if (!edgeFaces.ContainsKey(edge1))
                    {
                        edgeFaces[edge1] = new List <int>();
                    }

                    edgeFaces[edge1].Add(i);
                }
            }

            foreach (var pair in edgeFaces)
            {
                foreach (var face in pair.Value)
                {
                    if (!faceEdges.ContainsKey(face))
                    {
                        faceEdges[face] = new HashSet <UnorderedPair <int> >();
                    }

                    faceEdges[face].Add(pair.Key);
                }
            }

            graphDirty = false;
        }
 private bool EqualsSecondFirst(UnorderedPair <FirstType, SecondType> pair)
 {
     return(((m_second == null) && (pair.m_first == null)) ||
            ((m_second != null) && (pair.m_first != null) &&
             m_second.Equals(pair.m_first)));
 }
Beispiel #19
0
 public bool Adjacent(UnorderedPair <T> other)
 {
     return(Contains(other.t1) || Contains(other.t2));
 }
        // done!
        internal static void UnweightedMinimizeOld <T, S>(DFSA <T, S> dfsa)
        {
            ICollection <DFSAState <T, S> > states = dfsa.States();
            IDictionary <UnorderedPair <DFSAState <T, S>, DFSAState <T, S> >, IList <UnorderedPair <DFSAState <T, S>, DFSAState <T, S> > > > stateUPairToDependentUPairList = Generics.NewHashMap(states.Count * states.Count / 2 + 1);
            IDictionary <UnorderedPair <DFSAState <T, S>, DFSAState <T, S> >, bool> stateUPairToDistinguished = Generics.NewHashMap(states.Count * states.Count / 2 + 1);

            int[] c          = new int[states.Count * states.Count / 2 + 1];
            int   streak     = 0;
            int   collisions = 0;
            int   entries    = 0;
            long  time       = Runtime.CurrentTimeMillis();

            if (debug)
            {
                time = Runtime.CurrentTimeMillis();
                log.Info("Starting on " + dfsa.dfsaID);
                log.Info(" -- " + states.Count + " states.");
            }
            // initialize grid
            int numDone = 0;

            foreach (DFSAState <T, S> state1 in states)
            {
                foreach (DFSAState <T, S> state2 in states)
                {
                    UnorderedPair <DFSAState <T, S>, DFSAState <T, S> > up = new UnorderedPair <DFSAState <T, S>, DFSAState <T, S> >(state1, state2);
                    if (state1.Equals(state2))
                    {
                        continue;
                    }
                    if (stateUPairToDistinguished.Contains(up))
                    {
                        continue;
                    }
                    int bucket = (up.GetHashCode() & unchecked ((int)(0x7FFFFFFF))) % (states.Count * states.Count / 2 + 1);
                    c[bucket]++;
                    entries++;
                    if (c[bucket] > 1)
                    {
                        collisions++;
                        streak = 0;
                    }
                    else
                    {
                        streak++;
                    }
                    if (state1.IsAccepting() != state2.IsAccepting())
                    {
                        //log.info(Utils.pad((String)state1.stateID, 20)+" "+state2.stateID);
                        stateUPairToDistinguished[up] = true;
                    }
                    else
                    {
                        stateUPairToDistinguished[up] = false;
                    }
                }
                //stateUPairToDependentUPairList.put(up, new ArrayList());
                numDone++;
                if (numDone % 20 == 0)
                {
                    log.Info("\r" + numDone + "  " + ((double)collisions / (double)entries));
                }
            }
            if (debug)
            {
                log.Info("\nInitialized: " + (Runtime.CurrentTimeMillis() - time));
                time = Runtime.CurrentTimeMillis();
            }
            // visit each undistinguished pair
            foreach (UnorderedPair <DFSAState <T, S>, DFSAState <T, S> > up_1 in stateUPairToDistinguished.Keys)
            {
                DFSAState <T, S> state1_1 = up_1.first;
                DFSAState <T, S> state2   = up_1.second;
                if (stateUPairToDistinguished[up_1].Equals(true))
                {
                    continue;
                }
                // check if some input distinguishes this pair
                ICollection <T> inputs = Generics.NewHashSet(state1_1.ContinuingInputs());
                Sharpen.Collections.AddAll(inputs, state2.ContinuingInputs());
                bool distinguishable = false;
                ICollection <UnorderedPair <DFSAState <T, S>, DFSAState <T, S> > > pendingUPairs = Generics.NewHashSet();
                IEnumerator <T> inputI = inputs.GetEnumerator();
                while (inputI.MoveNext() && !distinguishable)
                {
                    T input = inputI.Current;
                    DFSATransition <T, S> transition1 = state1_1.Transition(input);
                    DFSATransition <T, S> transition2 = state2.Transition(input);
                    if ((transition1 == null) != (transition2 == null))
                    {
                        distinguishable = true;
                    }
                    if (transition1 != null && transition2 != null)
                    {
                        DFSAState <T, S> target1 = transition1.GetTarget();
                        DFSAState <T, S> target2 = transition2.GetTarget();
                        UnorderedPair <DFSAState <T, S>, DFSAState <T, S> > targetUPair = new UnorderedPair <DFSAState <T, S>, DFSAState <T, S> >(target1, target2);
                        if (!target1.Equals(target2))
                        {
                            if (stateUPairToDistinguished[targetUPair].Equals(true))
                            {
                                distinguishable = true;
                            }
                            else
                            {
                                pendingUPairs.Add(targetUPair);
                            }
                        }
                    }
                }
                // if the pair is distinguishable, record that
                if (distinguishable)
                {
                    IList <UnorderedPair <DFSAState <T, S>, DFSAState <T, S> > > markStack = new List <UnorderedPair <DFSAState <T, S>, DFSAState <T, S> > >();
                    markStack.Add(up_1);
                    while (!markStack.IsEmpty())
                    {
                        UnorderedPair <DFSAState <T, S>, DFSAState <T, S> > upToMark = markStack[markStack.Count - 1];
                        markStack.Remove(markStack.Count - 1);
                        stateUPairToDistinguished[upToMark] = true;
                        IList <UnorderedPair <DFSAState <T, S>, DFSAState <T, S> > > addList = stateUPairToDependentUPairList[upToMark];
                        if (addList != null)
                        {
                            Sharpen.Collections.AddAll(markStack, addList);
                            stateUPairToDependentUPairList[upToMark].Clear();
                        }
                    }
                }
                else
                {
                    // otherwise add it to any pending pairs
                    foreach (UnorderedPair <DFSAState <T, S>, DFSAState <T, S> > pendingUPair in pendingUPairs)
                    {
                        IList <UnorderedPair <DFSAState <T, S>, DFSAState <T, S> > > dependentList = stateUPairToDependentUPairList[pendingUPair];
                        if (dependentList == null)
                        {
                            dependentList = new List <UnorderedPair <DFSAState <T, S>, DFSAState <T, S> > >();
                            stateUPairToDependentUPairList[pendingUPair] = dependentList;
                        }
                        dependentList.Add(up_1);
                    }
                }
            }
            if (debug)
            {
                log.Info("All pairs marked: " + (Runtime.CurrentTimeMillis() - time));
                time = Runtime.CurrentTimeMillis();
            }
            // decide what canonical state each state will map to...
            IDisjointSet <DFSAState <T, S> > stateClasses = new FastDisjointSet <DFSAState <T, S> >(states);

            foreach (UnorderedPair <DFSAState <T, S>, DFSAState <T, S> > up_2 in stateUPairToDistinguished.Keys)
            {
                if (stateUPairToDistinguished[up_2].Equals(false))
                {
                    DFSAState <T, S> state1_1 = up_2.first;
                    DFSAState <T, S> state2   = up_2.second;
                    stateClasses.Union(state1_1, state2);
                }
            }
            IDictionary <DFSAState <T, S>, DFSAState <T, S> > stateToRep = Generics.NewHashMap();

            foreach (DFSAState <T, S> state in states)
            {
                DFSAState <T, S> rep = stateClasses.Find(state);
                stateToRep[state] = rep;
            }
            if (debug)
            {
                log.Info("Canonical states chosen: " + (Runtime.CurrentTimeMillis() - time));
                time = Runtime.CurrentTimeMillis();
            }
            // reduce the DFSA by replacing transition targets with their reps
            foreach (DFSAState <T, S> state_1 in states)
            {
                if (!state_1.Equals(stateToRep[state_1]))
                {
                    continue;
                }
                foreach (DFSATransition <T, S> transition in state_1.Transitions())
                {
                    transition.target = stateClasses.Find(transition.target);
                }
            }
            dfsa.initialState = stateClasses.Find(dfsa.initialState);
            if (debug)
            {
                log.Info("Done: " + (Runtime.CurrentTimeMillis() - time));
            }
        }
Beispiel #21
0
        public bool ExtrudeFaces(HashSet <int> selected)
        {
            if (!FacesAreConnected(selected))
            {
                Debug.LogError("Cannot Extrude Disconnected Faces");
                return(false);
            }

            var startEdge = FindOuterEdge(selected);

            if (startEdge.Item1 == -1)
            {
                Debug.LogError("Cannot Find Outer Edge");
                return(false);
            }

            // Make sure the first two vertices are in the right order by comparing with a selected face
            foreach (var f in edgeFaces[startEdge])
            {
                if (!selected.Contains(f))
                {
                    continue;
                }
                int t1index = faces[f].vertices.IndexOf(startEdge.Item1);
                int t2index = faces[f].vertices.IndexOf(startEdge.Item2);

                if (t1index == (t2index + 1) % faces[f].vertices.Count)
                {
                    // Edge is in the wrong order. Fix it (this doesn't modify the orignal edge).
                    int temp = startEdge.Item2;
                    startEdge = new UnorderedPair <int>(temp, startEdge.Item1);
                }

                break;
            }

            Vector3    normal   = GetFacesNormal(selected);
            List <int> edgeLoop = new List <int> {
                startEdge.Item1, startEdge.Item2
            };

            while (true)
            {
                int cur  = edgeLoop[edgeLoop.Count - 1];
                int prev = edgeLoop[edgeLoop.Count - 2];
                int next = -1;

                foreach (int cand in vertexNeighbors[cur])
                {
                    var edge = new UnorderedPair <int>(cur, cand);

                    if (cand == prev || !IsOuterEdge(edge, selected))
                    {
                        continue;
                    }
                    next = cand;
                    break;
                }

                if (next != -1)
                {
                    if (next == edgeLoop[0])
                    {
                        break;
                    }

                    edgeLoop.Add(next);
                }
                else
                {
                    Debug.LogError("Edge Loop Not Found");
                    return(false);
                }
            }

            Face lastCreatedFace = null;

            int v1 = -1, v2 = -1;

            foreach (var v in edgeLoop)
            {
                int newVert = AddVertex(vertices[v].position);

                if (lastCreatedFace != null)
                {
                    lastCreatedFace.vertices.Add(v);
                    lastCreatedFace.vertices.Add(newVert);
                }
                else
                {
                    v1 = v;
                    v2 = newVert;
                }

                lastCreatedFace = new Face(newVert, v);
                faces.Add(lastCreatedFace);

                foreach (int face in selected)
                {
                    for (int k = 0; k < faces[face].vertices.Count; k++)
                    {
                        if (faces[face].vertices[k] == v)
                        {
                            faces[face].vertices[k] = newVert;
                        }
                    }
                }
            }

            lastCreatedFace.vertices.Add(v1);
            lastCreatedFace.vertices.Add(v2);

            foreach (int v in GetUniqueVertexList(selected))
            {
                vertices[v].position += normal;
            }

            graphDirty = true;

            return(true);
        }
Beispiel #22
0
        public void Select(Transform transform, Vector2 mousePos, Camera camera, out int selVertex, out int selFace, out UnorderedPair <int> selEdge, float radius = 10, float bump = 0.2f)
        {
            selVertex = -1;
            selFace   = -1;
            selEdge   = new UnorderedPair <int>(-1, -1);

            float minDist = Mathf.Infinity;

            Ray ray = camera.ScreenPointToRay(mousePos);

            ray.origin    = transform.InverseTransformPoint(ray.origin);
            ray.direction = transform.InverseTransformDirection(ray.direction);

            for (int v = 0; v < vertices.Count; v++)
            {
                Vertex vert = vertices[v];

                Vector3 world  = transform.TransformPoint(vert.position);
                Vector3 screen = camera.WorldToScreenPoint(world);
                if (screen.z > 0)
                {
                    screen.z = 0;
                    float mouseDist2 = Vector2.SqrMagnitude((Vector2)screen - mousePos);

                    float camDist = Vector3.Distance(camera.transform.position, world) - bump * 3;
                    if (mouseDist2 < radius * radius && camDist < minDist)
                    {
                        selVertex = v;
                        minDist   = camDist;
                    }
                }
            }

            foreach (var e in GetEdges())
            {
                Vertex vert1 = vertices[e.Item1];
                Vertex vert2 = vertices[e.Item2];

                Vector3 v1      = vert1.position;
                Vector3 v2      = vert2.position;
                Vector3 segment = v2 - v1;

                Vector3 c     = Vector3.Cross(camera.transform.forward, segment);
                Vector3 n     = Vector3.Cross(c, segment);
                Plane   plane = new Plane(n, v1);
                float   camDist;

                if (plane.Raycast(ray, out camDist) && camDist - bump < minDist)
                {
                    Vector3 hitPos  = ray.GetPoint(camDist);
                    Vector3 hitProj = MathUtil.ProjectPointOnLineSegment(v1, v2, hitPos);

                    Vector3 projScreen = camera.WorldToScreenPoint(transform.TransformPoint(hitProj));
                    if (projScreen.z > 0 && Vector2.Distance(projScreen, mousePos) < radius * 0.6f)
                    {
                        selEdge   = e;
                        selVertex = -1;
                        minDist   = camDist - bump;
                    }
                }
            }

            for (int f = 0; f < faces.Count; f++)
            {
                Face    face   = faces[f];
                Vector3 normal = face.GetNormal(this);
                Plane   plane  = new Plane(normal, vertices[face.vertices[0]].position);

                float dist;
                if (plane.Raycast(ray, out dist) && dist < minDist)
                {
                    Vector3 hitPos = ray.GetPoint(dist);

                    bool inside = true;

                    for (int i = 0; i < face.vertices.Count; i++)
                    {
                        int j = (i + 1) % face.vertices.Count;

                        Vector3 v1 = vertices[face.vertices[i]].position;
                        Vector3 v2 = vertices[face.vertices[j]].position;

                        Vector3 edge  = v2 - v1;
                        Vector3 toHit = hitPos - v1;
                        Vector3 cross = Vector3.Cross(edge, toHit);

                        if (Vector3.Dot(cross, normal) < 0)
                        {
                            inside = false;
                            break;
                        }
                    }

                    if (inside)
                    {
                        selVertex = -1;
                        selEdge   = new UnorderedPair <int>(-1, -1);
                        selFace   = f;
                        minDist   = dist;
                    }
                }
            }
        }