@@ -45,10 +45,26 @@ RWLock NavMeshGenerator3D::generator_parsers_rwlock;
45
45
bool NavMeshGenerator3D::use_threads = true ;
46
46
bool NavMeshGenerator3D::baking_use_multiple_threads = true ;
47
47
bool NavMeshGenerator3D::baking_use_high_priority_threads = true ;
48
- HashSet <Ref<NavigationMesh>> NavMeshGenerator3D::baking_navmeshes;
48
+ HashMap <Ref<NavigationMesh>, NavMeshGenerator3D::NavMeshGeneratorTask3D * > NavMeshGenerator3D::baking_navmeshes;
49
49
HashMap<WorkerThreadPool::TaskID, NavMeshGenerator3D::NavMeshGeneratorTask3D *> NavMeshGenerator3D::generator_tasks;
50
50
LocalVector<NavMeshGeometryParser3D *> NavMeshGenerator3D::generator_parsers;
51
51
52
+ static const char *_navmesh_bake_state_msgs[(size_t )NavMeshGenerator3D::NavMeshBakeState::BAKE_STATE_MAX] = {
53
+ " " ,
54
+ " Setting up configuration..." ,
55
+ " Calculating grid size..." ,
56
+ " Creating heightfield..." ,
57
+ " Marking walkable triangles..." ,
58
+ " Constructing compact heightfield..." , // step 5
59
+ " Eroding walkable area..." ,
60
+ " Sample partitioning..." ,
61
+ " Creating contours..." ,
62
+ " Creating polymesh..." ,
63
+ " Converting to native navigation mesh..." , // step 10
64
+ " Baking cleanup..." ,
65
+ " Baking finished." ,
66
+ };
67
+
52
68
NavMeshGenerator3D *NavMeshGenerator3D::get_singleton () {
53
69
return singleton;
54
70
}
@@ -158,10 +174,15 @@ void NavMeshGenerator3D::bake_from_source_geometry_data(Ref<NavigationMesh> p_na
158
174
ERR_FAIL_MSG (" NavigationMesh is already baking. Wait for current bake to finish." );
159
175
}
160
176
baking_navmesh_mutex.lock ();
161
- baking_navmeshes.insert (p_navigation_mesh);
177
+ NavMeshGeneratorTask3D generator_task;
178
+ baking_navmeshes.insert (p_navigation_mesh, &generator_task);
162
179
baking_navmesh_mutex.unlock ();
163
180
164
- generator_bake_from_source_geometry_data (p_navigation_mesh, p_source_geometry_data);
181
+ generator_task.navigation_mesh = p_navigation_mesh;
182
+ generator_task.source_geometry_data = p_source_geometry_data;
183
+ generator_task.status = NavMeshGeneratorTask3D::TaskStatus::BAKING_STARTED;
184
+
185
+ generator_bake_from_source_geometry_data (&generator_task);
165
186
166
187
baking_navmesh_mutex.lock ();
167
188
baking_navmeshes.erase (p_navigation_mesh);
@@ -197,16 +218,16 @@ void NavMeshGenerator3D::bake_from_source_geometry_data_async(Ref<NavigationMesh
197
218
return ;
198
219
}
199
220
baking_navmesh_mutex.lock ();
200
- baking_navmeshes.insert (p_navigation_mesh);
221
+ NavMeshGeneratorTask3D *generator_task = memnew (NavMeshGeneratorTask3D);
222
+ baking_navmeshes.insert (p_navigation_mesh, generator_task);
201
223
baking_navmesh_mutex.unlock ();
202
224
203
- MutexLock generator_task_lock (generator_task_mutex);
204
- NavMeshGeneratorTask3D *generator_task = memnew (NavMeshGeneratorTask3D);
205
225
generator_task->navigation_mesh = p_navigation_mesh;
206
226
generator_task->source_geometry_data = p_source_geometry_data;
207
227
generator_task->callback = p_callback;
208
228
generator_task->status = NavMeshGeneratorTask3D::TaskStatus::BAKING_STARTED;
209
229
generator_task->thread_task_id = WorkerThreadPool::get_singleton ()->add_native_task (&NavMeshGenerator3D::generator_thread_bake, generator_task, NavMeshGenerator3D::baking_use_high_priority_threads, SNAME (" NavMeshGeneratorBake3D" ));
230
+ MutexLock generator_task_lock (generator_task_mutex);
210
231
generator_tasks.insert (generator_task->thread_task_id , generator_task);
211
232
}
212
233
@@ -215,10 +236,21 @@ bool NavMeshGenerator3D::is_baking(Ref<NavigationMesh> p_navigation_mesh) {
215
236
return baking_navmeshes.has (p_navigation_mesh);
216
237
}
217
238
239
+ String NavMeshGenerator3D::get_baking_state_msg (Ref<NavigationMesh> p_navigation_mesh) {
240
+ String bake_state_msg;
241
+ MutexLock baking_navmesh_lock (baking_navmesh_mutex);
242
+ if (baking_navmeshes.has (p_navigation_mesh)) {
243
+ bake_state_msg = _navmesh_bake_state_msgs[baking_navmeshes[p_navigation_mesh]->bake_state ];
244
+ } else {
245
+ bake_state_msg = _navmesh_bake_state_msgs[NavMeshBakeState::BAKE_STATE_NONE];
246
+ }
247
+ return bake_state_msg;
248
+ }
249
+
218
250
void NavMeshGenerator3D::generator_thread_bake (void *p_arg) {
219
251
NavMeshGeneratorTask3D *generator_task = static_cast <NavMeshGeneratorTask3D *>(p_arg);
220
252
221
- generator_bake_from_source_geometry_data (generator_task-> navigation_mesh , generator_task-> source_geometry_data );
253
+ generator_bake_from_source_geometry_data (generator_task);
222
254
223
255
generator_task->status = NavMeshGeneratorTask3D::TaskStatus::BAKING_FINISHED;
224
256
}
@@ -269,7 +301,10 @@ void NavMeshGenerator3D::generator_parse_source_geometry_data(const Ref<Navigati
269
301
}
270
302
}
271
303
272
- void NavMeshGenerator3D::generator_bake_from_source_geometry_data (Ref<NavigationMesh> p_navigation_mesh, const Ref<NavigationMeshSourceGeometryData3D> &p_source_geometry_data) {
304
+ void NavMeshGenerator3D::generator_bake_from_source_geometry_data (NavMeshGeneratorTask3D *p_generator_task) {
305
+ Ref<NavigationMesh> p_navigation_mesh = p_generator_task->navigation_mesh ;
306
+ const Ref<NavigationMeshSourceGeometryData3D> &p_source_geometry_data = p_generator_task->source_geometry_data ;
307
+
273
308
if (p_navigation_mesh.is_null () || p_source_geometry_data.is_null ()) {
274
309
return ;
275
310
}
@@ -294,10 +329,7 @@ void NavMeshGenerator3D::generator_bake_from_source_geometry_data(Ref<Navigation
294
329
rcPolyMeshDetail *detail_mesh = nullptr ;
295
330
rcContext ctx;
296
331
297
- // added to keep track of steps, no functionality right now
298
- String bake_state = " " ;
299
-
300
- bake_state = " Setting up Configuration..." ; // step #1
332
+ p_generator_task->bake_state = NavMeshBakeState::BAKE_STATE_CONFIGURATION; // step #1
301
333
302
334
const float *verts = source_geometry_vertices.ptr ();
303
335
const int nverts = source_geometry_vertices.size () / 3 ;
@@ -373,7 +405,7 @@ void NavMeshGenerator3D::generator_bake_from_source_geometry_data(Ref<Navigation
373
405
cfg.bmax [2 ] = cfg.bmin [2 ] + baking_aabb.size [2 ];
374
406
}
375
407
376
- bake_state = " Calculating grid size... " ; // step #2
408
+ p_generator_task-> bake_state = NavMeshBakeState::BAKE_STATE_CALC_GRID_SIZE ; // step #2
377
409
rcCalcGridSize (cfg.bmin , cfg.bmax , cfg.cs , &cfg.width , &cfg.height );
378
410
379
411
// ~30000000 seems to be around sweetspot where Editor baking breaks
@@ -387,13 +419,13 @@ void NavMeshGenerator3D::generator_bake_from_source_geometry_data(Ref<Navigation
387
419
return ;
388
420
}
389
421
390
- bake_state = " Creating heightfield... " ; // step #3
422
+ p_generator_task-> bake_state = NavMeshBakeState::BAKE_STATE_CREATE_HEIGHTFIELD ; // step #3
391
423
hf = rcAllocHeightfield ();
392
424
393
425
ERR_FAIL_NULL (hf);
394
426
ERR_FAIL_COND (!rcCreateHeightfield (&ctx, *hf, cfg.width , cfg.height , cfg.bmin , cfg.bmax , cfg.cs , cfg.ch ));
395
427
396
- bake_state = " Marking walkable triangles... " ; // step #4
428
+ p_generator_task-> bake_state = NavMeshBakeState::BAKE_STATE_MARK_WALKABLE_TRIANGLES ; // step #4
397
429
{
398
430
Vector<unsigned char > tri_areas;
399
431
tri_areas.resize (ntris);
@@ -416,7 +448,7 @@ void NavMeshGenerator3D::generator_bake_from_source_geometry_data(Ref<Navigation
416
448
rcFilterWalkableLowHeightSpans (&ctx, cfg.walkableHeight , *hf);
417
449
}
418
450
419
- bake_state = " Constructing compact heightfield... " ; // step #5
451
+ p_generator_task-> bake_state = NavMeshBakeState::BAKE_STATE_CONSTRUCT_COMPACT_HEIGHTFIELD ; // step #5
420
452
421
453
chf = rcAllocCompactHeightfield ();
422
454
@@ -443,7 +475,7 @@ void NavMeshGenerator3D::generator_bake_from_source_geometry_data(Ref<Navigation
443
475
}
444
476
}
445
477
446
- bake_state = " Eroding walkable area... " ; // step #6
478
+ p_generator_task-> bake_state = NavMeshBakeState::BAKE_STATE_ERODE_WALKABLE_AREA ; // step #6
447
479
448
480
ERR_FAIL_COND (!rcErodeWalkableArea (&ctx, cfg.walkableRadius , *chf));
449
481
@@ -464,7 +496,7 @@ void NavMeshGenerator3D::generator_bake_from_source_geometry_data(Ref<Navigation
464
496
}
465
497
}
466
498
467
- bake_state = " Partitioning... " ; // step #7
499
+ p_generator_task-> bake_state = NavMeshBakeState::BAKE_STATE_SAMPLE_PARTITIONING ; // step #7
468
500
469
501
if (p_navigation_mesh->get_sample_partition_type () == NavigationMesh::SAMPLE_PARTITION_WATERSHED) {
470
502
ERR_FAIL_COND (!rcBuildDistanceField (&ctx, *chf));
@@ -475,14 +507,14 @@ void NavMeshGenerator3D::generator_bake_from_source_geometry_data(Ref<Navigation
475
507
ERR_FAIL_COND (!rcBuildLayerRegions (&ctx, *chf, cfg.borderSize , cfg.minRegionArea ));
476
508
}
477
509
478
- bake_state = " Creating contours... " ; // step #8
510
+ p_generator_task-> bake_state = NavMeshBakeState::BAKE_STATE_CREATING_CONTOURS ; // step #8
479
511
480
512
cset = rcAllocContourSet ();
481
513
482
514
ERR_FAIL_NULL (cset);
483
515
ERR_FAIL_COND (!rcBuildContours (&ctx, *chf, cfg.maxSimplificationError , cfg.maxEdgeLen , *cset));
484
516
485
- bake_state = " Creating polymesh... " ; // step #9
517
+ p_generator_task-> bake_state = NavMeshBakeState::BAKE_STATE_CREATING_POLYMESH ; // step #9
486
518
487
519
poly_mesh = rcAllocPolyMesh ();
488
520
ERR_FAIL_NULL (poly_mesh);
@@ -497,7 +529,7 @@ void NavMeshGenerator3D::generator_bake_from_source_geometry_data(Ref<Navigation
497
529
rcFreeContourSet (cset);
498
530
cset = nullptr ;
499
531
500
- bake_state = " Converting to native navigation mesh... " ; // step #10
532
+ p_generator_task-> bake_state = NavMeshBakeState::BAKE_STATE_CONVERTING_NATIVE_NAVMESH ; // step #10
501
533
502
534
Vector<Vector3> nav_vertices;
503
535
Vector<Vector<int >> nav_polygons;
@@ -544,14 +576,14 @@ void NavMeshGenerator3D::generator_bake_from_source_geometry_data(Ref<Navigation
544
576
545
577
p_navigation_mesh->set_data (nav_vertices, nav_polygons);
546
578
547
- bake_state = " Cleanup... " ; // step #11
579
+ p_generator_task-> bake_state = NavMeshBakeState::BAKE_STATE_BAKE_CLEANUP ; // step #11
548
580
549
581
rcFreePolyMesh (poly_mesh);
550
582
poly_mesh = nullptr ;
551
583
rcFreePolyMeshDetail (detail_mesh);
552
584
detail_mesh = nullptr ;
553
585
554
- bake_state = " Baking finished. " ; // step #12
586
+ p_generator_task-> bake_state = NavMeshBakeState::BAKE_STATE_BAKE_FINISHED ; // step #12
555
587
}
556
588
557
589
bool NavMeshGenerator3D::generator_emit_callback (const Callable &p_callback) {
0 commit comments