summaryrefslogtreecommitdiff
path: root/scene/resources
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2016-07-21 10:06:38 -0300
committerJuan Linietsky <reduzio@gmail.com>2016-07-21 10:11:53 -0300
commit124e3591a5b17e0fd4e50540dd909bed94792f32 (patch)
treec9f5b88a50be0c57b804f82b8891a403f53d9d6b /scene/resources
parentad55c63918bee55c84c2be9aff27f348c267d93e (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.cpp51
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()) {