|
32 | 32 |
|
33 | 33 | #include "core/io/marshalls.h" |
34 | 34 | #include "core/math/convex_hull.h" |
| 35 | +#include "core/templates/a_hash_map.h" |
35 | 36 | #include "scene/resources/3d/box_shape_3d.h" |
36 | 37 | #include "scene/resources/3d/capsule_shape_3d.h" |
37 | 38 | #include "scene/resources/3d/concave_polygon_shape_3d.h" |
@@ -644,7 +645,11 @@ bool GridMap::_octant_update(const OctantKey &p_key) { |
644 | 645 | * and set said multimesh bounding box to one containing all cells which have this item |
645 | 646 | */ |
646 | 647 |
|
647 | | - HashMap<int, List<Pair<Transform3D, IndexKey>>> multimesh_items; |
| 648 | + struct MultiMeshItemPlacement { |
| 649 | + Transform3D transform; |
| 650 | + IndexKey index_key; |
| 651 | + }; |
| 652 | + AHashMap<int, LocalVector<MultiMeshItemPlacement>> item_id_to_multimesh_item_placements; |
648 | 653 |
|
649 | 654 | RID scenario; |
650 | 655 | #ifndef NAVIGATION_3D_DISABLED |
@@ -676,14 +681,14 @@ bool GridMap::_octant_update(const OctantKey &p_key) { |
676 | 681 | xform.basis.scale(Vector3(cell_scale, cell_scale, cell_scale)); |
677 | 682 | if (baked_meshes.is_empty()) { |
678 | 683 | if (mesh_library->get_item_mesh(c.item).is_valid()) { |
679 | | - if (!multimesh_items.has(c.item)) { |
680 | | - multimesh_items[c.item] = List<Pair<Transform3D, IndexKey>>(); |
| 684 | + if (!item_id_to_multimesh_item_placements.has(c.item)) { |
| 685 | + item_id_to_multimesh_item_placements[c.item] = LocalVector<MultiMeshItemPlacement>(); |
681 | 686 | } |
682 | 687 |
|
683 | | - Pair<Transform3D, IndexKey> p; |
684 | | - p.first = xform * mesh_library->get_item_mesh_transform(c.item); |
685 | | - p.second = E; |
686 | | - multimesh_items[c.item].push_back(p); |
| 688 | + MultiMeshItemPlacement p; |
| 689 | + p.transform = xform * mesh_library->get_item_mesh_transform(c.item); |
| 690 | + p.index_key = E; |
| 691 | + item_id_to_multimesh_item_placements[c.item].push_back(p); |
687 | 692 | } |
688 | 693 | } |
689 | 694 |
|
@@ -754,22 +759,23 @@ bool GridMap::_octant_update(const OctantKey &p_key) { |
754 | 759 |
|
755 | 760 | //update multimeshes, only if not baked |
756 | 761 | if (baked_meshes.is_empty()) { |
757 | | - for (const KeyValue<int, List<Pair<Transform3D, IndexKey>>> &E : multimesh_items) { |
| 762 | + for (const KeyValue<int, LocalVector<MultiMeshItemPlacement>> &E : item_id_to_multimesh_item_placements) { |
758 | 763 | Octant::MultimeshInstance mmi; |
759 | 764 |
|
760 | 765 | RID mm = RS::get_singleton()->multimesh_create(); |
761 | 766 | RS::get_singleton()->multimesh_allocate_data(mm, E.value.size(), RS::MULTIMESH_TRANSFORM_3D); |
762 | 767 | RS::get_singleton()->multimesh_set_mesh(mm, mesh_library->get_item_mesh(E.key)->get_rid()); |
763 | 768 |
|
764 | 769 | int idx = 0; |
765 | | - for (const Pair<Transform3D, IndexKey> &F : E.value) { |
766 | | - RS::get_singleton()->multimesh_instance_set_transform(mm, idx, F.first); |
| 770 | + const LocalVector<MultiMeshItemPlacement> &mm_item_placements = E.value; |
| 771 | + for (const MultiMeshItemPlacement &mm_item_placement : mm_item_placements) { |
| 772 | + RS::get_singleton()->multimesh_instance_set_transform(mm, idx, mm_item_placement.transform); |
767 | 773 | #ifdef TOOLS_ENABLED |
768 | 774 |
|
769 | 775 | Octant::MultimeshInstance::Item it; |
770 | 776 | it.index = idx; |
771 | | - it.transform = F.first; |
772 | | - it.key = F.second; |
| 777 | + it.transform = mm_item_placement.transform; |
| 778 | + it.key = mm_item_placement.index_key; |
773 | 779 | mmi.items.push_back(it); |
774 | 780 | #endif |
775 | 781 |
|
@@ -1131,17 +1137,19 @@ void GridMap::_update_octants_callback() { |
1131 | 1137 | return; |
1132 | 1138 | } |
1133 | 1139 |
|
1134 | | - List<OctantKey> to_delete; |
| 1140 | + LocalVector<OctantKey> to_delete; |
| 1141 | + to_delete.reserve(octant_map.size()); |
1135 | 1142 | for (const KeyValue<OctantKey, Octant *> &E : octant_map) { |
1136 | 1143 | if (_octant_update(E.key)) { |
1137 | 1144 | to_delete.push_back(E.key); |
1138 | 1145 | } |
1139 | 1146 | } |
1140 | 1147 |
|
1141 | | - while (to_delete.front()) { |
1142 | | - memdelete(octant_map[to_delete.front()->get()]); |
1143 | | - octant_map.erase(to_delete.front()->get()); |
1144 | | - to_delete.pop_front(); |
| 1148 | + while (!to_delete.is_empty()) { |
| 1149 | + const OctantKey &octantkey = to_delete[0]; |
| 1150 | + memdelete(octant_map[octantkey]); |
| 1151 | + octant_map.erase(octantkey); |
| 1152 | + to_delete.remove_at_unordered(0); |
1145 | 1153 | } |
1146 | 1154 |
|
1147 | 1155 | _update_visibility(); |
|
0 commit comments