Browse Source

Merge pull request #26942 from RandomShaper/fix-vp-issues

Fix Viewport and Camera issues
Rémi Verschelde 6 years ago
parent
commit
62b868fd37
3 changed files with 24 additions and 41 deletions
  1. 18 10
      scene/3d/camera.cpp
  2. 1 0
      scene/3d/camera.h
  3. 5 31
      scene/main/viewport.cpp

+ 18 - 10
scene/3d/camera.cpp

@@ -106,9 +106,15 @@ void Camera::_notification(int p_what) {
 
 		case NOTIFICATION_ENTER_WORLD: {
 
-			bool first_camera = get_viewport()->_camera_add(this);
-			if (!get_tree()->is_node_being_edited(this) && (current || first_camera))
-				make_current();
+			// Needs to track the Viewport  because it's needed on NOTIFICATION_EXIT_WORLD
+			// and Spatial will handle it first, including clearing its reference to the Viewport,
+			// therefore making it impossible to subclasses to access it
+			viewport = get_viewport();
+			ERR_FAIL_COND(!viewport);
+
+			bool first_camera = viewport->_camera_add(this);
+			if (current || first_camera)
+				viewport->_camera_set(this);
 
 		} break;
 		case NOTIFICATION_TRANSFORM_CHANGED: {
@@ -130,17 +136,20 @@ void Camera::_notification(int p_what) {
 				}
 			}
 
-			get_viewport()->_camera_remove(this);
+			if (viewport) {
+				viewport->_camera_remove(this);
+				viewport = NULL;
+			}
 
 		} break;
 		case NOTIFICATION_BECAME_CURRENT: {
-			if (get_world().is_valid()) {
-				get_world()->_register_camera(this);
+			if (viewport) {
+				viewport->find_world()->_register_camera(this);
 			}
 		} break;
 		case NOTIFICATION_LOST_CURRENT: {
-			if (get_world().is_valid()) {
-				get_world()->_remove_camera(this);
+			if (viewport) {
+				viewport->find_world()->_remove_camera(this);
 			}
 		} break;
 	}
@@ -255,8 +264,6 @@ bool Camera::is_current() const {
 		return get_viewport()->get_camera() == this;
 	} else
 		return current;
-
-	return false;
 }
 
 bool Camera::_can_gizmo_scale() const {
@@ -694,6 +701,7 @@ Camera::Camera() {
 	near = 0;
 	far = 0;
 	current = false;
+	viewport = NULL;
 	force_change = false;
 	mode = PROJECTION_PERSPECTIVE;
 	set_perspective(70.0, 0.05, 100.0);

+ 1 - 0
scene/3d/camera.h

@@ -64,6 +64,7 @@ public:
 private:
 	bool force_change;
 	bool current;
+	Viewport *viewport;
 
 	Projection mode;
 

+ 5 - 31
scene/main/viewport.cpp

@@ -886,7 +886,7 @@ void Viewport::_camera_set(Camera *p_camera) {
 	if (camera == p_camera)
 		return;
 
-	if (camera && find_world().is_valid()) {
+	if (camera) {
 		camera->notification(Camera::NOTIFICATION_LOST_CURRENT);
 	}
 	camera = p_camera;
@@ -895,7 +895,7 @@ void Viewport::_camera_set(Camera *p_camera) {
 	else
 		VisualServer::get_singleton()->viewport_attach_camera(viewport, RID());
 
-	if (camera && find_world().is_valid()) {
+	if (camera) {
 		camera->notification(Camera::NOTIFICATION_BECAME_CURRENT);
 	}
 
@@ -914,9 +914,7 @@ void Viewport::_camera_remove(Camera *p_camera) {
 
 	cameras.erase(p_camera);
 	if (camera == p_camera) {
-		if (camera && find_world().is_valid()) {
-			camera->notification(Camera::NOTIFICATION_LOST_CURRENT);
-		}
+		camera->notification(Camera::NOTIFICATION_LOST_CURRENT);
 		camera = NULL;
 	}
 }
@@ -1013,7 +1011,7 @@ void Viewport::_propagate_enter_world(Node *p_node) {
 			Viewport *v = Object::cast_to<Viewport>(p_node);
 			if (v) {
 
-				if (v->world.is_valid())
+				if (v->world.is_valid() || v->own_world.is_valid())
 					return;
 			}
 		}
@@ -1050,7 +1048,7 @@ void Viewport::_propagate_exit_world(Node *p_node) {
 			Viewport *v = Object::cast_to<Viewport>(p_node);
 			if (v) {
 
-				if (v->world.is_valid())
+				if (v->world.is_valid() || v->own_world.is_valid())
 					return;
 			}
 		}
@@ -1070,23 +1068,11 @@ void Viewport::set_world(const Ref<World> &p_world) {
 	if (is_inside_tree())
 		_propagate_exit_world(this);
 
-#ifndef _3D_DISABLED
-	if (find_world().is_valid() && camera)
-		camera->notification(Camera::NOTIFICATION_LOST_CURRENT);
-#endif
-
 	world = p_world;
 
 	if (is_inside_tree())
 		_propagate_enter_world(this);
 
-#ifndef _3D_DISABLED
-	if (find_world().is_valid() && camera)
-		camera->notification(Camera::NOTIFICATION_BECAME_CURRENT);
-#endif
-
-	//propagate exit
-
 	if (is_inside_tree()) {
 		VisualServer::get_singleton()->viewport_set_scenario(viewport, find_world()->get_scenario());
 	}
@@ -2722,11 +2708,6 @@ void Viewport::set_use_own_world(bool p_world) {
 	if (is_inside_tree())
 		_propagate_exit_world(this);
 
-#ifndef _3D_DISABLED
-	if (find_world().is_valid() && camera)
-		camera->notification(Camera::NOTIFICATION_LOST_CURRENT);
-#endif
-
 	if (!p_world)
 		own_world = Ref<World>();
 	else
@@ -2735,13 +2716,6 @@ void Viewport::set_use_own_world(bool p_world) {
 	if (is_inside_tree())
 		_propagate_enter_world(this);
 
-#ifndef _3D_DISABLED
-	if (find_world().is_valid() && camera)
-		camera->notification(Camera::NOTIFICATION_BECAME_CURRENT);
-#endif
-
-	//propagate exit
-
 	if (is_inside_tree()) {
 		VisualServer::get_singleton()->viewport_set_scenario(viewport, find_world()->get_scenario());
 	}