@@ -23,6 +23,7 @@ void FlowField::compute_flow(int set_width, int set_height, int arrivalX, int ar
2323 fmm::UniformSpeedEikonalSolver<float , 2 >(grid_spacing, uniform_speed));
2424
2525 // Apply Obstacles
26+ // TODO Make a separte function that gets applied, for static obstacles and use this for dynamic obstacles
2627 vector<bool > is_obstacle (width * height, false );
2728 for (int i = 0 ; i < obstacles.size (); ++i) {
2829 Vector2i pos = obstacles[i];
@@ -33,13 +34,37 @@ void FlowField::compute_flow(int set_width, int set_height, int arrivalX, int ar
3334 flow_field.resize (width * height);
3435
3536 // 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) {
3839 int idx = x + y * width;
3940
4041 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+ }
4368 }
4469
4570 // Compute Vector gradient
@@ -55,11 +80,11 @@ void FlowField::compute_flow(int set_width, int set_height, int arrivalX, int ar
5580 }
5681 }
5782
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);
6085}
6186
62- std::string FlowField::vectorToString (const std::vector<std::array< float , 2 >> &flow_field ) {
87+ std::string FlowField::vectorToString () {
6388 std::ostringstream oss;
6489 oss << " [" ; // Start with an opening bracket
6590
@@ -79,19 +104,45 @@ Vector3 FlowField::get_move_direction(const Vector3 &world_position, float grid_
79104 int gridY = static_cast <int >(world_position.z / grid_cell_size);
80105
81106 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");
84109 return Vector3 ();
85110 }
86111
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+ // }
88130
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 ]);
90139
91140 if (move_direction.length () > 0 .0f ) {
92141 move_direction = move_direction.normalized ();
93142 }
94143
144+ // UtilityFunctions::print("Final Output: ", move_direction);
145+
95146 return move_direction;
96147}
97148
0 commit comments