瀏覽代碼

Some optimizations and limits for extreme zoom in and out in editor, fixes #5820

Juan Linietsky 9 年之前
父節點
當前提交
124e3591a5
共有 2 個文件被更改,包括 58 次插入9 次删除
  1. 42 9
      scene/resources/world_2d.cpp
  2. 16 0
      tools/editor/plugins/canvas_item_editor_plugin.cpp

+ 42 - 9
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()) {

+ 16 - 0
tools/editor/plugins/canvas_item_editor_plugin.cpp

@@ -41,6 +41,11 @@
 #include "tools/editor/plugins/animation_player_editor_plugin.h"
 #include "scene/resources/packed_scene.h"
 
+
+#define MIN_ZOOM 0.01
+#define MAX_ZOOM 100
+
+
 class SnapDialog : public ConfirmationDialog {
 
 	OBJ_TYPE(SnapDialog,ConfirmationDialog);
@@ -1062,6 +1067,9 @@ void CanvasItemEditor::_viewport_input_event(const InputEvent& p_event) {
 
 		if (b.button_index==BUTTON_WHEEL_DOWN) {
 
+			if (zoom<MIN_ZOOM)
+				return;
+
 			float prev_zoom=zoom;
 			zoom=zoom*0.95;
 			{
@@ -1077,6 +1085,9 @@ void CanvasItemEditor::_viewport_input_event(const InputEvent& p_event) {
 
 		if (b.button_index==BUTTON_WHEEL_UP) {
 
+			if (zoom>MAX_ZOOM)
+				return;
+
 			float prev_zoom=zoom;
 			zoom=zoom*(1.0/0.95);
 			{
@@ -2526,12 +2537,17 @@ void CanvasItemEditor::_popup_callback(int p_op) {
 			snap_dialog->popup_centered(Size2(220,160));
 		} break;
 		case ZOOM_IN: {
+			if (zoom>MAX_ZOOM)
+				return;
 			zoom=zoom*(1.0/0.5);
 			_update_scroll(0);
 			viewport->update();
 			return;
 		} break;
 		case ZOOM_OUT: {
+			if (zoom<MIN_ZOOM)
+				return;
+
 			zoom=zoom*0.5;
 			_update_scroll(0);
 			viewport->update();