This repository has been archived by the owner on Nov 6, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
dijkstraNavigation.sqf
204 lines (148 loc) · 5.16 KB
/
dijkstraNavigation.sqf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
// Create Road Map
_roadMap = [];
_nextRoads = [];
_finishedRoads = [];
_startRoads = player nearRoads 10;
_firstRoad = _startRoads select 0;
_nextRoads pushBack _firstRoad;
_iterationCounter = 0;
while {_iterationCounter < 1000} do
{
_nextRoad = _nextRoads deleteAt 0;
_connectedRoads = roadsConnectedTo _nextRoad;
{
_distance = _x distance _nextRoad;
_roadMap pushBack [_nextRoad, _x, _distance];
if((_finishedRoads find _x) == -1) then
{
_nextRoads pushBack _x;
};
} foreach _connectedRoads;
_finishedRoads pushBack _nextRoad;
_iterationCounter = _iterationCounter +1;
};
diag_log format ["RoadMap: %1", _roadMap];
// Run the Dijkstra Algorithm
_startRoads = player nearRoads 10;
_startRoad = _startRoads select 0;
// Init Distances
_distanceArray = [];
_workQueue = [];
_distanceArray pushBack [_startRoad, 0, null];
_visitedRoads = [];
_visitedRoads pushBack _startRoad;
_workQueue pushBack [0, _startRoad];
_itC = 0;
_timeArray = [];
_start = diag_tickTime;
while { count _workQueue > 0} do
{
_workItem = _workQueue deleteAt 0;
_actualRoad = _workItem select 1;
_itC = _itC +1;
_connRoads = _roadMap select {(_x select 0) isEqualTo _actualRoad && !((_x select 1) in _visitedRoads)};
{
_road = _x select 0;
_connRoad = _x select 1;
_connDistance = _x select 2;
_visitedRoads pushBack _connRoad;
_roadDistance = _connDistance;
// Find Parent in Distance Array
_parents = _distanceArray select {(_x select 0 IsEqualTo _road)};
{
_parentRoad = _x select 0;
_parentDistance = _x select 1;
_parentParent = _x select 2;
_roadDistance = _roadDistance + _parentDistance;
} foreach _parents;
_distanceArray pushBack [_connRoad, _roadDistance, _road];
_workQueue pushBack [_roadDistance, _connRoad];
} foreach _connRoads;
// diag_log format ["Result: %1", _result];
// // Get the connected Roads out the RoadMap
// {
// _road = _x select 0;
// _connRoad = _x select 1;
// _connDistance = _x select 2;
// if ((_road == _actualRoad) && !(_connRoad in _visitedRoads)) then // Find Connected Roads, not yet visited
// {
// _visitedRoads pushBack _connRoad; // Save connected road as visited
// // Calculate Distance between the Roads
// _roadDistance = _connDistance;
// // Search for Parent in Distance Array and get his Distance
// {
// _parentRoad = _x select 0;
// _parentDistance = _x select 1;
// _parentParent = _x select 2;
// if(_parentRoad == _road) then
// {
// _roadDistance = _roadDistance + _parentDistance; // Add distance of parent to new distance
// };
// } foreach _distanceArray;
// // Save new Road in Distance Array
// _distanceArray pushBack [_connRoad, _roadDistance, _road]; // Add connected road to Distance Array
// _workQueue pushBack [_roadDistance, _connRoad]; // Add connected road to queue
// };
// } forEach _roadMap;
if(count _workQueue > 0) then {_workQueue sort true;};
};
_stop = diag_tickTime;
diag_log format ["Time: %1, Iteration: %2", _stop - _start, _itC];
// diag_log str _itC;
// diag_log format ["Number of Iterations: %1, TimeArray: %2", _itC, _timeArray];
// Now Finding the Shortest Path to Destination
_destinationPath = [];
_destinationLength = 0;
_startNode = _distanceArray select 0;
// Get the Destination Node from Marker
_destinationMarker = allMapMarkers select ((count allMapMarkers) -1);
_nearestDestinationRoad = (getMarkerPos(_destinationMarker) nearRoads 10) select 0;
_selectedNode = [];
// Find DestinationRoad in Array
{
_nodeRoadx = _x select 0;
if(_nodeRoadx == _nearestDestinationRoad) then
{
_selectedNode = _x;
}
} foreach _distanceArray;
// Get the Distance to Destination
_destinationLength = _selectedNode select 1;
diag_log format ["StartNode: %1, SelectNode: %2, DestinationLength: %3", _startNode, _selectedNode, _destinationLength];
// Get the Path to Destination
while{!(_selectedNode isEqualTo _startNode)} do
{
_nodeRoad = _selectedNode select 0; // Select the Road in the Node
_destinationPath pushBack _nodeRoad; // Save the Road in the Path
_nodeParent = _selectedNode select 2; // Node Parent to find
// Find Node Parent in Distance Array
{
_nodeRoadx = _x select 0;
if(_nodeRoadx == _nodeParent) then
{
_selectedNode = _x;
}
} foreach _distanceArray;
};
_destinationPath pushBack (_startNode select 0);
// Create Local Markers to navigate to the path
{
_streetMarker = "VR_3DSelector_01_exit_F" createVehicleLocal getPosATL(_x);
// _mapMarker = createMarkerLocal ["markername",[getPos(_x select 0) select 0,getPos(_x select 0) select 1]];
// _mapMarker setMarkerShapeLocal "ICON";m
// _mapMarker setMarkerTypeLocal "DOT";
} foreach _destinationPath;
// Delete Local Markers when passing them
[] spawn {
while{true} do
{
_nearestObjects = nearestObjects [player, [], 10];
{
if(typeOf _x == "VR_3DSelector_01_exit_F") then
{
deleteVehicle _x;
}
} foreach _nearestObjects;
sleep 0.1;
}
}