diff options
Diffstat (limited to 'modules/gridmap/grid_map.cpp')
-rw-r--r-- | modules/gridmap/grid_map.cpp | 111 |
1 files changed, 86 insertions, 25 deletions
diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp index 02fe4d93de..7d80cbef7c 100644 --- a/modules/gridmap/grid_map.cpp +++ b/modules/gridmap/grid_map.cpp @@ -103,9 +103,10 @@ bool GridMap::_get(const StringName &p_name, Variant &r_ret) const { { int *w = cells.ptrw(); int i = 0; - for (Map<IndexKey, Cell>::Element *E = cell_map.front(); E; E = E->next(), i++) { - encode_uint64(E->key().key, (uint8_t *)&w[i * 3]); - encode_uint32(E->get().cell, (uint8_t *)&w[i * 3 + 2]); + for (const KeyValue<IndexKey, Cell> &E : cell_map) { + encode_uint64(E.key.key, (uint8_t *)&w[i * 3]); + encode_uint32(E.value.cell, (uint8_t *)&w[i * 3 + 2]); + i++; } } @@ -225,15 +226,33 @@ bool GridMap::is_baking_navigation() { return bake_navigation; } -void GridMap::set_navigation_layers(uint32_t p_layers) { - navigation_layers = p_layers; +void GridMap::set_navigation_layers(uint32_t p_navigation_layers) { + navigation_layers = p_navigation_layers; _recreate_octant_data(); } -uint32_t GridMap::get_navigation_layers() { +uint32_t GridMap::get_navigation_layers() const { return navigation_layers; } +void GridMap::set_navigation_layer_value(int p_layer_number, bool p_value) { + ERR_FAIL_COND_MSG(p_layer_number < 1, "Navigation layer number must be between 1 and 32 inclusive."); + ERR_FAIL_COND_MSG(p_layer_number > 32, "Navigation layer number must be between 1 and 32 inclusive."); + uint32_t _navigation_layers = get_navigation_layers(); + if (p_value) { + _navigation_layers |= 1 << (p_layer_number - 1); + } else { + _navigation_layers &= ~(1 << (p_layer_number - 1)); + } + set_navigation_layers(_navigation_layers); +} + +bool GridMap::get_navigation_layer_value(int p_layer_number) const { + ERR_FAIL_COND_V_MSG(p_layer_number < 1, false, "Navigation layer number must be between 1 and 32 inclusive."); + ERR_FAIL_COND_V_MSG(p_layer_number > 32, false, "Navigation layer number must be between 1 and 32 inclusive."); + return get_navigation_layers() & (1 << (p_layer_number - 1)); +} + void GridMap::set_mesh_library(const Ref<MeshLibrary> &p_mesh_library) { if (!mesh_library.is_null()) { mesh_library->unregister_owner(this); @@ -432,6 +451,18 @@ void GridMap::_octant_transform(const OctantKey &p_key) { RS::get_singleton()->instance_set_transform(g.collision_debug_instance, get_global_transform()); } + // update transform for NavigationServer regions and navigation debugmesh instances + for (const KeyValue<IndexKey, Octant::NavMesh> &E : g.navmesh_ids) { + if (bake_navigation) { + if (E.value.region.is_valid()) { + NavigationServer3D::get_singleton()->region_set_transform(E.value.region, get_global_transform() * E.value.xform); + } + if (E.value.navmesh_debug_instance.is_valid()) { + RS::get_singleton()->instance_set_transform(E.value.navmesh_debug_instance, get_global_transform() * E.value.xform); + } + } + } + for (int i = 0; i < g.multimesh_instances.size(); i++) { RS::get_singleton()->instance_set_transform(g.multimesh_instances[i].instance, get_global_transform()); } @@ -455,6 +486,9 @@ bool GridMap::_octant_update(const OctantKey &p_key) { //erase navigation for (const KeyValue<IndexKey, Octant::NavMesh> &E : g.navmesh_ids) { NavigationServer3D::get_singleton()->free(E.value.region); + if (E.value.navmesh_debug_instance.is_valid()) { + RS::get_singleton()->free(E.value.navmesh_debug_instance); + } } g.navmesh_ids.clear(); @@ -480,17 +514,17 @@ bool GridMap::_octant_update(const OctantKey &p_key) { * and set said multimesh bounding box to one containing all cells which have this item */ - Map<int, List<Pair<Transform3D, IndexKey>>> multimesh_items; + HashMap<int, List<Pair<Transform3D, IndexKey>>> multimesh_items; - for (Set<IndexKey>::Element *E = g.cells.front(); E; E = E->next()) { - ERR_CONTINUE(!cell_map.has(E->get())); - const Cell &c = cell_map[E->get()]; + for (const IndexKey &E : g.cells) { + ERR_CONTINUE(!cell_map.has(E)); + const Cell &c = cell_map[E]; if (!mesh_library.is_valid() || !mesh_library->has_item(c.item)) { continue; } - Vector3 cellpos = Vector3(E->get().x, E->get().y, E->get().z); + Vector3 cellpos = Vector3(E.x, E.y, E.z); Vector3 ofs = _get_offset(); Transform3D xform; @@ -506,7 +540,7 @@ bool GridMap::_octant_update(const OctantKey &p_key) { Pair<Transform3D, IndexKey> p; p.first = xform * mesh_library->get_item_mesh_transform(c.item); - p.second = E->get(); + p.second = E; multimesh_items[c.item].push_back(p); } } @@ -532,14 +566,29 @@ bool GridMap::_octant_update(const OctantKey &p_key) { if (bake_navigation) { RID region = NavigationServer3D::get_singleton()->region_create(); - NavigationServer3D::get_singleton()->region_set_layers(region, navigation_layers); + NavigationServer3D::get_singleton()->region_set_navigation_layers(region, navigation_layers); NavigationServer3D::get_singleton()->region_set_navmesh(region, navmesh); - NavigationServer3D::get_singleton()->region_set_transform(region, get_global_transform() * mesh_library->get_item_navmesh_transform(c.item)); + NavigationServer3D::get_singleton()->region_set_transform(region, get_global_transform() * nm.xform); NavigationServer3D::get_singleton()->region_set_map(region, get_world_3d()->get_navigation_map()); nm.region = region; + + // add navigation debugmesh visual instances if debug is enabled + SceneTree *st = SceneTree::get_singleton(); + if (st && st->is_debugging_navigation_hint()) { + if (!nm.navmesh_debug_instance.is_valid()) { + RID navmesh_debug_rid = navmesh->get_debug_mesh()->get_rid(); + nm.navmesh_debug_instance = RS::get_singleton()->instance_create(); + RS::get_singleton()->instance_set_base(nm.navmesh_debug_instance, navmesh_debug_rid); + RS::get_singleton()->mesh_surface_set_material(navmesh_debug_rid, 0, st->get_debug_navigation_material()->get_rid()); + } + if (is_inside_tree()) { + RS::get_singleton()->instance_set_scenario(nm.navmesh_debug_instance, get_world_3d()->get_scenario()); + RS::get_singleton()->instance_set_transform(nm.navmesh_debug_instance, get_global_transform() * nm.xform); + } + } } - g.navmesh_ids[E->get()] = nm; + g.navmesh_ids[E] = nm; } } @@ -628,7 +677,7 @@ void GridMap::_octant_enter_world(const OctantKey &p_key) { Ref<NavigationMesh> nm = mesh_library->get_item_navmesh(cell_map[F.key].item); if (nm.is_valid()) { RID region = NavigationServer3D::get_singleton()->region_create(); - NavigationServer3D::get_singleton()->region_set_layers(region, navigation_layers); + NavigationServer3D::get_singleton()->region_set_navigation_layers(region, navigation_layers); NavigationServer3D::get_singleton()->region_set_navmesh(region, nm); NavigationServer3D::get_singleton()->region_set_transform(region, get_global_transform() * F.value.xform); NavigationServer3D::get_singleton()->region_set_map(region, get_world_3d()->get_navigation_map()); @@ -659,6 +708,10 @@ void GridMap::_octant_exit_world(const OctantKey &p_key) { NavigationServer3D::get_singleton()->free(F.value.region); F.value.region = RID(); } + if (F.value.navmesh_debug_instance.is_valid()) { + RS::get_singleton()->free(F.value.navmesh_debug_instance); + F.value.navmesh_debug_instance = RID(); + } } } @@ -677,7 +730,12 @@ void GridMap::_octant_clean_up(const OctantKey &p_key) { // Erase navigation for (const KeyValue<IndexKey, Octant::NavMesh> &E : g.navmesh_ids) { - NavigationServer3D::get_singleton()->free(E.value.region); + if (E.value.region.is_valid()) { + NavigationServer3D::get_singleton()->free(E.value.region); + } + if (E.value.navmesh_debug_instance.is_valid()) { + RS::get_singleton()->free(E.value.navmesh_debug_instance); + } } g.navmesh_ids.clear(); @@ -770,7 +828,7 @@ void GridMap::_queue_octants_dirty() { void GridMap::_recreate_octant_data() { recreating_octants = true; - Map<IndexKey, Cell> cell_copy = cell_map; + HashMap<IndexKey, Cell, IndexKey> cell_copy = cell_map; _clear_internal(); for (const KeyValue<IndexKey, Cell> &E : cell_copy) { set_cell_item(Vector3i(E.key), E.value.item, E.value.rot); @@ -797,7 +855,7 @@ void GridMap::clear() { clear_baked_meshes(); } -void GridMap::resource_changed(const RES &p_res) { +void GridMap::resource_changed(const Ref<Resource> &p_res) { _recreate_octant_data(); } @@ -845,6 +903,9 @@ void GridMap::_bind_methods() { ClassDB::bind_method(D_METHOD("set_navigation_layers", "layers"), &GridMap::set_navigation_layers); ClassDB::bind_method(D_METHOD("get_navigation_layers"), &GridMap::get_navigation_layers); + ClassDB::bind_method(D_METHOD("set_navigation_layer_value", "layer_number", "value"), &GridMap::set_navigation_layer_value); + ClassDB::bind_method(D_METHOD("get_navigation_layer_value", "layer_number"), &GridMap::get_navigation_layer_value); + ClassDB::bind_method(D_METHOD("set_mesh_library", "mesh_library"), &GridMap::set_mesh_library); ClassDB::bind_method(D_METHOD("get_mesh_library"), &GridMap::get_mesh_library); @@ -889,7 +950,7 @@ void GridMap::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh_library", PROPERTY_HINT_RESOURCE_TYPE, "MeshLibrary"), "set_mesh_library", "get_mesh_library"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material", "get_physics_material"); ADD_GROUP("Cell", "cell_"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "cell_size"), "set_cell_size", "get_cell_size"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "cell_size", PROPERTY_HINT_NONE, "suffix:m"), "set_cell_size", "get_cell_size"); ADD_PROPERTY(PropertyInfo(Variant::INT, "cell_octant_size", PROPERTY_HINT_RANGE, "1,1024,1"), "set_octant_size", "get_octant_size"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cell_center_x"), "set_center_x", "get_center_x"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cell_center_y"), "set_center_y", "get_center_y"); @@ -969,7 +1030,7 @@ Array GridMap::get_meshes() const { xform.set_origin(cellpos * cell_size + ofs); xform.basis.scale(Vector3(cell_scale, cell_scale, cell_scale)); - meshes.push_back(xform); + meshes.push_back(xform * mesh_library->get_item_mesh_transform(id)); meshes.push_back(mesh); } @@ -998,7 +1059,7 @@ void GridMap::make_baked_meshes(bool p_gen_lightmap_uv, float p_lightmap_uv_texe } //generate - Map<OctantKey, Map<Ref<Material>, Ref<SurfaceTool>>> surface_map; + HashMap<OctantKey, HashMap<Ref<Material>, Ref<SurfaceTool>>, OctantKey> surface_map; for (KeyValue<IndexKey, Cell> &E : cell_map) { IndexKey key = E.key; @@ -1028,10 +1089,10 @@ void GridMap::make_baked_meshes(bool p_gen_lightmap_uv, float p_lightmap_uv_texe ok.z = key.z / octant_size; if (!surface_map.has(ok)) { - surface_map[ok] = Map<Ref<Material>, Ref<SurfaceTool>>(); + surface_map[ok] = HashMap<Ref<Material>, Ref<SurfaceTool>>(); } - Map<Ref<Material>, Ref<SurfaceTool>> &mat_map = surface_map[ok]; + HashMap<Ref<Material>, Ref<SurfaceTool>> &mat_map = surface_map[ok]; for (int i = 0; i < mesh->get_surface_count(); i++) { if (mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES) { @@ -1051,7 +1112,7 @@ void GridMap::make_baked_meshes(bool p_gen_lightmap_uv, float p_lightmap_uv_texe } } - for (KeyValue<OctantKey, Map<Ref<Material>, Ref<SurfaceTool>>> &E : surface_map) { + for (KeyValue<OctantKey, HashMap<Ref<Material>, Ref<SurfaceTool>>> &E : surface_map) { Ref<ArrayMesh> mesh; mesh.instantiate(); for (KeyValue<Ref<Material>, Ref<SurfaceTool>> &F : E.value) { |