@@ -23,6 +23,7 @@ void FlowField::compute_flow(int set_width, int set_height, int arrivalX, int ar
23
23
fmm::UniformSpeedEikonalSolver<float , 2 >(grid_spacing, uniform_speed));
24
24
25
25
// Apply Obstacles
26
+ // TODO Make a separte function that gets applied, for static obstacles and use this for dynamic obstacles
26
27
vector<bool > is_obstacle (width * height, false );
27
28
for (int i = 0 ; i < obstacles.size (); ++i) {
28
29
Vector2i pos = obstacles[i];
@@ -33,13 +34,37 @@ void FlowField::compute_flow(int set_width, int set_height, int arrivalX, int ar
33
34
flow_field.resize (width * height);
34
35
35
36
// Compute flow field for each cell
36
- for (int x = 1 ; x < width - 1 ; ++x) {
37
- for (int y = 1 ; y < height - 1 ; ++y) {
37
+ for (int x = 0 ; x < width; ++x) {
38
+ for (int y = 0 ; y < height; ++y) {
38
39
int idx = x + y * width;
39
40
40
41
if (is_obstacle[idx]) {
41
- flow_field[idx] = { 0 .0f , 0 .0f };
42
- continue ;
42
+ float min_time = 1e6f;
43
+ array<float , 2 > best_vector = { 0 .0f , 0 .0f };
44
+
45
+ // Check the four neighbors for the smallest arrival time
46
+ int neighbors[4 ] = { idx - 1 , idx + 1 , idx - width, idx + width };
47
+
48
+ for (int n = 0 ; n < 4 ; n++) {
49
+ if (neighbors[n] < 0 || neighbors[n] >= width * height || is_obstacle[neighbors[n]])
50
+ continue ;
51
+
52
+ if (arrival_times[neighbors[n]] < min_time) {
53
+ min_time = arrival_times[neighbors[n]];
54
+
55
+ // Compute direction to the lowest-time neighbor
56
+ best_vector[0 ] = (neighbors[n] % width) - x;
57
+ best_vector[1 ] = ((neighbors[n] / width) - y);
58
+ }
59
+ }
60
+
61
+ // Normalize the vector if a valid neighbor was found
62
+ float mag = std::sqrt (best_vector[0 ] * best_vector[0 ] + best_vector[1 ] * best_vector[1 ]);
63
+ if (mag > 0 ) {
64
+ flow_field[idx] = { best_vector[0 ] / mag, best_vector[1 ] / mag };
65
+ } else {
66
+ flow_field[idx] = { 0 .0f , 0 .0f }; // No valid direction found
67
+ }
43
68
}
44
69
45
70
// Compute Vector gradient
@@ -55,11 +80,11 @@ void FlowField::compute_flow(int set_width, int set_height, int arrivalX, int ar
55
80
}
56
81
}
57
82
58
- String godot_string = String (vectorToString (flow_field ).c_str ());
59
- UtilityFunctions::print (" Flow Field Vector: " , godot_string);
83
+ // String godot_string = String(vectorToString().c_str());
84
+ // UtilityFunctions::print("Flow Field Vector: ", godot_string);
60
85
}
61
86
62
- std::string FlowField::vectorToString (const std::vector<std::array< float , 2 >> &flow_field ) {
87
+ std::string FlowField::vectorToString () {
63
88
std::ostringstream oss;
64
89
oss << " [" ; // Start with an opening bracket
65
90
@@ -79,19 +104,45 @@ Vector3 FlowField::get_move_direction(const Vector3 &world_position, float grid_
79
104
int gridY = static_cast <int >(world_position.z / grid_cell_size);
80
105
81
106
int index = gridX + gridY * width;
82
- if (index < 0 || index >= static_cast <int >(flow_field.size ())) {
83
- UtilityFunctions::push_error (" AI Blue Error : Flow Field | Final Flow Field Vector is empty" );
107
+ if (index < 0 || index > static_cast <int >(flow_field.size ())) {
108
+ // UtilityFunctions::push_error("AI Blue Error : Flow Field | Final Flow Field Vector is empty");
84
109
return Vector3 ();
85
110
}
86
111
87
- const auto &direction_vector = flow_field[index];
112
+ // for (size_t i = 0; i < flow_field.size(); ++i) {
113
+ // UtilityFunctions::print("Index: ", i, " Value: ", flow_field[i][0], ", ", flow_field[i][1]);
114
+ // }
115
+
116
+ // UtilityFunctions::print("World Position: ", world_position);
117
+ // UtilityFunctions::print("Index: ", index);
118
+ // UtilityFunctions::print("Flow Field Max Size: ", flow_field.size());
119
+
120
+ // Ref<FileAccess>
121
+ // file = FileAccess::open("user://debug_output.txt", FileAccess::WRITE_READ);
122
+ // if (file.is_valid()) {
123
+ // file->seek_end(); // Move to end before writing
124
+
125
+ // // Convert flow_field to a readable string
126
+ // String flow_data;
127
+ // for (const auto &vector : flow_field) {
128
+ // flow_data += String("(") + String::num(vector[0]) + ", " + String::num(vector[1]) + ")\n";
129
+ // }
88
130
89
- Vector3 move_direction (direction_vector[0 ], 0 .0f , direction_vector[1 ]);
131
+ // file->store_string(flow_data); // Write properly formatted data
132
+ // file->close();
133
+ // }
134
+
135
+ // String godot_string = String(const_cast<FlowField *>(this)->vectorToString().c_str());
136
+ // UtilityFunctions::print("Flow Field Vector: ", godot_string);
137
+
138
+ Vector3 move_direction (this ->flow_field [index][0 ], 0 .0f , this ->flow_field [index][1 ]);
90
139
91
140
if (move_direction.length () > 0 .0f ) {
92
141
move_direction = move_direction.normalized ();
93
142
}
94
143
144
+ // UtilityFunctions::print("Final Output: ", move_direction);
145
+
95
146
return move_direction;
96
147
}
97
148
0 commit comments