Exemple #1
0
        public void analyze()
        {
            // 1. build mapping from room to center nodes
            foreach (var room in roomGraph.rooms)
            {
                // create unconnected center nodes
                sngNodes[room] = new DelayedNode(new StructuralNavigationGraph.Node(room.center)
                {
                    room = room // store link to room
                });
            }

            // 2. create nodes of indirection
            foreach (var nodePair in sngNodes)
            {
                var room       = nodePair.Key;
                var centerNode = nodePair.Value;
                foreach (var door in room.doors)
                {
                    // calculate positions of inner and outer door nodes
                    var doorCenter = door.doorCenter;
                    var(dx, dy) = DirectionStepper.stepIn(door.dir);
                    var innerDoor = doorCenter + new Point(-dx * StructuralNavigationGraph.DOOR_NODE_DIST,
                                                           -dy * StructuralNavigationGraph.DOOR_NODE_DIST);
                    var outerDoor = doorCenter + new Point(dx * StructuralNavigationGraph.DOOR_NODE_DIST,
                                                           dy * StructuralNavigationGraph.DOOR_NODE_DIST);
                    var innerDoorNode = new DelayedNode(new StructuralNavigationGraph.Node(innerDoor));
                    var outerDoorNode = new DelayedNode(new StructuralNavigationGraph.Node(outerDoor)
                    {
                        edge = new StructuralNavigationGraph.RoomLink(door.roomLocal, door.roomOther)
                    });
                    centerNode.addPendingLink(innerDoorNode);    // attach CENTER - INNER
                    innerDoorNode.addPendingLink(outerDoorNode); // attach INNER - OUTER
                    // when collapsed, we should get CENTER - INNER - OUTER (a "spike")
                }

                centerNode.collapse();
            }

            var centralNodes = sngNodes.Values.Select(x => x.centerNode).ToList();

            allNodes.AddRange(centralNodes);
            // now, we have all our nodes of the form
            // CENTER with [INNER - OUTER] spikes for each door
            // 3. next, we need to merge these spikes by door link
            // and merge all these delayed nodes into a graph
            var spikeNodes = new List <StructuralNavigationGraph.Node>();

            foreach (var nodePair in sngNodes)
            {
                var room       = nodePair.Key;
                var centerNode = nodePair.Value;
                var gn         = centerNode.centerNode;

                // do a BFS on the node. we are going to make a list of spike nodes.
                var visited = new Dictionary <StructuralNavigationGraph.Node, bool>();
                var queue   = new Queue <StructuralNavigationGraph.Node>();
                // mark the starting node as visited, and queue it
                visited[gn] = true;
                queue.Enqueue(gn);

                while (queue.Count > 0)
                {
                    // process the current vertex
                    var vertex = queue.Dequeue();
                    // add to node list
                    if (!allNodes.Contains(vertex))
                    {
                        allNodes.Add(vertex);
                    }

                    if (vertex.edge != null)
                    {
                        spikeNodes.Add(vertex);
                    }

                    // get all adjacent, and enqueue any unvisited
                    foreach (var adjacent in vertex.links)
                    {
                        if (!visited.ContainsKey(adjacent) || !visited[adjacent]) // not visited
                        {
                            visited[adjacent] = true;                             // mark visited
                            queue.Enqueue(adjacent);                              // enqueue
                        }
                    }
                }
            }

            // then, we will x2 loop through all spike nodes and match spike to spike via link equiv
            foreach (var spk1 in spikeNodes)
            {
                foreach (var spk2 in spikeNodes)
                {
                    if (spk1 == spk2)
                    {
                        continue;
                    }
                    // now, match spike-to-spike
                    if (spk1.edge.equiv(spk2.edge))
                    {
                        // we have a match!
                        spk1.links.Add(spk2);
                        spk2.links.Add(spk1);
                    }
                }
            }

            // this should give us a graph!e
        }
Exemple #2
0
 public void addPendingLink(DelayedNode node)
 {
     pendingLinks.Add(node);
 }