diff options
author | Juan Linietsky <reduzio@gmail.com> | 2016-07-21 10:06:38 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2016-07-21 10:11:53 -0300 |
commit | 124e3591a5b17e0fd4e50540dd909bed94792f32 (patch) | |
tree | c9f5b88a50be0c57b804f82b8891a403f53d9d6b /scene/resources | |
parent | ad55c63918bee55c84c2be9aff27f348c267d93e (diff) |
Some optimizations and limits for extreme zoom in and out in editor, fixes #5820
Diffstat (limited to 'scene/resources')
-rw-r--r-- | scene/resources/world_2d.cpp | 51 |
1 files changed, 42 insertions, 9 deletions
diff --git a/scene/resources/world_2d.cpp b/scene/resources/world_2d.cpp index e96cac170b..6b329a1a73 100644 --- a/scene/resources/world_2d.cpp +++ b/scene/resources/world_2d.cpp @@ -235,19 +235,20 @@ struct SpatialIndexer2D { List<VisibilityNotifier2D*> added; List<VisibilityNotifier2D*> removed; - for(int i=begin.x;i<=end.x;i++) { + int visible_cells=(end.x-begin.x)*(end.y-begin.y); - for(int j=begin.y;j<=end.y;j++) { + if (visible_cells>10000) { - CellKey ck; - ck.x=i; - ck.y=j; + //well you zoomed out a lot, it's your problem. To avoid freezing in the for loops below, we'll manually check cell by cell - Map<CellKey,CellData>::Element *F=cells.find(ck); - if (!F) { - continue; - } + for (Map<CellKey,CellData>::Element *F=cells.front();F;F=F->next()) { + + const CellKey &ck=F->key(); + if (ck.x<begin.x || ck.x>end.x) + continue; + if (ck.y<begin.y || ck.y>end.y) + continue; //notifiers in cell for (Map<VisibilityNotifier2D*,CellRef>::Element *G=F->get().notifiers.front();G;G=G->next()) { @@ -262,6 +263,38 @@ struct SpatialIndexer2D { } } } + + } else { + + //check cells in grid fashion + for(int i=begin.x;i<=end.x;i++) { + + for(int j=begin.y;j<=end.y;j++) { + + CellKey ck; + ck.x=i; + ck.y=j; + + Map<CellKey,CellData>::Element *F=cells.find(ck); + if (!F) { + continue; + } + + + //notifiers in cell + for (Map<VisibilityNotifier2D*,CellRef>::Element *G=F->get().notifiers.front();G;G=G->next()) { + + Map<VisibilityNotifier2D*,uint64_t>::Element *H=E->get().notifiers.find(G->key()); + if (!H) { + + H=E->get().notifiers.insert(G->key(),pass); + added.push_back(G->key()); + } else { + H->get()=pass; + } + } + } + } } for (Map<VisibilityNotifier2D*,uint64_t>::Element *F=E->get().notifiers.front();F;F=F->next()) { |