Browse Source

Added "main" attribute to camera

BearishSun 10 years ago
parent
commit
fcb7247e94

+ 10 - 0
BansheeEngine/Include/BsCCamera.h

@@ -272,6 +272,16 @@ namespace BansheeEngine
 		 */
 		 */
 		Vector3 unprojectPoint(const Vector3& point) const { return mInternal->unprojectPoint(point); }
 		Vector3 unprojectPoint(const Vector3& point) const { return mInternal->unprojectPoint(point); }
 
 
+		/**
+		 * @copydoc	Camera::isMain
+		 */	
+		bool isMain() const { return mInternal->isMain(); }
+
+		/**
+		 * @copydoc	Camera::setMain
+		 */	
+		void setMain(bool main);
+
 		/**
 		/**
 		 * @brief	Returns the internal camera that is used for
 		 * @brief	Returns the internal camera that is used for
 		 *			majority of operations by this component.
 		 *			majority of operations by this component.

+ 13 - 0
BansheeEngine/Include/BsCamera.h

@@ -558,6 +558,18 @@ namespace BansheeEngine
 		 */	
 		 */	
 		ViewportPtr getViewport() const { return mViewport; }
 		ViewportPtr getViewport() const { return mViewport; }
 
 
+		/**
+		 * @brief	Determines whether this is the main application camera. Main camera controls the final render
+		 *			surface that is displayed to the user.
+		 */	
+		bool isMain() const { return mMain; }
+
+		/**
+		 * @brief	Marks or unmarks this camera as the main application camera. Main camera controls the final render
+		 *			surface that is displayed to the user.
+		 */	
+		void setMain(bool main) { mMain = main; }
+
 		/**
 		/**
 		 * @brief	Retrieves an implementation of a camera handler usable only from the
 		 * @brief	Retrieves an implementation of a camera handler usable only from the
 		 *			core thread.
 		 *			core thread.
@@ -615,6 +627,7 @@ namespace BansheeEngine
 		static CameraPtr createEmpty();
 		static CameraPtr createEmpty();
 
 
 		ViewportPtr mViewport; /**< Viewport that describes 2D rendering surface. */
 		ViewportPtr mViewport; /**< Viewport that describes 2D rendering surface. */
+		bool mMain;
 		UINT32 mLastUpdateHash;
 		UINT32 mLastUpdateHash;
 
 
 		/************************************************************************/
 		/************************************************************************/

+ 17 - 0
BansheeEngine/Include/BsSceneManager.h

@@ -88,6 +88,15 @@ namespace BansheeEngine
 		 */
 		 */
 		const Map<Renderable*, SceneRenderableData>& getAllRenderables() const { return mRenderables; }
 		const Map<Renderable*, SceneRenderableData>& getAllRenderables() const { return mRenderables; }
 
 
+		/**
+		 * @brief	Returns the camera in the scene marked as main. Main camera controls the final render
+		 *			surface that is displayed to the user. If there are multiple main cameras, the first one found
+		 *			returned.
+		 *
+		 * @note	Internal method.
+		 */
+		SceneCameraData getMainCamera() const;
+
 		/**
 		/**
 		 * @brief	Notifies the scene manager that a new renderable was created.
 		 * @brief	Notifies the scene manager that a new renderable was created.
 		 * 
 		 * 
@@ -116,6 +125,13 @@ namespace BansheeEngine
 		 */
 		 */
 		void _unregisterCamera(const SPtr<Camera>& camera);
 		void _unregisterCamera(const SPtr<Camera>& camera);
 
 
+		/**
+		 * @brief	Notifies the scene manager that a camera either became the main camera, or has stopped being main camera.
+		 *
+		 * @note	Internal method.
+		 */
+		void _notifyMainCameraStateChanged(const SPtr<Camera>& camera);
+
 		/**
 		/**
 		 * @brief	Notifies the scene manager that a new light was created.
 		 * @brief	Notifies the scene manager that a new light was created.
 		 *
 		 *
@@ -149,6 +165,7 @@ namespace BansheeEngine
 		Map<Camera*, SceneCameraData> mCameras;
 		Map<Camera*, SceneCameraData> mCameras;
 		Map<Renderable*, SceneRenderableData> mRenderables;
 		Map<Renderable*, SceneRenderableData> mRenderables;
 		Map<Light*, SceneLightData> mLights;
 		Map<Light*, SceneLightData> mLights;
+		Vector<SceneCameraData> mMainCameras;
 
 
 		volatile static InitOnStart DoInitOnStart;
 		volatile static InitOnStart DoInitOnStart;
 	};
 	};

+ 7 - 0
BansheeEngine/Source/BsCCamera.cpp

@@ -55,6 +55,13 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
+	void CCamera::setMain(bool main)
+	{
+		mInternal->setMain(main);
+
+		gSceneManager()._notifyMainCameraStateChanged(mInternal);
+	}
+
 	void CCamera::update() 
 	void CCamera::update() 
 	{
 	{
 
 

+ 1 - 1
BansheeEngine/Source/BsCamera.cpp

@@ -731,7 +731,7 @@ namespace BansheeEngine
 	}
 	}
 
 
 	Camera::Camera(RenderTargetPtr target, float left, float top, float width, float height)
 	Camera::Camera(RenderTargetPtr target, float left, float top, float width, float height)
-		:mLastUpdateHash(0)
+		:mLastUpdateHash(0), mMain(false)
 	{
 	{
 		if (target != nullptr)
 		if (target != nullptr)
 			target->blockUntilCoreInitialized();
 			target->blockUntilCoreInitialized();

+ 28 - 0
BansheeEngine/Source/BsSceneManager.cpp

@@ -29,6 +29,26 @@ namespace BansheeEngine
 		mCameras.erase(camera.get());
 		mCameras.erase(camera.get());
 	}
 	}
 
 
+	void SceneManager::_notifyMainCameraStateChanged(const SPtr<Camera>& camera)
+	{
+		auto iterFind = std::find_if(mMainCameras.begin(), mMainCameras.end(),
+			[&](const SceneCameraData& entry)
+		{
+			return entry.camera == camera;
+		});
+
+		if (camera->isMain())
+		{
+			if (iterFind == mMainCameras.end())
+				mMainCameras.push_back(mCameras[camera.get()]);
+		}
+		else
+		{
+			if (iterFind != mMainCameras.end())
+				mMainCameras.erase(iterFind);
+		}
+	}
+
 	void SceneManager::_registerLight(const SPtr<Light>& light, const HSceneObject& so)
 	void SceneManager::_registerLight(const SPtr<Light>& light, const HSceneObject& so)
 	{
 	{
 		mLights[light.get()] = SceneLightData(light, so);
 		mLights[light.get()] = SceneLightData(light, so);
@@ -92,6 +112,14 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
+	SceneCameraData SceneManager::getMainCamera() const
+	{
+		if (mMainCameras.size() > 0)
+			return mMainCameras[0];
+
+		return SceneCameraData();
+	}
+
 	SceneManager& SceneManager::instance()
 	SceneManager& SceneManager::instance()
 	{
 	{
 		return static_cast<SceneManager&>(CoreSceneManager::instance());
 		return static_cast<SceneManager&>(CoreSceneManager::instance());

+ 10 - 0
MBansheeEditor/Inspectors/CameraInspector.cs

@@ -25,6 +25,7 @@ namespace BansheeEditor
         private GUIColorField clearColorField = new GUIColorField(new LocEdString("Clear color"));
         private GUIColorField clearColorField = new GUIColorField(new LocEdString("Clear color"));
         private GUIIntField priorityField = new GUIIntField(new LocEdString("Render priority"));
         private GUIIntField priorityField = new GUIIntField(new LocEdString("Render priority"));
         private GUIListBoxField layersField = new GUIListBoxField(Layers.Names, true, new LocEdString("Layers"));
         private GUIListBoxField layersField = new GUIListBoxField(Layers.Names, true, new LocEdString("Layers"));
+        private GUIToggleField mainField = new GUIToggleField(new LocEdString("Main"));
 
 
         private ulong layersValue = 0;
         private ulong layersValue = 0;
         private InspectableState modifyState;
         private InspectableState modifyState;
@@ -63,6 +64,7 @@ namespace BansheeEditor
             clearDepthField.Value = camera.ClearDepth;
             clearDepthField.Value = camera.ClearDepth;
             clearColorField.Value = camera.ClearColor;
             clearColorField.Value = camera.ClearColor;
             priorityField.Value = camera.Priority;
             priorityField.Value = camera.Priority;
+            mainField.Value = camera.Main;
 
 
             if (layersValue != camera.Layers)
             if (layersValue != camera.Layers)
             {
             {
@@ -201,6 +203,13 @@ namespace BansheeEditor
                     ConfirmModify();
                     ConfirmModify();
                 };
                 };
 
 
+                mainField.OnChanged += x =>
+                {
+                    camera.Main = x; 
+                    MarkAsModified();
+                    ConfirmModify();
+                };
+
                 Layout.AddElement(projectionTypeField);
                 Layout.AddElement(projectionTypeField);
                 Layout.AddElement(fieldOfView);
                 Layout.AddElement(fieldOfView);
                 Layout.AddElement(orthoHeight);
                 Layout.AddElement(orthoHeight);
@@ -225,6 +234,7 @@ namespace BansheeEditor
                 Layout.AddElement(clearStencilField);
                 Layout.AddElement(clearStencilField);
                 Layout.AddElement(priorityField);
                 Layout.AddElement(priorityField);
                 Layout.AddElement(layersField);
                 Layout.AddElement(layersField);
+                Layout.AddElement(mainField);
 
 
                 ToggleTypeSpecificFields(camera.ProjectionType);
                 ToggleTypeSpecificFields(camera.ProjectionType);
             }
             }

+ 10 - 0
MBansheeEngine/Camera.cs

@@ -222,6 +222,16 @@ namespace BansheeEngine
             set { native.target = value; }
             set { native.target = value; }
         }
         }
 
 
+        /// <summary>
+        /// Determines if this is the main application camera. Main camera controls the final render surface that is 
+        /// displayed to the user.
+        /// </summary>
+        public bool Main
+        {
+            get { return native.main; }
+            set { native.main = value; }
+        }
+
         /// <summary>
         /// <summary>
         /// Converts a point in world space to screen coordinates.
         /// Converts a point in world space to screen coordinates.
         /// </summary>
         /// </summary>

+ 11 - 0
MBansheeEngine/NativeCamera.cs

@@ -168,6 +168,12 @@ namespace BansheeEngine
             }
             }
         }
         }
 
 
+        internal bool main
+        {
+            get { return Internal_GetMain(mCachedPtr); }
+            set { Internal_SetMain(mCachedPtr, value); }
+        }
+
         internal Vector2I WorldToScreen(Vector3 value) { return Internal_WorldToScreen(mCachedPtr, value); }
         internal Vector2I WorldToScreen(Vector3 value) { return Internal_WorldToScreen(mCachedPtr, value); }
         internal Vector2 WorldToClip(Vector3 value) { return Internal_WorldToClip(mCachedPtr, value); }
         internal Vector2 WorldToClip(Vector3 value) { return Internal_WorldToClip(mCachedPtr, value); }
         internal Vector3 WorldToView(Vector3 value) { return Internal_WorldToView(mCachedPtr, value); }
         internal Vector3 WorldToView(Vector3 value) { return Internal_WorldToView(mCachedPtr, value); }
@@ -333,6 +339,11 @@ namespace BansheeEngine
         [MethodImpl(MethodImplOptions.InternalCall)]
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_SetRenderTarget(IntPtr instance, IntPtr rt);
         private static extern void Internal_SetRenderTarget(IntPtr instance, IntPtr rt);
 
 
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern bool Internal_GetMain(IntPtr instance);
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetMain(IntPtr instance, bool main);
+
         [MethodImpl(MethodImplOptions.InternalCall)]
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_UpdateView(IntPtr instance, IntPtr parentSO);
         private static extern void Internal_UpdateView(IntPtr instance, IntPtr parentSO);
 
 

+ 20 - 0
MBansheeEngine/Scene.cs

@@ -28,6 +28,23 @@ namespace BansheeEngine
             get { return Internal_GetRoot(); }
             get { return Internal_GetRoot(); }
         }
         }
 
 
+        /// <summary>
+        /// Returns the main camera that controls the final render surface that is displayed to the user. If the current
+        /// scene has no main camera null is returned.
+        /// </summary>
+        public static Camera Camera
+        {
+            get
+            {
+                SceneObject so = Internal_GetMainCameraSO();
+
+                if (so == null)
+                    return null;
+
+                return so.GetComponent<Camera>();
+            }
+        }
+
         /// <summary>
         /// <summary>
         /// Clears all scene objects from the current scene.
         /// Clears all scene objects from the current scene.
         /// </summary>
         /// </summary>
@@ -62,5 +79,8 @@ namespace BansheeEngine
 
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_ClearScene();
         private static extern void Internal_ClearScene();
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern SceneObject Internal_GetMainCameraSO();
     }
     }
 }
 }

+ 3 - 0
SBansheeEngine/Include/BsScriptCamera.h

@@ -115,6 +115,9 @@ namespace BansheeEngine
 
 
 		static void internal_SetRenderTarget(ScriptCamera* instance, ScriptRenderTarget* target);
 		static void internal_SetRenderTarget(ScriptCamera* instance, ScriptRenderTarget* target);
 
 
+		static bool internal_GetMain(ScriptCamera* instance);
+		static void internal_SetMain(ScriptCamera* instance, bool main);
+
 		static void internal_UpdateView(ScriptCamera* instance, ScriptSceneObject* parent);
 		static void internal_UpdateView(ScriptCamera* instance, ScriptSceneObject* parent);
 		static void internal_OnDestroy(ScriptCamera* instance);
 		static void internal_OnDestroy(ScriptCamera* instance);
 	};
 	};

+ 1 - 0
SBansheeEngine/Include/BsScriptScene.h

@@ -22,5 +22,6 @@ namespace BansheeEngine
 		static MonoObject* internal_LoadScene(MonoString* path);
 		static MonoObject* internal_LoadScene(MonoString* path);
 		static MonoObject* internal_GetRoot();
 		static MonoObject* internal_GetRoot();
 		static void internal_ClearScene();
 		static void internal_ClearScene();
+		static MonoObject* internal_GetMainCameraSO();
 	};
 	};
 }
 }

+ 14 - 0
SBansheeEngine/Source/BsScriptCamera.cpp

@@ -106,6 +106,9 @@ namespace BansheeEngine
 
 
 		metaData.scriptClass->addInternalCall("Internal_SetRenderTarget", &ScriptCamera::internal_SetRenderTarget);
 		metaData.scriptClass->addInternalCall("Internal_SetRenderTarget", &ScriptCamera::internal_SetRenderTarget);
 
 
+		metaData.scriptClass->addInternalCall("Internal_GetMain", &ScriptCamera::internal_GetMain);
+		metaData.scriptClass->addInternalCall("Internal_SetMain", &ScriptCamera::internal_SetMain);
+
 		metaData.scriptClass->addInternalCall("Internal_UpdateView", &ScriptCamera::internal_UpdateView);
 		metaData.scriptClass->addInternalCall("Internal_UpdateView", &ScriptCamera::internal_UpdateView);
 		metaData.scriptClass->addInternalCall("Internal_OnDestroy", &ScriptCamera::internal_OnDestroy);
 		metaData.scriptClass->addInternalCall("Internal_OnDestroy", &ScriptCamera::internal_OnDestroy);
 	}
 	}
@@ -405,6 +408,17 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
+	bool ScriptCamera::internal_GetMain(ScriptCamera* instance)
+	{
+		return instance->mCamera->isMain();
+	}
+
+	void ScriptCamera::internal_SetMain(ScriptCamera* instance, bool main)
+	{
+		instance->mCamera->setMain(main);
+		gSceneManager()._notifyMainCameraStateChanged(instance->mCamera);
+	}
+
 	void ScriptCamera::internal_UpdateView(ScriptCamera* instance, ScriptSceneObject* parent)
 	void ScriptCamera::internal_UpdateView(ScriptCamera* instance, ScriptSceneObject* parent)
 	{
 	{
 		HSceneObject parentSO = parent->getNativeSceneObject();
 		HSceneObject parentSO = parent->getNativeSceneObject();

+ 11 - 0
SBansheeEngine/Source/BsScriptScene.cpp

@@ -25,6 +25,7 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_LoadScene", &ScriptScene::internal_LoadScene);
 		metaData.scriptClass->addInternalCall("Internal_LoadScene", &ScriptScene::internal_LoadScene);
 		metaData.scriptClass->addInternalCall("Internal_GetRoot", &ScriptScene::internal_GetRoot);
 		metaData.scriptClass->addInternalCall("Internal_GetRoot", &ScriptScene::internal_GetRoot);
 		metaData.scriptClass->addInternalCall("Internal_ClearScene", &ScriptScene::internal_ClearScene);
 		metaData.scriptClass->addInternalCall("Internal_ClearScene", &ScriptScene::internal_ClearScene);
+		metaData.scriptClass->addInternalCall("Internal_GetMainCameraSO", &ScriptScene::internal_GetMainCameraSO);
 	}
 	}
 
 
 	MonoObject* ScriptScene::internal_LoadScene(MonoString* path)
 	MonoObject* ScriptScene::internal_LoadScene(MonoString* path)
@@ -82,4 +83,14 @@ namespace BansheeEngine
 	{
 	{
 		gSceneManager().clearScene();
 		gSceneManager().clearScene();
 	}
 	}
+
+	MonoObject* ScriptScene::internal_GetMainCameraSO()
+	{
+		SceneCameraData cameraData = gSceneManager().getMainCamera();
+		if (cameraData.sceneObject == nullptr)
+			return nullptr;
+
+		ScriptSceneObject* cameraSo = ScriptGameObjectManager::instance().getOrCreateScriptSceneObject(cameraData.sceneObject);
+		return cameraSo->getManagedInstance();
+	}
 }
 }