Просмотр исходного кода

Set up gizmo picking (icons still don't work)
Various fixes related to handle rendering

Marko Pintera 11 лет назад
Родитель
Сommit
7ee22c56b5
29 измененных файлов с 260 добавлено и 276 удалено
  1. 1 2
      BansheeCore/Include/BsRenderSystem.h
  2. 2 2
      BansheeCore/Source/BsRenderSystem.cpp
  3. 1 1
      BansheeD3D11RenderSystem/Include/BsD3D11RenderSystem.h
  4. 1 10
      BansheeD3D11RenderSystem/Source/BsD3D11RenderSystem.cpp
  5. 1 1
      BansheeD3D9RenderSystem/Include/BsD3D9RenderSystem.h
  6. 1 10
      BansheeD3D9RenderSystem/Source/BsD3D9RenderSystem.cpp
  7. 13 7
      BansheeEditor/Include/BsGizmoManager.h
  8. 4 21
      BansheeEditor/Include/BsScenePicking.h
  9. 1 1
      BansheeEditor/Source/BsBuiltinEditorResources.cpp
  10. 101 114
      BansheeEditor/Source/BsGizmoManager.cpp
  11. 6 2
      BansheeEditor/Source/BsHandleSliderManager.cpp
  12. 1 1
      BansheeEditor/Source/BsSceneEditorWidget.cpp
  13. 1 1
      BansheeEditor/Source/BsSceneGrid.cpp
  14. 55 58
      BansheeEditor/Source/BsScenePicking.cpp
  15. 1 1
      BansheeEditorExec/BsEditorExec.cpp
  16. 5 5
      BansheeEngine/Source/BsCamera.cpp
  17. 9 8
      BansheeEngine/Source/BsDrawHelper.cpp
  18. 18 4
      BansheeEngine/Source/BsShapeMeshes3D.cpp
  19. 1 2
      BansheeGLRenderSystem/Include/BsGLRenderSystem.h
  20. 1 1
      BansheeGLRenderSystem/Source/BsGLRenderSystem.cpp
  21. 7 4
      BansheeUtility/Include/BsAsyncOp.h
  22. 1 3
      BansheeUtility/Include/BsMatrix4.h
  23. 2 2
      MBansheeEngine/Math/Matrix3.cs
  24. 1 1
      Notes.txt
  25. 9 1
      SBansheeEditor/Source/BsScriptGizmoManager.cpp
  26. 4 4
      SBansheeEditor/Source/BsScriptHandleSliderDisc.cpp
  27. 3 3
      SBansheeEditor/Source/BsScriptHandleSliderLine.cpp
  28. 4 4
      SBansheeEditor/Source/BsScriptHandleSliderPlane.cpp
  29. 5 2
      SceneView.txt

+ 1 - 2
BansheeCore/Include/BsRenderSystem.h

@@ -285,8 +285,7 @@ namespace BansheeEngine
 		 *
 		 *
 		 * @note	Thread safe.
 		 * @note	Thread safe.
 		 */
 		 */
-		virtual void convertProjectionMatrix(const Matrix4& matrix,
-			Matrix4& dest, bool forGpuProgram = false) = 0;
+		virtual void convertProjectionMatrix(const Matrix4& matrix, Matrix4& dest) = 0;
 
 
 		/**
 		/**
 		 * @brief	Gets horizontal texel offset used for mapping texels to pixels
 		 * @brief	Gets horizontal texel offset used for mapping texels to pixels

+ 2 - 2
BansheeCore/Source/BsRenderSystem.cpp

@@ -15,8 +15,8 @@
 
 
 using namespace std::placeholders;
 using namespace std::placeholders;
 
 
-namespace BansheeEngine {
-
+namespace BansheeEngine 
+{
     static const TexturePtr sNullTexPtr;
     static const TexturePtr sNullTexPtr;
 
 
     RenderSystem::RenderSystem()
     RenderSystem::RenderSystem()

+ 1 - 1
BansheeD3D11RenderSystem/Include/BsD3D11RenderSystem.h

@@ -143,7 +143,7 @@ namespace BansheeEngine
 		/**
 		/**
 		 * @copydoc	RenderSystem::convertProjectionMatrix
 		 * @copydoc	RenderSystem::convertProjectionMatrix
 		 */
 		 */
-		void convertProjectionMatrix(const Matrix4& matrix, Matrix4& dest, bool forGpuProgram = false);
+		void convertProjectionMatrix(const Matrix4& matrix, Matrix4& dest);
 
 
 		/**
 		/**
 		 * @copydoc	RenderSystem::getColorVertexElementType
 		 * @copydoc	RenderSystem::getColorVertexElementType

+ 1 - 10
BansheeD3D11RenderSystem/Source/BsD3D11RenderSystem.cpp

@@ -988,7 +988,7 @@ namespace BansheeEngine
 		return VET_COLOR_ABGR;
 		return VET_COLOR_ABGR;
 	}
 	}
 
 
-	void D3D11RenderSystem::convertProjectionMatrix(const Matrix4& matrix, Matrix4& dest, bool forGpuProgram)
+	void D3D11RenderSystem::convertProjectionMatrix(const Matrix4& matrix, Matrix4& dest)
 	{
 	{
 		dest = matrix;
 		dest = matrix;
 
 
@@ -997,15 +997,6 @@ namespace BansheeEngine
 		dest[2][1] = (dest[2][1] + dest[3][1]) / 2;
 		dest[2][1] = (dest[2][1] + dest[3][1]) / 2;
 		dest[2][2] = (dest[2][2] + dest[3][2]) / 2;
 		dest[2][2] = (dest[2][2] + dest[3][2]) / 2;
 		dest[2][3] = (dest[2][3] + dest[3][3]) / 2;
 		dest[2][3] = (dest[2][3] + dest[3][3]) / 2;
-
-		if (!forGpuProgram)
-		{
-			// Convert right-handed to left-handed
-			dest[0][2] = -dest[0][2];
-			dest[1][2] = -dest[1][2];
-			dest[2][2] = -dest[2][2];
-			dest[3][2] = -dest[3][2];
-		}
 	}
 	}
 
 
 	float D3D11RenderSystem::getHorizontalTexelOffset()
 	float D3D11RenderSystem::getHorizontalTexelOffset()

+ 1 - 1
BansheeD3D9RenderSystem/Include/BsD3D9RenderSystem.h

@@ -138,7 +138,7 @@ namespace BansheeEngine
 		/**
 		/**
 		 * @copydoc RenderSystem::convertProjectionMatrix()
 		 * @copydoc RenderSystem::convertProjectionMatrix()
 		 */
 		 */
-		void convertProjectionMatrix(const Matrix4& matrix, Matrix4& dest, bool forGpuProgram = false);
+		void convertProjectionMatrix(const Matrix4& matrix, Matrix4& dest);
 
 
 		/**
 		/**
 		 * @copydoc	RenderSystem::getHorizontalTexelOffset
 		 * @copydoc	RenderSystem::getHorizontalTexelOffset

+ 1 - 10
BansheeD3D9RenderSystem/Source/BsD3D9RenderSystem.cpp

@@ -1511,7 +1511,7 @@ namespace BansheeEngine
 		return VET_COLOR_ARGB;
 		return VET_COLOR_ARGB;
 	}
 	}
 
 
-	void D3D9RenderSystem::convertProjectionMatrix(const Matrix4& matrix, Matrix4& dest, bool forGpuProgram)
+	void D3D9RenderSystem::convertProjectionMatrix(const Matrix4& matrix, Matrix4& dest)
 	{
 	{
 		dest = matrix;
 		dest = matrix;
 
 
@@ -1520,15 +1520,6 @@ namespace BansheeEngine
 		dest[2][1] = (dest[2][1] + dest[3][1]) / 2;
 		dest[2][1] = (dest[2][1] + dest[3][1]) / 2;
 		dest[2][2] = (dest[2][2] + dest[3][2]) / 2;
 		dest[2][2] = (dest[2][2] + dest[3][2]) / 2;
 		dest[2][3] = (dest[2][3] + dest[3][3]) / 2;
 		dest[2][3] = (dest[2][3] + dest[3][3]) / 2;
-
-		if (!forGpuProgram)
-		{
-			// Convert right-handed to left-handed
-			dest[0][2] = -dest[0][2];
-			dest[1][2] = -dest[1][2];
-			dest[2][2] = -dest[2][2];
-			dest[3][2] = -dest[3][2];
-		}
 	}
 	}
 
 
 	/************************************************************************/
 	/************************************************************************/

+ 13 - 7
BansheeEditor/Include/BsGizmoManager.h

@@ -36,11 +36,19 @@ namespace BansheeEngine
 		void renderForPicking(const HCamera& camera, std::function<Color(UINT32)> idxToColorCallback);
 		void renderForPicking(const HCamera& camera, std::function<Color(UINT32)> idxToColorCallback);
 		void clearGizmos();
 		void clearGizmos();
 
 
+		HSceneObject getSceneObject(UINT32 gizmoIdx);
+
 	private:
 	private:
 		friend class GizmoManagerCore;
 		friend class GizmoManagerCore;
 
 
+		enum class GizmoMaterial
+		{
+			Solid, Wire, Picking
+		};
+
 		struct CommonData
 		struct CommonData
 		{
 		{
+			UINT32 idx;
 			Color color;
 			Color color;
 			Matrix4 transform;
 			Matrix4 transform;
 			HSceneObject sceneObject;
 			HSceneObject sceneObject;
@@ -99,7 +107,7 @@ namespace BansheeEngine
 		typedef Vector<IconRenderData> IconRenderDataVec;
 		typedef Vector<IconRenderData> IconRenderDataVec;
 		typedef std::shared_ptr<IconRenderDataVec> IconRenderDataVecPtr;
 		typedef std::shared_ptr<IconRenderDataVec> IconRenderDataVecPtr;
 
 
-		TransientMeshPtr buildIconMesh(const HCamera& camera, const Vector<IconData>& iconData, bool pickingOnly, IconRenderDataVecPtr& renderData);
+		TransientMeshPtr buildIconMesh(const HCamera& camera, const Vector<IconData>& iconData, bool forPicking, IconRenderDataVecPtr& renderData);
 
 
 		void limitIconSize(UINT32& width, UINT32& height);
 		void limitIconSize(UINT32& width, UINT32& height);
 		void calculateIconColors(const Color& tint, const Camera& camera, UINT32 iconHeight, bool fixedScale,
 		void calculateIconColors(const Color& tint, const Camera& camera, UINT32 iconHeight, bool fixedScale,
@@ -122,6 +130,7 @@ namespace BansheeEngine
 		Matrix4 mTransform;
 		Matrix4 mTransform;
 		HSceneObject mActiveSO;
 		HSceneObject mActiveSO;
 		bool mPickable;
 		bool mPickable;
+		UINT32 mCurrentIdx;
 
 
 		DrawHelper* mDrawHelper;
 		DrawHelper* mDrawHelper;
 		DrawHelper* mPickingDrawHelper;
 		DrawHelper* mPickingDrawHelper;
@@ -133,6 +142,7 @@ namespace BansheeEngine
 		Vector<LineData> mLineData;
 		Vector<LineData> mLineData;
 		Vector<FrustumData> mFrustumData;
 		Vector<FrustumData> mFrustumData;
 		Vector<IconData> mIconData;
 		Vector<IconData> mIconData;
+		Map<UINT32, HSceneObject> mIdxToSceneObjectMap;
 
 
 		MeshHeapPtr mIconMeshHeap;
 		MeshHeapPtr mIconMeshHeap;
 
 
@@ -203,12 +213,8 @@ namespace BansheeEngine
 		void initialize(const GizmoManager::CoreInitData& initData);
 		void initialize(const GizmoManager::CoreInitData& initData);
 
 
 		void render(const CameraProxy& camera);
 		void render(const CameraProxy& camera);
-		void renderSolidGizmos(Matrix4 viewMatrix, Matrix4 projMatrix, MeshProxyPtr mesh);
-		void renderWireGizmos(Matrix4 viewMatrix, Matrix4 projMatrix, MeshProxyPtr mesh);
-		void renderIconGizmos(Rect2I screenArea, MeshProxyPtr mesh, GizmoManager::IconRenderDataVecPtr renderData);
-
-		void renderGizmosForPicking(Matrix4 viewMatrix, Matrix4 projMatrix, MeshProxyPtr mesh);
-		void renderIconGizmosForPicking(Rect2I screenArea, MeshProxyPtr mesh, GizmoManager::IconRenderDataVecPtr renderData);
+		void renderGizmos(Matrix4 viewMatrix, Matrix4 projMatrix, MeshProxyPtr mesh, GizmoManager::GizmoMaterial material);
+		void renderIconGizmos(Rect2I screenArea, MeshProxyPtr mesh, GizmoManager::IconRenderDataVecPtr renderData, bool usePickingMaterial);
 
 
 		void updateData(const RenderTargetPtr& rt, const MeshProxyPtr& solidMeshProxy, const MeshProxyPtr& wireMeshProxy,
 		void updateData(const RenderTargetPtr& rt, const MeshProxyPtr& solidMeshProxy, const MeshProxyPtr& wireMeshProxy,
 			const MeshProxyPtr& iconMeshProxy, const GizmoManager::IconRenderDataVecPtr& iconRenderData);
 			const MeshProxyPtr& iconMeshProxy, const GizmoManager::IconRenderDataVecPtr& iconRenderData);

+ 4 - 21
BansheeEditor/Include/BsScenePicking.h

@@ -7,21 +7,6 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
-	class PickResult
-	{
-	public:
-		enum class Type
-		{
-			SceneObject,
-			Gizmo,
-			None
-		};
-
-		HSceneObject sceneObject;
-		UINT32 gizmoId;
-		Type type;
-	};
-
 	class ScenePicking : public Module<ScenePicking>
 	class ScenePicking : public Module<ScenePicking>
 	{
 	{
 		struct RenderablePickData
 		struct RenderablePickData
@@ -59,10 +44,8 @@ namespace BansheeEngine
 	public:
 	public:
 		ScenePicking();
 		ScenePicking();
 
 
-		HSceneObject pickClosestSceneObject(const HCamera& cam, const Vector2I& position, const Vector2I& area);
-		PickResult pickClosestObject(const HCamera& cam, const Vector2I& position, const Vector2I& area);
-		Vector<HSceneObject> pickSceneObjects(const HCamera& cam, const Vector2I& position, const Vector2I& area);
-		Vector<PickResult> pickObjects(const HCamera& cam, const Vector2I& position, const Vector2I& area);
+		HSceneObject pickClosestObject(const HCamera& cam, const Vector2I& position, const Vector2I& area);
+		Vector<HSceneObject> pickObjects(const HCamera& cam, const Vector2I& position, const Vector2I& area);
 
 
 	private:
 	private:
 		typedef Set<RenderablePickData, std::function<bool(const RenderablePickData&, const RenderablePickData&)>> RenderableSet;
 		typedef Set<RenderablePickData, std::function<bool(const RenderablePickData&, const RenderablePickData&)>> RenderableSet;
@@ -72,8 +55,8 @@ namespace BansheeEngine
 		Color encodeIndex(UINT32 index);
 		Color encodeIndex(UINT32 index);
 		UINT32 decodeIndex(Color color);
 		UINT32 decodeIndex(Color color);
 
 
-		void corePickObjects(const Viewport& viewport, const RenderableSet& renderables, const Vector2I& position,
-			const Vector2I& area, AsyncOp& asyncOp);
+		void corePickingBegin(const Viewport& viewport, const RenderableSet& renderables, const Vector2I& position, const Vector2I& area);
+		void corePickingEnd(const Viewport& viewport, const Vector2I& position, const Vector2I& area, AsyncOp& asyncOp);
 
 
 		static const float ALPHA_CUTOFF;
 		static const float ALPHA_CUTOFF;
 
 

+ 1 - 1
BansheeEditor/Source/BsBuiltinEditorResources.cpp

@@ -1420,7 +1420,6 @@ namespace BansheeEngine
 		blendDesc.renderTargetDesc[0].srcBlend = BF_SOURCE_ALPHA;
 		blendDesc.renderTargetDesc[0].srcBlend = BF_SOURCE_ALPHA;
 		blendDesc.renderTargetDesc[0].dstBlend = BF_INV_SOURCE_ALPHA;
 		blendDesc.renderTargetDesc[0].dstBlend = BF_INV_SOURCE_ALPHA;
 		blendDesc.renderTargetDesc[0].blendOp = BO_ADD;
 		blendDesc.renderTargetDesc[0].blendOp = BO_ADD;
-		blendDesc.renderTargetDesc[0].renderTargetWriteMask = 0x7; // Don't write to alpha
 
 
 		HBlendState blendState = BlendState::create(blendDesc);
 		HBlendState blendState = BlendState::create(blendDesc);
 
 
@@ -1491,6 +1490,7 @@ namespace BansheeEngine
 
 
 		mShaderGizmoAlphaPicking->addParameter("mainTexture", "mainTexture", GPOT_TEXTURE2D);
 		mShaderGizmoAlphaPicking->addParameter("mainTexture", "mainTexture", GPOT_TEXTURE2D);
 
 
+		mShaderGizmoAlphaPicking->addParameter("alphaCutoff", "alphaCutoff", GPDT_FLOAT1);
 		mShaderGizmoAlphaPicking->addParameter("matViewProj", "matViewProj", GPDT_MATRIX_4X4);
 		mShaderGizmoAlphaPicking->addParameter("matViewProj", "matViewProj", GPDT_MATRIX_4X4);
 
 
 		TechniquePtr newTechnique = mShaderGizmoAlphaPicking->addTechnique(mActiveRenderSystem, RendererInvariant);
 		TechniquePtr newTechnique = mShaderGizmoAlphaPicking->addTechnique(mActiveRenderSystem, RendererInvariant);

+ 101 - 114
BansheeEditor/Source/BsGizmoManager.cpp

@@ -31,8 +31,9 @@ namespace BansheeEngine
 	const float GizmoManager::ICON_TEXEL_WORLD_SIZE = 0.05f;
 	const float GizmoManager::ICON_TEXEL_WORLD_SIZE = 0.05f;
 
 
 	GizmoManager::GizmoManager()
 	GizmoManager::GizmoManager()
-		:mPickable(false), mDrawHelper(nullptr), mPickingDrawHelper(nullptr), mCore(nullptr)
+		:mPickable(false), mDrawHelper(nullptr), mPickingDrawHelper(nullptr), mCore(nullptr), mCurrentIdx(0)
 	{
 	{
+		mTransform = Matrix4::IDENTITY;
 		mDrawHelper = bs_new<DrawHelper>();
 		mDrawHelper = bs_new<DrawHelper>();
 		mPickingDrawHelper = bs_new<DrawHelper>();
 		mPickingDrawHelper = bs_new<DrawHelper>();
 
 
@@ -102,11 +103,13 @@ namespace BansheeEngine
 
 
 	void GizmoManager::setColor(const Color& color)
 	void GizmoManager::setColor(const Color& color)
 	{
 	{
+		mDrawHelper->setColor(color);
 		mColor = color;
 		mColor = color;
 	}
 	}
 
 
 	void GizmoManager::setTransform(const Matrix4& transform)
 	void GizmoManager::setTransform(const Matrix4& transform)
 	{
 	{
+		mDrawHelper->setTransform(transform);
 		mTransform = transform;
 		mTransform = transform;
 	}
 	}
 
 
@@ -115,6 +118,7 @@ namespace BansheeEngine
 		mSolidCubeData.push_back(CubeData());
 		mSolidCubeData.push_back(CubeData());
 		CubeData& cubeData = mSolidCubeData.back();
 		CubeData& cubeData = mSolidCubeData.back();
 
 
+		cubeData.idx = mCurrentIdx++;
 		cubeData.position = position;
 		cubeData.position = position;
 		cubeData.extents = extents;
 		cubeData.extents = extents;
 		cubeData.color = mColor;
 		cubeData.color = mColor;
@@ -123,6 +127,7 @@ namespace BansheeEngine
 		cubeData.pickable = mPickable;
 		cubeData.pickable = mPickable;
 
 
 		mDrawHelper->cube(position, extents);
 		mDrawHelper->cube(position, extents);
+		mIdxToSceneObjectMap[cubeData.idx] = mActiveSO;
 	}
 	}
 
 
 	void GizmoManager::drawSphere(const Vector3& position, float radius)
 	void GizmoManager::drawSphere(const Vector3& position, float radius)
@@ -130,6 +135,7 @@ namespace BansheeEngine
 		mSolidSphereData.push_back(SphereData());
 		mSolidSphereData.push_back(SphereData());
 		SphereData& sphereData = mSolidSphereData.back();
 		SphereData& sphereData = mSolidSphereData.back();
 
 
+		sphereData.idx = mCurrentIdx++;
 		sphereData.position = position;
 		sphereData.position = position;
 		sphereData.radius = radius;
 		sphereData.radius = radius;
 		sphereData.color = mColor;
 		sphereData.color = mColor;
@@ -138,6 +144,7 @@ namespace BansheeEngine
 		sphereData.pickable = mPickable;
 		sphereData.pickable = mPickable;
 
 
 		mDrawHelper->sphere(position, radius);
 		mDrawHelper->sphere(position, radius);
+		mIdxToSceneObjectMap[sphereData.idx] = mActiveSO;
 	}
 	}
 
 
 	void GizmoManager::drawWireCube(const Vector3& position, const Vector3& extents)
 	void GizmoManager::drawWireCube(const Vector3& position, const Vector3& extents)
@@ -145,6 +152,7 @@ namespace BansheeEngine
 		mWireCubeData.push_back(CubeData());
 		mWireCubeData.push_back(CubeData());
 		CubeData& cubeData = mWireCubeData.back();
 		CubeData& cubeData = mWireCubeData.back();
 
 
+		cubeData.idx = mCurrentIdx++;
 		cubeData.position = position;
 		cubeData.position = position;
 		cubeData.extents = extents;
 		cubeData.extents = extents;
 		cubeData.color = mColor;
 		cubeData.color = mColor;
@@ -153,6 +161,7 @@ namespace BansheeEngine
 		cubeData.pickable = mPickable;
 		cubeData.pickable = mPickable;
 
 
 		mDrawHelper->wireCube(position, extents);
 		mDrawHelper->wireCube(position, extents);
+		mIdxToSceneObjectMap[cubeData.idx] = mActiveSO;
 	}
 	}
 
 
 	void GizmoManager::drawWireSphere(const Vector3& position, float radius)
 	void GizmoManager::drawWireSphere(const Vector3& position, float radius)
@@ -160,6 +169,7 @@ namespace BansheeEngine
 		mWireSphereData.push_back(SphereData());
 		mWireSphereData.push_back(SphereData());
 		SphereData& sphereData = mWireSphereData.back();
 		SphereData& sphereData = mWireSphereData.back();
 
 
+		sphereData.idx = mCurrentIdx++;
 		sphereData.position = position;
 		sphereData.position = position;
 		sphereData.radius = radius;
 		sphereData.radius = radius;
 		sphereData.color = mColor;
 		sphereData.color = mColor;
@@ -168,6 +178,7 @@ namespace BansheeEngine
 		sphereData.pickable = mPickable;
 		sphereData.pickable = mPickable;
 
 
 		mDrawHelper->wireSphere(position, radius);
 		mDrawHelper->wireSphere(position, radius);
+		mIdxToSceneObjectMap[sphereData.idx] = mActiveSO;
 	}
 	}
 
 
 	void GizmoManager::drawLine(const Vector3& start, const Vector3& end)
 	void GizmoManager::drawLine(const Vector3& start, const Vector3& end)
@@ -175,6 +186,7 @@ namespace BansheeEngine
 		mLineData.push_back(LineData());
 		mLineData.push_back(LineData());
 		LineData& lineData = mLineData.back();
 		LineData& lineData = mLineData.back();
 
 
+		lineData.idx = mCurrentIdx++;
 		lineData.start = start;
 		lineData.start = start;
 		lineData.end = end;
 		lineData.end = end;
 		lineData.color = mColor;
 		lineData.color = mColor;
@@ -183,6 +195,7 @@ namespace BansheeEngine
 		lineData.pickable = mPickable;
 		lineData.pickable = mPickable;
 
 
 		mDrawHelper->line(start, end);
 		mDrawHelper->line(start, end);
+		mIdxToSceneObjectMap[lineData.idx] = mActiveSO;
 	}
 	}
 
 
 	void GizmoManager::drawFrustum(const Vector3& position, float aspect, Degree FOV, float near, float far)
 	void GizmoManager::drawFrustum(const Vector3& position, float aspect, Degree FOV, float near, float far)
@@ -190,6 +203,7 @@ namespace BansheeEngine
 		mFrustumData.push_back(FrustumData());
 		mFrustumData.push_back(FrustumData());
 		FrustumData& frustumData = mFrustumData.back();
 		FrustumData& frustumData = mFrustumData.back();
 
 
+		frustumData.idx = mCurrentIdx++;
 		frustumData.position = position;
 		frustumData.position = position;
 		frustumData.aspect = aspect;
 		frustumData.aspect = aspect;
 		frustumData.FOV = FOV;
 		frustumData.FOV = FOV;
@@ -201,6 +215,7 @@ namespace BansheeEngine
 		frustumData.pickable = mPickable;
 		frustumData.pickable = mPickable;
 
 
 		mDrawHelper->frustum(position, aspect, FOV, near, far);
 		mDrawHelper->frustum(position, aspect, FOV, near, far);
+		mIdxToSceneObjectMap[frustumData.idx] = mActiveSO;
 	}
 	}
 
 
 	void GizmoManager::drawIcon(Vector3 position, HSpriteTexture image, bool fixedScale)
 	void GizmoManager::drawIcon(Vector3 position, HSpriteTexture image, bool fixedScale)
@@ -208,6 +223,7 @@ namespace BansheeEngine
 		mIconData.push_back(IconData());
 		mIconData.push_back(IconData());
 		IconData& iconData = mIconData.back();
 		IconData& iconData = mIconData.back();
 
 
+		iconData.idx = mCurrentIdx++;
 		iconData.position = position;
 		iconData.position = position;
 		iconData.texture = image;
 		iconData.texture = image;
 		iconData.fixedScale = fixedScale;
 		iconData.fixedScale = fixedScale;
@@ -215,6 +231,8 @@ namespace BansheeEngine
 		iconData.transform = mTransform;
 		iconData.transform = mTransform;
 		iconData.sceneObject = mActiveSO;
 		iconData.sceneObject = mActiveSO;
 		iconData.pickable = mPickable;
 		iconData.pickable = mPickable;
+
+		mIdxToSceneObjectMap[iconData.idx] = mActiveSO;
 	}
 	}
 
 
 	void GizmoManager::update()
 	void GizmoManager::update()
@@ -257,8 +275,6 @@ namespace BansheeEngine
 			IconRenderDataVecPtr iconRenderData = bs_shared_ptr<IconRenderDataVec>();
 			IconRenderDataVecPtr iconRenderData = bs_shared_ptr<IconRenderDataVec>();
 			gCoreAccessor().queueCommand(std::bind(&GizmoManagerCore::updateData, mCore, nullptr, nullptr, nullptr, nullptr, iconRenderData));
 			gCoreAccessor().queueCommand(std::bind(&GizmoManagerCore::updateData, mCore, nullptr, nullptr, nullptr, nullptr, iconRenderData));
 		}
 		}
-
-		clearGizmos();
 	}
 	}
 
 
 	void GizmoManager::renderForPicking(const HCamera& camera, std::function<Color(UINT32)> idxToColorCallback)
 	void GizmoManager::renderForPicking(const HCamera& camera, std::function<Color(UINT32)> idxToColorCallback)
@@ -268,13 +284,12 @@ namespace BansheeEngine
 
 
 		mPickingDrawHelper->clear();
 		mPickingDrawHelper->clear();
 
 
-		UINT32 gizmoIdx = 0; // TODO - Since I need to be able to quickly access gizmo data per ID i'll probably want to assign this when they're initially added and used an unordered map
 		for (auto& cubeDataEntry : mSolidCubeData)
 		for (auto& cubeDataEntry : mSolidCubeData)
 		{
 		{
 			if (!cubeDataEntry.pickable)
 			if (!cubeDataEntry.pickable)
 				continue;
 				continue;
 
 
-			mPickingDrawHelper->setColor(idxToColorCallback(gizmoIdx++));
+			mPickingDrawHelper->setColor(idxToColorCallback(cubeDataEntry.idx));
 			mPickingDrawHelper->setTransform(cubeDataEntry.transform);
 			mPickingDrawHelper->setTransform(cubeDataEntry.transform);
 
 
 			mPickingDrawHelper->cube(cubeDataEntry.position, cubeDataEntry.extents);
 			mPickingDrawHelper->cube(cubeDataEntry.position, cubeDataEntry.extents);
@@ -285,7 +300,7 @@ namespace BansheeEngine
 			if (!cubeDataEntry.pickable)
 			if (!cubeDataEntry.pickable)
 				continue;
 				continue;
 
 
-			mPickingDrawHelper->setColor(idxToColorCallback(gizmoIdx++));
+			mPickingDrawHelper->setColor(idxToColorCallback(cubeDataEntry.idx));
 			mPickingDrawHelper->setTransform(cubeDataEntry.transform);
 			mPickingDrawHelper->setTransform(cubeDataEntry.transform);
 
 
 			mPickingDrawHelper->wireCube(cubeDataEntry.position, cubeDataEntry.extents);
 			mPickingDrawHelper->wireCube(cubeDataEntry.position, cubeDataEntry.extents);
@@ -296,7 +311,7 @@ namespace BansheeEngine
 			if (!sphereDataEntry.pickable)
 			if (!sphereDataEntry.pickable)
 				continue;
 				continue;
 
 
-			mPickingDrawHelper->setColor(idxToColorCallback(gizmoIdx++));
+			mPickingDrawHelper->setColor(idxToColorCallback(sphereDataEntry.idx));
 			mPickingDrawHelper->setTransform(sphereDataEntry.transform);
 			mPickingDrawHelper->setTransform(sphereDataEntry.transform);
 
 
 			mPickingDrawHelper->sphere(sphereDataEntry.position, sphereDataEntry.radius);
 			mPickingDrawHelper->sphere(sphereDataEntry.position, sphereDataEntry.radius);
@@ -307,7 +322,7 @@ namespace BansheeEngine
 			if (!sphereDataEntry.pickable)
 			if (!sphereDataEntry.pickable)
 				continue;
 				continue;
 
 
-			mPickingDrawHelper->setColor(idxToColorCallback(gizmoIdx++));
+			mPickingDrawHelper->setColor(idxToColorCallback(sphereDataEntry.idx));
 			mPickingDrawHelper->setTransform(sphereDataEntry.transform);
 			mPickingDrawHelper->setTransform(sphereDataEntry.transform);
 
 
 			mPickingDrawHelper->wireSphere(sphereDataEntry.position, sphereDataEntry.radius);
 			mPickingDrawHelper->wireSphere(sphereDataEntry.position, sphereDataEntry.radius);
@@ -318,7 +333,7 @@ namespace BansheeEngine
 			if (!lineDataEntry.pickable)
 			if (!lineDataEntry.pickable)
 				continue;
 				continue;
 
 
-			mPickingDrawHelper->setColor(idxToColorCallback(gizmoIdx++));
+			mPickingDrawHelper->setColor(idxToColorCallback(lineDataEntry.idx));
 			mPickingDrawHelper->setTransform(lineDataEntry.transform);
 			mPickingDrawHelper->setTransform(lineDataEntry.transform);
 
 
 			mPickingDrawHelper->line(lineDataEntry.start, lineDataEntry.end);
 			mPickingDrawHelper->line(lineDataEntry.start, lineDataEntry.end);
@@ -329,7 +344,7 @@ namespace BansheeEngine
 			if (!frustumDataEntry.pickable)
 			if (!frustumDataEntry.pickable)
 				continue;
 				continue;
 
 
-			mPickingDrawHelper->setColor(idxToColorCallback(gizmoIdx++));
+			mPickingDrawHelper->setColor(idxToColorCallback(frustumDataEntry.idx));
 			mPickingDrawHelper->setTransform(frustumDataEntry.transform);
 			mPickingDrawHelper->setTransform(frustumDataEntry.transform);
 
 
 			mPickingDrawHelper->frustum(frustumDataEntry.position, frustumDataEntry.aspect, frustumDataEntry.FOV, 
 			mPickingDrawHelper->frustum(frustumDataEntry.position, frustumDataEntry.aspect, frustumDataEntry.FOV, 
@@ -342,7 +357,7 @@ namespace BansheeEngine
 				continue;
 				continue;
 
 
 			iconData.push_back(iconDataEntry);
 			iconData.push_back(iconDataEntry);
-			iconData.back().color = idxToColorCallback(gizmoIdx++);
+			iconData.back().color = idxToColorCallback(iconDataEntry.idx);
 		}
 		}
 
 
 		TransientMeshPtr solidMesh = mPickingDrawHelper->buildSolidMesh();
 		TransientMeshPtr solidMesh = mPickingDrawHelper->buildSolidMesh();
@@ -351,19 +366,19 @@ namespace BansheeEngine
 
 
 		// Note: This must be rendered while Scene view is being rendered
 		// Note: This must be rendered while Scene view is being rendered
 		Matrix4 viewMat = camera->getViewMatrix();
 		Matrix4 viewMat = camera->getViewMatrix();
-		Matrix4 projMat = camera->getProjectionMatrix();
+		Matrix4 projMat = camera->getProjectionMatrixRS();
 		ViewportPtr viewport = camera->getViewport();
 		ViewportPtr viewport = camera->getViewport();
 
 
-		gCoreAccessor().queueCommand(std::bind(&GizmoManagerCore::renderGizmosForPicking,
-			mCore, viewMat, projMat, solidMesh->_createProxy(0)));
+		gCoreAccessor().queueCommand(std::bind(&GizmoManagerCore::renderGizmos,
+			mCore, viewMat, projMat, solidMesh->_createProxy(0), GizmoMaterial::Picking));
 
 
-		gCoreAccessor().queueCommand(std::bind(&GizmoManagerCore::renderGizmosForPicking,
-			mCore, viewMat, projMat, wireMesh->_createProxy(0)));
+		gCoreAccessor().queueCommand(std::bind(&GizmoManagerCore::renderGizmos,
+			mCore, viewMat, projMat, wireMesh->_createProxy(0), GizmoMaterial::Picking));
 
 
 		Rect2I screenArea = camera->getViewport()->getArea();
 		Rect2I screenArea = camera->getViewport()->getArea();
 
 
-		gCoreAccessor().queueCommand(std::bind(&GizmoManagerCore::renderIconGizmosForPicking,
-			mCore, screenArea, iconMesh->_createProxy(0), iconRenderData));
+		gCoreAccessor().queueCommand(std::bind(&GizmoManagerCore::renderIconGizmos,
+			mCore, screenArea, iconMesh->_createProxy(0), iconRenderData, true));
 
 
 		mPickingDrawHelper->releaseSolidMesh(solidMesh);
 		mPickingDrawHelper->releaseSolidMesh(solidMesh);
 		mPickingDrawHelper->releaseWireMesh(wireMesh);
 		mPickingDrawHelper->releaseWireMesh(wireMesh);
@@ -379,12 +394,15 @@ namespace BansheeEngine
 		mLineData.clear();
 		mLineData.clear();
 		mFrustumData.clear();
 		mFrustumData.clear();
 		mIconData.clear();
 		mIconData.clear();
+		mIdxToSceneObjectMap.clear();
 
 
 		mDrawHelper->clear();
 		mDrawHelper->clear();
+
+		mCurrentIdx = 0;
 	}
 	}
 
 
 	TransientMeshPtr GizmoManager::buildIconMesh(const HCamera& camera, const Vector<IconData>& iconData, 
 	TransientMeshPtr GizmoManager::buildIconMesh(const HCamera& camera, const Vector<IconData>& iconData, 
-		bool pickingOnly, GizmoManager::IconRenderDataVecPtr& iconRenderData)
+		bool forPicking, GizmoManager::IconRenderDataVecPtr& iconRenderData)
 	{
 	{
 		mSortedIconData.clear();
 		mSortedIconData.clear();
 		
 		
@@ -392,9 +410,9 @@ namespace BansheeEngine
 			mSortedIconData.resize(iconData.size());
 			mSortedIconData.resize(iconData.size());
 
 
 		UINT32 i = 0;
 		UINT32 i = 0;
-		for (auto& iconData : mIconData)
+		for (auto& iconEntry : iconData)
 		{
 		{
-			Vector3 viewPoint = camera->worldToViewPoint(iconData.position);
+			Vector3 viewPoint = camera->worldToViewPoint(iconEntry.position);
 
 
 			float distance = -viewPoint.z;
 			float distance = -viewPoint.z;
 			if (distance < camera->getNearClipDistance()) // Ignore behind clip plane
 			if (distance < camera->getNearClipDistance()) // Ignore behind clip plane
@@ -403,10 +421,10 @@ namespace BansheeEngine
 			if (distance > MAX_ICON_RANGE) // Ignore too far away
 			if (distance > MAX_ICON_RANGE) // Ignore too far away
 				continue;
 				continue;
 
 
-			if (!iconData.texture) // Ignore missing texture
+			if (!iconEntry.texture) // Ignore missing texture
 				continue;
 				continue;
 
 
-			if (pickingOnly && !iconData.pickable)
+			if (forPicking && !iconEntry.pickable)
 				continue;
 				continue;
 
 
 			SortedIconData& sortedIconData = mSortedIconData[i];
 			SortedIconData& sortedIconData = mSortedIconData[i];
@@ -490,7 +508,7 @@ namespace BansheeEngine
 
 
 			Vector3 position((float)sortedIconData.screenPosition.x, (float)sortedIconData.screenPosition.y, -sortedIconData.distance);
 			Vector3 position((float)sortedIconData.screenPosition.x, (float)sortedIconData.screenPosition.y, -sortedIconData.distance);
 			Vector3 projPosition = camera->projectPoint(position);
 			Vector3 projPosition = camera->projectPoint(position);
-			position.z = -projPosition.z;
+			position.z = projPosition.z;
 
 
 			float halfWidth = iconWidth * 0.5f;
 			float halfWidth = iconWidth * 0.5f;
 			float halfHeight = iconHeight * 0.5f;
 			float halfHeight = iconHeight * 0.5f;
@@ -510,6 +528,9 @@ namespace BansheeEngine
 			Color normalColor, fadedColor;
 			Color normalColor, fadedColor;
 			calculateIconColors(curIconData.color, *camera.get(), (UINT32)(halfHeight * 2.0f), curIconData.fixedScale, normalColor, fadedColor);
 			calculateIconColors(curIconData.color, *camera.get(), (UINT32)(halfHeight * 2.0f), curIconData.fixedScale, normalColor, fadedColor);
 
 
+			if (forPicking)
+				normalColor = curIconData.color;
+
 			Vector3 positions[4];
 			Vector3 positions[4];
 			positions[0] = position + Vector3(-halfWidth, -halfHeight, 0.0f);
 			positions[0] = position + Vector3(-halfWidth, -halfHeight, 0.0f);
 			positions[1] = position + Vector3(halfWidth, -halfHeight, 0.0f);
 			positions[1] = position + Vector3(halfWidth, -halfHeight, 0.0f);
@@ -584,6 +605,16 @@ namespace BansheeEngine
 		fadedColor.a *= 0.2f;
 		fadedColor.a *= 0.2f;
 	}
 	}
 
 
+	HSceneObject GizmoManager::getSceneObject(UINT32 gizmoIdx)
+	{
+		auto iterFind = mIdxToSceneObjectMap.find(gizmoIdx);
+
+		if (iterFind != mIdxToSceneObjectMap.end())
+			return iterFind->second;
+
+		return HSceneObject();
+	}
+
 	const float GizmoManagerCore::PICKING_ALPHA_CUTOFF = 0.5f;
 	const float GizmoManagerCore::PICKING_ALPHA_CUTOFF = 0.5f;
 
 
 	GizmoManagerCore::GizmoManagerCore(const PrivatelyConstuct& dummy)
 	GizmoManagerCore::GizmoManagerCore(const PrivatelyConstuct& dummy)
@@ -682,40 +713,41 @@ namespace BansheeEngine
 		screenArea.height = (int)(normArea.height * height);
 		screenArea.height = (int)(normArea.height * height);
 
 
 		if (mSolidMeshProxy != nullptr)
 		if (mSolidMeshProxy != nullptr)
-			renderSolidGizmos(camera.viewMatrix, camera.projMatrix, mSolidMeshProxy);
+			renderGizmos(camera.viewMatrix, camera.projMatrix, mSolidMeshProxy, GizmoManager::GizmoMaterial::Solid);
 
 
 		if (mWireMeshProxy != nullptr)
 		if (mWireMeshProxy != nullptr)
-			renderWireGizmos(camera.viewMatrix, camera.projMatrix, mWireMeshProxy);
+			renderGizmos(camera.viewMatrix, camera.projMatrix, mWireMeshProxy, GizmoManager::GizmoMaterial::Wire);
 
 
 		if (mIconMeshProxy != nullptr)
 		if (mIconMeshProxy != nullptr)
-			renderIconGizmos(screenArea, mIconMeshProxy, mIconRenderData);
+			renderIconGizmos(screenArea, mIconMeshProxy, mIconRenderData, false);
 	}
 	}
 
 
-	void GizmoManagerCore::renderSolidGizmos(Matrix4 viewMatrix, Matrix4 projMatrix, MeshProxyPtr meshProxy)
+	void GizmoManagerCore::renderGizmos(Matrix4 viewMatrix, Matrix4 projMatrix, MeshProxyPtr meshProxy, GizmoManager::GizmoMaterial material)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
 		Matrix4 viewProjMat = projMatrix * viewMatrix;
 		Matrix4 viewProjMat = projMatrix * viewMatrix;
 
 
-		mSolidMaterial.mViewProj.set(viewProjMat);
-
-		Renderer::setPass(*mSolidMaterial.proxy, 0);
-		Renderer::draw(*meshProxy);
-	}
-
-	void GizmoManagerCore::renderWireGizmos(Matrix4 viewMatrix, Matrix4 projMatrix, MeshProxyPtr meshProxy)
-	{
-		THROW_IF_NOT_CORE_THREAD;
-
-		Matrix4 viewProjMat = projMatrix * viewMatrix;
-
-		mWireMaterial.mViewProj.set(viewProjMat);
-
-		Renderer::setPass(*mWireMaterial.proxy, 0);
+		switch (material)
+		{
+		case GizmoManager::GizmoMaterial::Solid:
+			mSolidMaterial.mViewProj.set(viewProjMat);
+			Renderer::setPass(*mSolidMaterial.proxy, 0);
+			break;
+		case GizmoManager::GizmoMaterial::Wire:
+			mWireMaterial.mViewProj.set(viewProjMat);
+			Renderer::setPass(*mWireMaterial.proxy, 0);
+			break;
+		case GizmoManager::GizmoMaterial::Picking:
+			mPickingMaterial.mViewProj.set(viewProjMat);
+			Renderer::setPass(*mPickingMaterial.proxy, 0);
+			break;
+		}
+		
 		Renderer::draw(*meshProxy);
 		Renderer::draw(*meshProxy);
 	}
 	}
 
 
-	void GizmoManagerCore::renderIconGizmos(Rect2I screenArea, MeshProxyPtr meshProxy, GizmoManager::IconRenderDataVecPtr renderData)
+	void GizmoManagerCore::renderIconGizmos(Rect2I screenArea, MeshProxyPtr meshProxy, GizmoManager::IconRenderDataVecPtr renderData, bool usePickingMaterial)
 	{
 	{
 		RenderSystem& rs = RenderSystem::instance();
 		RenderSystem& rs = RenderSystem::instance();
 		MeshBasePtr mesh;
 		MeshBasePtr mesh;
@@ -749,89 +781,44 @@ namespace BansheeEngine
 		float near = rs.getMinimumDepthInputValue();
 		float near = rs.getMinimumDepthInputValue();
 		float far = rs.getMaximumDepthInputValue();
 		float far = rs.getMaximumDepthInputValue();
 
 
-		projMat.makeProjectionOrtho(left, right, top, bottom, near, far);
-		mIconMaterial.mViewProj[0].set(projMat);
-		mIconMaterial.mViewProj[1].set(projMat);
+		projMat.makeProjectionOrtho(left, right, top, bottom, -near, -far); // Minus near/far because Z is flipped for normalized device coords
 
 
-		for (UINT32 passIdx = 0; passIdx < 2; passIdx++)
+		if (!usePickingMaterial)
 		{
 		{
-			Renderer::setPass(*mIconMaterial.proxy, passIdx);
+			mIconMaterial.mViewProj[0].set(projMat);
+			mIconMaterial.mViewProj[1].set(projMat);
 
 
-			UINT32 curIndexOffset = 0;
-			for (auto curRenderData : *renderData)
+			for (UINT32 passIdx = 0; passIdx < 2; passIdx++)
 			{
 			{
-				mIconMaterial.mTexture[passIdx].set(curRenderData.texture);
-				rs.bindGpuParams(GPT_FRAGMENT_PROGRAM, mIconMaterial.mFragParams[passIdx]);
+				Renderer::setPass(*mIconMaterial.proxy, passIdx);
 
 
-				rs.drawIndexed(curIndexOffset, curRenderData.count * 6, 0, curRenderData.count * 4);
-				curIndexOffset += curRenderData.count * 6;
+				UINT32 curIndexOffset = 0;
+				for (auto curRenderData : *renderData)
+				{
+					mIconMaterial.mTexture[passIdx].set(curRenderData.texture);
+					rs.bindGpuParams(GPT_FRAGMENT_PROGRAM, mIconMaterial.mFragParams[passIdx]);
 
 
+					rs.drawIndexed(curIndexOffset, curRenderData.count * 6, 0, curRenderData.count * 4);
+					curIndexOffset += curRenderData.count * 6;
+				}
 			}
 			}
 		}
 		}
-
-		mesh->_notifyUsedOnGPU();
-	}
-
-	void GizmoManagerCore::renderGizmosForPicking(Matrix4 viewMatrix, Matrix4 projMatrix, MeshProxyPtr meshProxy)
-	{
-		THROW_IF_NOT_CORE_THREAD;
-
-		Matrix4 viewProjMat = projMatrix * viewMatrix;
-
-		mSolidMaterial.mViewProj.set(viewProjMat);
-
-		Renderer::setPass(*mPickingMaterial.proxy, 0);
-		Renderer::draw(*meshProxy);
-	}
-
-	void GizmoManagerCore::renderIconGizmosForPicking(Rect2I screenArea, MeshProxyPtr meshProxy, GizmoManager::IconRenderDataVecPtr renderData)
-	{
-		RenderSystem& rs = RenderSystem::instance();
-		MeshBasePtr mesh;
-
-		// TODO: Instead of this lock consider just storing all needed data in MeshProxy and not referencing Mesh at all?
-		if (!meshProxy->mesh.expired())
-			mesh = meshProxy->mesh.lock();
 		else
 		else
-			return;
-
-		std::shared_ptr<VertexData> vertexData = mesh->_getVertexData();
-
-		rs.setVertexDeclaration(vertexData->vertexDeclaration);
-		auto vertexBuffers = vertexData->getBuffers();
-
-		VertexBufferPtr vertBuffers[1] = { vertexBuffers.begin()->second };
-		rs.setVertexBuffers(0, vertBuffers, 1);
-
-		IndexBufferPtr indexBuffer = mesh->_getIndexBuffer();
-		rs.setIndexBuffer(indexBuffer);
-
-		rs.setDrawOperation(DOT_TRIANGLE_LIST);
-
-		// Set up ortho matrix
-		Matrix4 projMat;
-
-		float left = screenArea.x + rs.getHorizontalTexelOffset();
-		float right = screenArea.x + screenArea.width + rs.getHorizontalTexelOffset();
-		float top = screenArea.y + rs.getVerticalTexelOffset();
-		float bottom = screenArea.y + screenArea.height + rs.getVerticalTexelOffset();
-		float near = rs.getMinimumDepthInputValue();
-		float far = rs.getMaximumDepthInputValue();
-
-		projMat.makeProjectionOrtho(left, right, top, bottom, near, far);
-		mAlphaPickingMaterial.mViewProj.set(projMat);
+		{
+			mAlphaPickingMaterial.mViewProj.set(projMat);
 
 
-		Renderer::setPass(*mAlphaPickingMaterial.proxy, 0);
+			Renderer::setPass(*mAlphaPickingMaterial.proxy, 0);
 
 
-		UINT32 curIndexOffset = 0;
-		for (auto curRenderData : *renderData)
-		{
-			mAlphaPickingMaterial.mTexture.set(curRenderData.texture);
-			rs.bindGpuParams(GPT_FRAGMENT_PROGRAM, mAlphaPickingMaterial.mFragParams);
+			UINT32 curIndexOffset = 0;
+			for (auto curRenderData : *renderData)
+			{
+				mAlphaPickingMaterial.mTexture.set(curRenderData.texture);
+				rs.bindGpuParams(GPT_FRAGMENT_PROGRAM, mAlphaPickingMaterial.mFragParams);
 
 
-			rs.drawIndexed(curIndexOffset, curRenderData.count * 6, 0, curRenderData.count * 4);
-			curIndexOffset += curRenderData.count * 6;
+				rs.drawIndexed(curIndexOffset, curRenderData.count * 6, 0, curRenderData.count * 4);
+				curIndexOffset += curRenderData.count * 6;
 
 
+			}
 		}
 		}
 
 
 		mesh->_notifyUsedOnGPU();
 		mesh->_notifyUsedOnGPU();

+ 6 - 2
BansheeEditor/Source/BsHandleSliderManager.cpp

@@ -53,7 +53,9 @@ namespace BansheeEngine
 
 
 				if (mHoverSlider != overSlider)
 				if (mHoverSlider != overSlider)
 				{
 				{
-					mHoverSlider->setInactive();
+					if (mHoverSlider != nullptr)
+						mHoverSlider->setInactive();
+
 					mHoverSlider = overSlider;
 					mHoverSlider = overSlider;
 					overSlider->setHover();
 					overSlider->setHover();
 				}
 				}
@@ -68,7 +70,9 @@ namespace BansheeEngine
 
 
 				if (mActiveSlider != overSlider)
 				if (mActiveSlider != overSlider)
 				{
 				{
-					mActiveSlider->setInactive();
+					if (mActiveSlider != nullptr)
+						mActiveSlider->setInactive();
+
 					mActiveSlider = overSlider;
 					mActiveSlider = overSlider;
 					overSlider->setActive(inputPos);
 					overSlider->setActive(inputPos);
 				}
 				}

+ 1 - 1
BansheeEditor/Source/BsSceneEditorWidget.cpp

@@ -154,7 +154,7 @@ namespace BansheeEngine
 		{
 		{
 			// TODO - Handle multi-selection (i.e. selection rectangle when dragging)
 			// TODO - Handle multi-selection (i.e. selection rectangle when dragging)
 			// TODO - Handle selecting gizmos (will likely require slight refactor of ScenePicking)
 			// TODO - Handle selecting gizmos (will likely require slight refactor of ScenePicking)
-			HSceneObject pickedObject = ScenePicking::instance().pickClosestSceneObject(mCamera, scenePos, Vector2I(1, 1));
+			HSceneObject pickedObject = ScenePicking::instance().pickClosestObject(mCamera, scenePos, Vector2I(1, 1));
 
 
 			if (pickedObject)
 			if (pickedObject)
 			{
 			{

+ 1 - 1
BansheeEditor/Source/BsSceneGrid.cpp

@@ -66,7 +66,7 @@ namespace BansheeEngine
 		MaterialPtr mat = mGridMaterial.getInternalPtr();
 		MaterialPtr mat = mGridMaterial.getInternalPtr();
 		MeshPtr mesh = mGridMesh.getInternalPtr();
 		MeshPtr mesh = mGridMesh.getInternalPtr();
 
 
-		Matrix4 projMatrix = camera->getProjectionMatrix();
+		Matrix4 projMatrix = camera->getProjectionMatrixRS();
 		Matrix4 viewMatrix = camera->getViewMatrix();
 		Matrix4 viewMatrix = camera->getViewMatrix();
 
 
 		Matrix4 viewProjMatrix = projMatrix * viewMatrix;
 		Matrix4 viewProjMatrix = projMatrix * viewMatrix;

+ 55 - 58
BansheeEditor/Source/BsScenePicking.cpp

@@ -22,6 +22,7 @@
 #include "BsBuiltinEditorResources.h"
 #include "BsBuiltinEditorResources.h"
 #include "BsShader.h"
 #include "BsShader.h"
 #include "BsRenderer.h"
 #include "BsRenderer.h"
+#include "BsGizmoManager.h"
 
 
 using namespace std::placeholders;
 using namespace std::placeholders;
 
 
@@ -78,41 +79,16 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	HSceneObject ScenePicking::pickClosestSceneObject(const HCamera& cam, const Vector2I& position, const Vector2I& area)
+	HSceneObject ScenePicking::pickClosestObject(const HCamera& cam, const Vector2I& position, const Vector2I& area)
 	{
 	{
-		Vector<PickResult> selectedObjects = pickObjects(cam, position, area);
-		for (auto& object : selectedObjects)
-		{
-			if (object.type == PickResult::Type::SceneObject)
-				return object.sceneObject;
-		}
-
-		return HSceneObject();
-	}
-
-	PickResult ScenePicking::pickClosestObject(const HCamera& cam, const Vector2I& position, const Vector2I& area)
-	{
-		Vector<PickResult> selectedObjects = pickObjects(cam, position, area);
+		Vector<HSceneObject> selectedObjects = pickObjects(cam, position, area);
 		if (selectedObjects.size() == 0)
 		if (selectedObjects.size() == 0)
-			return { HSceneObject(), 0, PickResult::Type::None };
+			return HSceneObject();
 
 
 		return selectedObjects[0];
 		return selectedObjects[0];
 	}
 	}
 
 
-	Vector<HSceneObject> ScenePicking::pickSceneObjects(const HCamera& cam, const Vector2I& position, const Vector2I& area)
-	{
-		Vector<HSceneObject> results;
-		Vector<PickResult> selectedObjects = pickObjects(cam, position, area);
-		for (auto& object : selectedObjects)
-		{
-			if (object.type == PickResult::Type::SceneObject)
-				results.push_back(object.sceneObject);
-		}
-
-		return results;
-	}
-
-	Vector<PickResult> ScenePicking::pickObjects(const HCamera& cam, const Vector2I& position, const Vector2I& area)
+	Vector<HSceneObject> ScenePicking::pickObjects(const HCamera& cam, const Vector2I& position, const Vector2I& area)
 	{
 	{
 		auto comparePickElement = [&] (const ScenePicking::RenderablePickData& a, const ScenePicking::RenderablePickData& b)
 		auto comparePickElement = [&] (const ScenePicking::RenderablePickData& a, const ScenePicking::RenderablePickData& b)
 		{
 		{
@@ -128,7 +104,7 @@ namespace BansheeEngine
 				return (UINT32)a.alpha > (UINT32)b.alpha;
 				return (UINT32)a.alpha > (UINT32)b.alpha;
 		};
 		};
 
 
-		Matrix4 viewProjMatrix = cam->getProjectionMatrix() * cam->getViewMatrix();
+		Matrix4 viewProjMatrix = cam->getProjectionMatrixRS() * cam->getViewMatrix();
 
 
 		const Vector<HRenderable>& renderables = SceneManager::instance().getAllRenderables();
 		const Vector<HRenderable>& renderables = SceneManager::instance().getAllRenderables();
 		RenderableSet pickData(comparePickElement);
 		RenderableSet pickData(comparePickElement);
@@ -210,50 +186,49 @@ namespace BansheeEngine
 			}
 			}
 		}
 		}
 
 
+		UINT32 firstGizmoIdx = (UINT32)pickData.size();
+
 		Viewport vp = cam->getViewport()->clone();
 		Viewport vp = cam->getViewport()->clone();
-		AsyncOp op = gCoreAccessor().queueReturnCommand(std::bind(&ScenePicking::corePickObjects, this, vp, std::cref(pickData), position, area, _1));
+		gCoreAccessor().queueCommand(std::bind(&ScenePicking::corePickingBegin, this, vp, std::cref(pickData), position, area));
+
+		GizmoManager::instance().renderForPicking(cam, [&](UINT32 inputIdx) { return encodeIndex(firstGizmoIdx + inputIdx); });
+
+		AsyncOp op = gCoreAccessor().queueReturnCommand(std::bind(&ScenePicking::corePickingEnd, this, vp, position, area, _1));
 		gCoreAccessor().submitToCoreThread(true);
 		gCoreAccessor().submitToCoreThread(true);
 
 
 		assert(op.hasCompleted());
 		assert(op.hasCompleted());
 
 
 		Vector<UINT32>& selectedObjects = op.getReturnValue<Vector<UINT32>>();
 		Vector<UINT32>& selectedObjects = op.getReturnValue<Vector<UINT32>>();
-		Vector<PickResult> results;
+		Vector<HSceneObject> results;
 
 
-		for (auto& selectedObject : selectedObjects)
+		for (auto& selectedObjectIdx : selectedObjects)
 		{
 		{
-			auto iterFind = idxToRenderable.find(selectedObject);
+			if (selectedObjectIdx < firstGizmoIdx)
+			{
+				auto iterFind = idxToRenderable.find(selectedObjectIdx);
+
+				if (iterFind != idxToRenderable.end())
+					results.push_back(iterFind->second->SO());
+			}
+			else
+			{
+				UINT32 gizmoIdx = selectedObjectIdx - firstGizmoIdx;
 
 
-			if (iterFind != idxToRenderable.end())
-				results.push_back({ iterFind->second->SO(), 0, PickResult::Type::SceneObject });
+				HSceneObject so = GizmoManager::instance().getSceneObject(gizmoIdx);
+				if (so)
+					results.push_back(so);
+			}
 		}
 		}
 
 
 		return results;
 		return results;
 	}
 	}
 
 
-	void ScenePicking::corePickObjects(const Viewport& vp, const RenderableSet& renderables, const Vector2I& position,
-		const Vector2I& area, AsyncOp& asyncOp)
+	void ScenePicking::corePickingBegin(const Viewport& viewport, const RenderableSet& renderables, const Vector2I& position, const Vector2I& area)
 	{
 	{
 		RenderSystem& rs = RenderSystem::instance();
 		RenderSystem& rs = RenderSystem::instance();
 
 
-		RenderTargetPtr rt = vp.getTarget();
-		if (rt->getCore()->getProperties().isWindow())
-		{
-			// TODO: When I do implement this then I will likely want a method in RenderTarget that unifies both render window and render texture readback
-			BS_EXCEPT(NotImplementedException, "Picking is not supported on render windows as framebuffer readback methods aren't implemented");
-		}
-
-		RenderTexturePtr rtt = std::static_pointer_cast<RenderTexture>(rt);
-		TexturePtr outputTexture = rtt->getBindableColorTexture().getInternalPtr();
-
-		if (position.x < 0 || position.x >= (INT32)outputTexture->getWidth() || 
-			position.y < 0 || position.y >= (INT32)outputTexture->getHeight())
-		{
-			asyncOp._completeOperation(Vector<UINT32>());
-			return;
-		}
-
 		rs.beginFrame();
 		rs.beginFrame();
-		rs.setViewport(vp);
+		rs.setViewport(viewport);
 		rs.clearRenderTarget(FBT_COLOR | FBT_DEPTH | FBT_STENCIL, Color::White);
 		rs.clearRenderTarget(FBT_COLOR | FBT_DEPTH | FBT_STENCIL, Color::White);
 		rs.setScissorRect(position.x, position.y, position.x + area.x, position.y + area.y);
 		rs.setScissorRect(position.x, position.y, position.x + area.x, position.y + area.y);
 
 
@@ -273,7 +248,7 @@ namespace BansheeEngine
 				else
 				else
 					Renderer::setPass(*mMaterialData[(UINT32)activeMaterialCull].mMatPickingProxy, 0);
 					Renderer::setPass(*mMaterialData[(UINT32)activeMaterialCull].mMatPickingProxy, 0);
 			}
 			}
-			
+
 			Color color = encodeIndex(renderable.index);
 			Color color = encodeIndex(renderable.index);
 			MaterialData& md = mMaterialData[(UINT32)activeMaterialCull];
 			MaterialData& md = mMaterialData[(UINT32)activeMaterialCull];
 
 
@@ -297,12 +272,34 @@ namespace BansheeEngine
 
 
 			Renderer::draw(*renderable.mesh);
 			Renderer::draw(*renderable.mesh);
 		}
 		}
-		rs.endFrame();
+	}
+
+	void ScenePicking::corePickingEnd(const Viewport& vp, const Vector2I& position, const Vector2I& area, AsyncOp& asyncOp)
+	{
+		RenderTargetPtr rt = vp.getTarget();
+		if (rt->getCore()->getProperties().isWindow())
+		{
+			// TODO: When I do implement this then I will likely want a method in RenderTarget that unifies both render window and render texture readback
+			BS_EXCEPT(NotImplementedException, "Picking is not supported on render windows as framebuffer readback methods aren't implemented");
+		}
+
+		RenderTexturePtr rtt = std::static_pointer_cast<RenderTexture>(rt);
+		TexturePtr outputTexture = rtt->getBindableColorTexture().getInternalPtr();
+
+		if (position.x < 0 || position.x >= (INT32)outputTexture->getWidth() ||
+			position.y < 0 || position.y >= (INT32)outputTexture->getHeight())
+		{
+			asyncOp._completeOperation(Vector<UINT32>());
+			return;
+		}
 
 
 		PixelDataPtr outputPixelData = outputTexture->allocateSubresourceBuffer(0);
 		PixelDataPtr outputPixelData = outputTexture->allocateSubresourceBuffer(0);
 		GpuResourceDataPtr outputData = outputPixelData;
 		GpuResourceDataPtr outputData = outputPixelData;
 		AsyncOp unused;
 		AsyncOp unused;
 
 
+		RenderSystem& rs = RenderSystem::instance();
+
+		rs.endFrame();
 		rs.readSubresource(outputTexture, 0, outputData, unused);
 		rs.readSubresource(outputTexture, 0, outputData, unused);
 
 
 		Map<UINT32, UINT32> selectionScores;
 		Map<UINT32, UINT32> selectionScores;

+ 1 - 1
BansheeEditorExec/BsEditorExec.cpp

@@ -11,7 +11,7 @@ int CALLBACK WinMain(
 	_In_  int nCmdShow
 	_In_  int nCmdShow
 	)
 	)
 {
 {
-	EditorApplication::startUp(RenderSystemPlugin::OpenGL);
+	EditorApplication::startUp(RenderSystemPlugin::DX11);
 	EditorApplication::instance().runMainLoop();
 	EditorApplication::instance().runMainLoop();
 	EditorApplication::shutDown();
 	EditorApplication::shutDown();
 
 

+ 5 - 5
BansheeEngine/Source/BsCamera.cpp

@@ -578,9 +578,9 @@ namespace BansheeEngine
 	Vector3 Camera::projectPoint(const Vector3& point) const
 	Vector3 Camera::projectPoint(const Vector3& point) const
 	{
 	{
 		Vector4 projPoint4(point.x, point.y, point.z, 1.0f);
 		Vector4 projPoint4(point.x, point.y, point.z, 1.0f);
-		projPoint4 = getProjectionMatrix().multiply(projPoint4);
+		projPoint4 = getProjectionMatrixRS().multiply(projPoint4);
 
 
-		if (projPoint4.w > 1e-7f)
+		if (Math::abs(projPoint4.w) > 1e-7f)
 		{
 		{
 			float invW = 1.0f / projPoint4.w;
 			float invW = 1.0f / projPoint4.w;
 			projPoint4.x *= invW;
 			projPoint4.x *= invW;
@@ -600,14 +600,14 @@ namespace BansheeEngine
 	Vector3 Camera::unprojectPoint(const Vector3& point) const
 	Vector3 Camera::unprojectPoint(const Vector3& point) const
 	{
 	{
 		Vector4 dir4(point.x, point.y, 0.95f, 1.0f); // 0.95f arbitrary
 		Vector4 dir4(point.x, point.y, 0.95f, 1.0f); // 0.95f arbitrary
-		dir4 = getProjectionMatrix().inverse().multiply(dir4);
+		dir4 = getProjectionMatrixRS().inverse().multiply(dir4);
 
 
 		Vector3 dir;
 		Vector3 dir;
 		dir.x = dir4.x;
 		dir.x = dir4.x;
 		dir.y = dir4.y;
 		dir.y = dir4.y;
 		dir.z = dir4.z;
 		dir.z = dir4.z;
 
 
-		if (dir4.w > 1e-7f)
+		if (Math::abs(dir4.w) > 1e-7f)
 		{
 		{
 			float invW = 1.0f / dir4.w;
 			float invW = 1.0f / dir4.w;
 			dir.x *= invW;
 			dir.x *= invW;
@@ -641,7 +641,7 @@ namespace BansheeEngine
 		CameraProxyPtr proxy = bs_shared_ptr<CameraProxy>();
 		CameraProxyPtr proxy = bs_shared_ptr<CameraProxy>();
 		proxy->layer = mLayers;
 		proxy->layer = mLayers;
 		proxy->priority = mPriority;
 		proxy->priority = mPriority;
-		proxy->projMatrix = getProjectionMatrix();
+		proxy->projMatrix = getProjectionMatrixRS();
 		proxy->viewMatrix = getViewMatrix();
 		proxy->viewMatrix = getViewMatrix();
 		proxy->worldMatrix = SO()->getWorldTfrm();
 		proxy->worldMatrix = SO()->getWorldTfrm();
 		proxy->viewport = mViewport->clone();
 		proxy->viewport = mViewport->clone();

+ 9 - 8
BansheeEngine/Source/BsDrawHelper.cpp

@@ -156,8 +156,8 @@ namespace BansheeEngine
 		UINT32 numVertices, numIndices;
 		UINT32 numVertices, numIndices;
 		ShapeMeshes3D::getNumElementsCone(quality, numVertices, numIndices);
 		ShapeMeshes3D::getNumElementsCone(quality, numVertices, numIndices);
 
 
-		mTotalRequiredWireVertices += numVertices;
-		mTotalRequiredWireIndices += numIndices;
+		mTotalRequiredSolidVertices += numVertices;
+		mTotalRequiredSolidIndices += numIndices;
 	}
 	}
 
 
 	void DrawHelper::disc(const Vector3& position, const Vector3& normal, float radius, UINT32 quality)
 	void DrawHelper::disc(const Vector3& position, const Vector3& normal, float radius, UINT32 quality)
@@ -175,8 +175,8 @@ namespace BansheeEngine
 		UINT32 numVertices, numIndices;
 		UINT32 numVertices, numIndices;
 		ShapeMeshes3D::getNumElementsDisc(quality, numVertices, numIndices);
 		ShapeMeshes3D::getNumElementsDisc(quality, numVertices, numIndices);
 
 
-		mTotalRequiredWireVertices += numVertices;
-		mTotalRequiredWireIndices += numIndices;
+		mTotalRequiredSolidVertices += numVertices;
+		mTotalRequiredSolidIndices += numIndices;
 	}
 	}
 
 
 	void DrawHelper::wireDisc(const Vector3& position, const Vector3& normal, float radius, UINT32 quality)
 	void DrawHelper::wireDisc(const Vector3& position, const Vector3& normal, float radius, UINT32 quality)
@@ -216,8 +216,8 @@ namespace BansheeEngine
 		UINT32 numVertices, numIndices;
 		UINT32 numVertices, numIndices;
 		ShapeMeshes3D::getNumElementsArc(quality, numVertices, numIndices);
 		ShapeMeshes3D::getNumElementsArc(quality, numVertices, numIndices);
 
 
-		mTotalRequiredWireVertices += numVertices;
-		mTotalRequiredWireIndices += numIndices;
+		mTotalRequiredSolidVertices += numVertices;
+		mTotalRequiredSolidIndices += numIndices;
 	}
 	}
 
 
 	void DrawHelper::wireArc(const Vector3& position, const Vector3& normal, float radius, 
 	void DrawHelper::wireArc(const Vector3& position, const Vector3& normal, float radius, 
@@ -251,8 +251,8 @@ namespace BansheeEngine
 		rectData.color = mColor;
 		rectData.color = mColor;
 		rectData.transform = mTransform;
 		rectData.transform = mTransform;
 
 
-		mTotalRequiredWireVertices += 4;
-		mTotalRequiredWireIndices += 6;
+		mTotalRequiredSolidVertices += 4;
+		mTotalRequiredSolidIndices += 6;
 	}
 	}
 
 
 	void DrawHelper::clear()
 	void DrawHelper::clear()
@@ -269,6 +269,7 @@ namespace BansheeEngine
 		mWireDiscData.clear();
 		mWireDiscData.clear();
 		mArcData.clear();
 		mArcData.clear();
 		mWireArcData.clear();
 		mWireArcData.clear();
+		mConeData.clear();
 
 
 		mTotalRequiredSolidVertices = 0;
 		mTotalRequiredSolidVertices = 0;
 		mTotalRequiredSolidIndices = 0;
 		mTotalRequiredSolidIndices = 0;

+ 18 - 4
BansheeEngine/Source/BsShapeMeshes3D.cpp

@@ -289,7 +289,7 @@ namespace BansheeEngine
 	void ShapeMeshes3D::getNumElementsCone(UINT32 quality, UINT32& numVertices, UINT32& numIndices)
 	void ShapeMeshes3D::getNumElementsCone(UINT32 quality, UINT32& numVertices, UINT32& numIndices)
 	{
 	{
 		numVertices = ((quality + 1) * 4 + 1) * 2;
 		numVertices = ((quality + 1) * 4 + 1) * 2;
-		numIndices = ((quality + 1) * 4 - 1) * 6;
+		numIndices = ((quality + 1) * 4) * 6;
 	}
 	}
 
 
 	void ShapeMeshes3D::wireAABox(const AABox& box, UINT8* outVertices, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset)
 	void ShapeMeshes3D::wireAABox(const AABox& box, UINT8* outVertices, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset)
@@ -596,13 +596,20 @@ namespace BansheeEngine
 		}
 		}
 
 
 		UINT32 numTriangles = numArcVertices;
 		UINT32 numTriangles = numArcVertices;
-		for (UINT32 i = 0; i < numTriangles; i++)
+		for (UINT32 i = 0; i < numTriangles - 1; i++)
 		{
 		{
 			outIndices[i * 3 + 0] = vertexOffset + baseIdx;
 			outIndices[i * 3 + 0] = vertexOffset + baseIdx;
 			outIndices[i * 3 + 1] = vertexOffset + i;
 			outIndices[i * 3 + 1] = vertexOffset + i;
 			outIndices[i * 3 + 2] = vertexOffset + i + 1;
 			outIndices[i * 3 + 2] = vertexOffset + i + 1;
 		}
 		}
 
 
+		{
+			UINT32 i = numTriangles - 1;
+			outIndices[i * 3 + 0] = vertexOffset + baseIdx;
+			outIndices[i * 3 + 1] = vertexOffset + i;
+			outIndices[i * 3 + 2] = vertexOffset + 0;
+		}
+
 		// Generate cone
 		// Generate cone
 		generateArcVertices(base, normal, radius, Degree(0), Degree(360),
 		generateArcVertices(base, normal, radius, Degree(0), Degree(360),
 			numArcVertices + 1, outVertices, 0, vertexStride);
 			numArcVertices + 1, outVertices, 0, vertexStride);
@@ -629,16 +636,23 @@ namespace BansheeEngine
 
 
 		outVertices += numArcVertices * vertexStride;
 		outVertices += numArcVertices * vertexStride;
 		outVertices = writeVector3(outVertices, vertexStride, topVertex); // Write top vertex
 		outVertices = writeVector3(outVertices, vertexStride, topVertex); // Write top vertex
-		UINT32 topIdx = numArcVertices * 2 + 2;
+		UINT32 topIdx = numArcVertices;
 
 
 		outIndices += numTriangles * 3;
 		outIndices += numTriangles * 3;
 		UINT32 curVertOffset = vertexOffset + numArcVertices + 1;
 		UINT32 curVertOffset = vertexOffset + numArcVertices + 1;
-		for (UINT32 i = 0; i < numTriangles; i++)
+		for (UINT32 i = 0; i < numTriangles - 1; i++)
 		{
 		{
 			outIndices[i * 3 + 0] = curVertOffset + topIdx;
 			outIndices[i * 3 + 0] = curVertOffset + topIdx;
 			outIndices[i * 3 + 1] = curVertOffset + i;
 			outIndices[i * 3 + 1] = curVertOffset + i;
 			outIndices[i * 3 + 2] = curVertOffset + i + 1;
 			outIndices[i * 3 + 2] = curVertOffset + i + 1;
 		}
 		}
+
+		{
+			UINT32 i = numTriangles - 1;
+			outIndices[i * 3 + 0] = vertexOffset + topIdx;
+			outIndices[i * 3 + 1] = vertexOffset + i;
+			outIndices[i * 3 + 2] = vertexOffset + 0;
+		}
 	}
 	}
 
 
 	void ShapeMeshes3D::solidQuad(const Rect3& area, UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset)
 	void ShapeMeshes3D::solidQuad(const Rect3& area, UINT8* outVertices, UINT8* outNormals, UINT32 vertexOffset, UINT32 vertexStride, UINT32* outIndices, UINT32 indexOffset)

+ 1 - 2
BansheeGLRenderSystem/Include/BsGLRenderSystem.h

@@ -161,8 +161,7 @@ namespace BansheeEngine
 		/**
 		/**
 		 * @copydoc RenderSystem::convertProjectionMatrix()
 		 * @copydoc RenderSystem::convertProjectionMatrix()
 		 */
 		 */
-        void convertProjectionMatrix(const Matrix4& matrix,
-            Matrix4& dest, bool forGpuProgram = false);
+        void convertProjectionMatrix(const Matrix4& matrix, Matrix4& dest);
 
 
 		/************************************************************************/
 		/************************************************************************/
 		/* 				Internal use by OpenGL RenderSystem only                */
 		/* 				Internal use by OpenGL RenderSystem only                */

+ 1 - 1
BansheeGLRenderSystem/Source/BsGLRenderSystem.cpp

@@ -2087,7 +2087,7 @@ namespace BansheeEngine
 		return VET_COLOR_ABGR;
 		return VET_COLOR_ABGR;
 	}
 	}
 
 
-	void GLRenderSystem::convertProjectionMatrix(const Matrix4& matrix, Matrix4& dest, bool forGpuProgram)
+	void GLRenderSystem::convertProjectionMatrix(const Matrix4& matrix, Matrix4& dest)
 	{
 	{
 		dest = matrix;
 		dest = matrix;
 	}
 	}

+ 7 - 4
BansheeUtility/Include/BsAsyncOp.h

@@ -12,9 +12,10 @@ namespace BansheeEngine
 	 * 			
 	 * 			
 	 * @note	You are allowed (and meant to) to copy this by value.
 	 * @note	You are allowed (and meant to) to copy this by value.
 	 * 			
 	 * 			
-	 *			You'll notice mIsCompleted isn't locked. This is safe on x86 architectures because all stores
-	 *			are executed in order. Loads may be executed out of order from stores but worst case scenario is that
-	 *			mIsCompleted reports false a few cycles too late, which is not relevant for practical use.
+	 *			You'll notice mIsCompleted isn't synchronized. This is because we're okay if 
+	 *			mIsCompleted reports true a few cycles too late, which is not relevant for practical use.
+	 *			And in cases where you need to ensure operation has completed you will usually use some kind
+	 *			of synchronization primitive that includes a memory barrier anyway.
 	 */
 	 */
 	class BS_UTILITY_EXPORT AsyncOp
 	class BS_UTILITY_EXPORT AsyncOp
 	{
 	{
@@ -34,7 +35,9 @@ namespace BansheeEngine
 			:mData(bs_shared_ptr<AsyncOpData, ScratchAlloc>())
 			:mData(bs_shared_ptr<AsyncOpData, ScratchAlloc>())
 		{
 		{
 #if BS_ARCH_TYPE != BS_ARCHITECTURE_x86_32 && BS_ARCH_TYPE != BS_ARCHITECTURE_x86_64
 #if BS_ARCH_TYPE != BS_ARCHITECTURE_x86_32 && BS_ARCH_TYPE != BS_ARCHITECTURE_x86_64
-			static_assert(false, "You will likely need to add locks for mIsCompleted on architectures other than x86.");
+			// On some architectures it is not guaranteed that stores are executed in order, which means
+			// return value could be stored after mIsCompleted is set
+			static_assert(false, "You will likely need to add a memory barrier for mIsCompleted on architectures other than x86.");
 #endif
 #endif
 		}
 		}
 
 

+ 1 - 3
BansheeUtility/Include/BsMatrix4.h

@@ -401,9 +401,7 @@ namespace BansheeEngine
         /**
         /**
          * @brief	Transform a 4D vector by this matrix.  
          * @brief	Transform a 4D vector by this matrix.  
          *
          *
-         * @note	After transformation all components are projected back so that w remains 1.
-         * 			
-		 *			If your matrix doesn't contain projection components use "multiply3x4" method as it is faster.
+         * @note	If your matrix doesn't contain projection components use "multiply3x4" method as it is faster.
          */
          */
         Vector4 multiply(const Vector4& v) const
         Vector4 multiply(const Vector4& v) const
         {
         {

+ 2 - 2
MBansheeEngine/Math/Matrix3.cs

@@ -54,11 +54,11 @@ namespace BansheeEngine
         {
         {
             get
             get
             {
             {
-                return this[row * 4 + column];
+                return this[row * 3 + column];
             }
             }
             set
             set
             {
             {
-                this[row * 4 + column] = value;
+                this[row * 3 + column] = value;
             }
             }
         }
         }
 
 

+ 1 - 1
Notes.txt

@@ -74,7 +74,7 @@ Reminders:
   - Add FolderManager, extensible C# script that can be attached to a folder (can be in a folder .meta) file. Handles processing of assets in that folder. Can get notified 
   - Add FolderManager, extensible C# script that can be attached to a folder (can be in a folder .meta) file. Handles processing of assets in that folder. Can get notified 
     whenever anything in the folder changes. But is that necessary if I can have asset post- and pre- processor that can filter by folder programatically?
     whenever anything in the folder changes. But is that necessary if I can have asset post- and pre- processor that can filter by folder programatically?
   - Add option to optimize mesh for post-transform cache (triangles sharing vertices are sequential) on import (also pre-transform as well, order vertices by their first reference in IB, and so on)
   - Add option to optimize mesh for post-transform cache (triangles sharing vertices are sequential) on import (also pre-transform as well, order vertices by their first reference in IB, and so on)
-
+  - It would be nice to have automated creation of glue code between C# and C++ instead of writing all of these Script classes
 
 
 Potential optimizations:
 Potential optimizations:
  - bulkPixelConversion is EXTREMELY poorly unoptimized. Each pixel it calls a separate method that does redudant operations every pixel.
  - bulkPixelConversion is EXTREMELY poorly unoptimized. Each pixel it calls a separate method that does redudant operations every pixel.

+ 9 - 1
SBansheeEditor/Source/BsScriptGizmoManager.cpp

@@ -10,6 +10,7 @@
 #include "BsComponent.h"
 #include "BsComponent.h"
 #include "BsManagedComponent.h"
 #include "BsManagedComponent.h"
 #include "BsGizmoManager.h"
 #include "BsGizmoManager.h"
+#include "BsSelection.h"
 
 
 using namespace std::placeholders;
 using namespace std::placeholders;
 
 
@@ -41,6 +42,8 @@ namespace BansheeEngine
 
 
 	void ScriptGizmoManager::update()
 	void ScriptGizmoManager::update()
 	{
 	{
+		GizmoManager::instance().clearGizmos();
+
 		HSceneObject rootSO = SceneManager::instance().getRootNode();
 		HSceneObject rootSO = SceneManager::instance().getRootNode();
 
 
 		Stack<HSceneObject> todo;
 		Stack<HSceneObject> todo;
@@ -49,6 +52,8 @@ namespace BansheeEngine
 		bool isParentSelected = false;
 		bool isParentSelected = false;
 		UINT32 parentSelectedPopIdx = 0;
 		UINT32 parentSelectedPopIdx = 0;
 		
 		
+		Vector<HSceneObject> selectedObjects = Selection::instance().getSceneObjects();
+
 		while (!todo.empty())
 		while (!todo.empty())
 		{
 		{
 			if (isParentSelected && parentSelectedPopIdx == (UINT32)todo.size())
 			if (isParentSelected && parentSelectedPopIdx == (UINT32)todo.size())
@@ -59,7 +64,7 @@ namespace BansheeEngine
 			HSceneObject curSO = todo.top();
 			HSceneObject curSO = todo.top();
 			todo.pop();
 			todo.pop();
 
 
-			bool isSelected = dummyIsSelected(curSO);
+			bool isSelected = std::count(selectedObjects.begin(), selectedObjects.end(), curSO) > 0;
 			if (isSelected && !isParentSelected)
 			if (isSelected && !isParentSelected)
 			{
 			{
 				isParentSelected = true;
 				isParentSelected = true;
@@ -91,10 +96,13 @@ namespace BansheeEngine
 						if (drawGizmo)
 						if (drawGizmo)
 						{
 						{
 							bool pickable = (flags & (UINT32)DrawGizmoFlags::Pickable) != 0;
 							bool pickable = (flags & (UINT32)DrawGizmoFlags::Pickable) != 0;
+							GizmoManager::instance().startGizmo(curSO);
 							GizmoManager::instance().setPickable(pickable);
 							GizmoManager::instance().setPickable(pickable);
 
 
 							void* params[1] = { managedComponent->getManagedInstance() };
 							void* params[1] = { managedComponent->getManagedInstance() };
 							iterFind->second.drawGizmosMethod->invoke(nullptr, params);
 							iterFind->second.drawGizmosMethod->invoke(nullptr, params);
+
+							GizmoManager::instance().endGizmo();
 						}
 						}
 					}
 					}
 				}
 				}

+ 4 - 4
SBansheeEditor/Source/BsScriptHandleSliderDisc.cpp

@@ -28,10 +28,10 @@ namespace BansheeEngine
 
 
 	void ScriptHandleSliderDisc::initRuntimeData()
 	void ScriptHandleSliderDisc::initRuntimeData()
 	{
 	{
-		metaData.scriptClass->addInternalCall("internal_CreateInstance", &ScriptHandleSliderDisc::internal_CreateInstance);
-		metaData.scriptClass->addInternalCall("internal_GetDelta", &ScriptHandleSliderDisc::internal_GetDelta);
-		metaData.scriptClass->addInternalCall("internal_GetDeltaDirection", &ScriptHandleSliderDisc::internal_GetDeltaDirection);
-		metaData.scriptClass->addInternalCall("internal_GetNewRotation", &ScriptHandleSliderDisc::internal_GetNewRotation);
+		metaData.scriptClass->addInternalCall("Internal_CreateInstance", &ScriptHandleSliderDisc::internal_CreateInstance);
+		metaData.scriptClass->addInternalCall("Internal_GetDelta", &ScriptHandleSliderDisc::internal_GetDelta);
+		metaData.scriptClass->addInternalCall("Internal_GetDeltaDirection", &ScriptHandleSliderDisc::internal_GetDeltaDirection);
+		metaData.scriptClass->addInternalCall("Internal_GetNewRotation", &ScriptHandleSliderDisc::internal_GetNewRotation);
 	}
 	}
 
 
 	void ScriptHandleSliderDisc::internal_CreateInstance(MonoObject* instance, Vector3 normal, float radius, bool fixedScale, float snapValue)
 	void ScriptHandleSliderDisc::internal_CreateInstance(MonoObject* instance, Vector3 normal, float radius, bool fixedScale, float snapValue)

+ 3 - 3
SBansheeEditor/Source/BsScriptHandleSliderLine.cpp

@@ -28,9 +28,9 @@ namespace BansheeEngine
 
 
 	void ScriptHandleSliderLine::initRuntimeData()
 	void ScriptHandleSliderLine::initRuntimeData()
 	{
 	{
-		metaData.scriptClass->addInternalCall("internal_CreateInstance", &ScriptHandleSliderLine::internal_CreateInstance);
-		metaData.scriptClass->addInternalCall("internal_GetDelta", &ScriptHandleSliderLine::internal_GetDelta);
-		metaData.scriptClass->addInternalCall("internal_GetNewPosition", &ScriptHandleSliderLine::internal_GetNewPosition);
+		metaData.scriptClass->addInternalCall("Internal_CreateInstance", &ScriptHandleSliderLine::internal_CreateInstance);
+		metaData.scriptClass->addInternalCall("Internal_GetDelta", &ScriptHandleSliderLine::internal_GetDelta);
+		metaData.scriptClass->addInternalCall("Internal_GetNewPosition", &ScriptHandleSliderLine::internal_GetNewPosition);
 	}
 	}
 
 
 	void ScriptHandleSliderLine::internal_CreateInstance(MonoObject* instance, Vector3 direction, float length, bool fixedScale, float snapValue)
 	void ScriptHandleSliderLine::internal_CreateInstance(MonoObject* instance, Vector3 direction, float length, bool fixedScale, float snapValue)

+ 4 - 4
SBansheeEditor/Source/BsScriptHandleSliderPlane.cpp

@@ -28,10 +28,10 @@ namespace BansheeEngine
 
 
 	void ScriptHandleSliderPlane::initRuntimeData()
 	void ScriptHandleSliderPlane::initRuntimeData()
 	{
 	{
-		metaData.scriptClass->addInternalCall("internal_CreateInstance", &ScriptHandleSliderPlane::internal_CreateInstance);
-		metaData.scriptClass->addInternalCall("internal_GetDelta", &ScriptHandleSliderPlane::internal_GetDelta);
-		metaData.scriptClass->addInternalCall("internal_GetDeltaDirection", &ScriptHandleSliderPlane::internal_GetDeltaDirection);
-		metaData.scriptClass->addInternalCall("internal_GetNewPosition", &ScriptHandleSliderPlane::internal_GetNewPosition);
+		metaData.scriptClass->addInternalCall("Internal_CreateInstance", &ScriptHandleSliderPlane::internal_CreateInstance);
+		metaData.scriptClass->addInternalCall("Internal_GetDelta", &ScriptHandleSliderPlane::internal_GetDelta);
+		metaData.scriptClass->addInternalCall("Internal_GetDeltaDirection", &ScriptHandleSliderPlane::internal_GetDeltaDirection);
+		metaData.scriptClass->addInternalCall("Internal_GetNewPosition", &ScriptHandleSliderPlane::internal_GetNewPosition);
 	}
 	}
 
 
 	void ScriptHandleSliderPlane::internal_CreateInstance(MonoObject* instance, Vector3 dir1, Vector3 dir2, float length, bool fixedScale, float snapValue)
 	void ScriptHandleSliderPlane::internal_CreateInstance(MonoObject* instance, Vector3 dir1, Vector3 dir2, float length, bool fixedScale, float snapValue)

+ 5 - 2
SceneView.txt

@@ -4,10 +4,13 @@
     - Make those two a non-component types. Anywhere they are used in the Renderer they should just be passed as pointers.
     - Make those two a non-component types. Anywhere they are used in the Renderer they should just be passed as pointers.
 	- Then make a Component wrapper around the non-component types, and also a C# wrapper around the same types
 	- Then make a Component wrapper around the non-component types, and also a C# wrapper around the same types
 
 
-RESOURCES CAN BE INCORRECTLY CAST between each other. e.g. HSpriteTexture to HTexture will be cast implicitly.
 REFACTOR material getParams* and related classes. Those params should update all gpu program params that share that variable, not just the first found
 REFACTOR material getParams* and related classes. Those params should update all gpu program params that share that variable, not just the first found
-Icon appears faded even if it renders in front of a mesh (OpenGL). Likely wrong depth.
+Add a way to render GUI image without alpha
 Crash related to Handles when object is selected
 Crash related to Handles when object is selected
+Exception related to handle manager on shutdown
+Cannot pick gizmo icon
+Cone handle doesn't render properly
+Line slider collider intersection doesn't work properly
 
 
 Test gizmos
 Test gizmos
  - HOOK UP GIZMO SELECTION and test it
  - HOOK UP GIZMO SELECTION and test it