Преглед изворни кода

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

Marko Pintera пре 11 година
родитељ
комит
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.
 		 */
-		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

+ 2 - 2
BansheeCore/Source/BsRenderSystem.cpp

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

+ 1 - 1
BansheeD3D11RenderSystem/Include/BsD3D11RenderSystem.h

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

+ 1 - 10
BansheeD3D11RenderSystem/Source/BsD3D11RenderSystem.cpp

@@ -988,7 +988,7 @@ namespace BansheeEngine
 		return VET_COLOR_ABGR;
 	}
 
-	void D3D11RenderSystem::convertProjectionMatrix(const Matrix4& matrix, Matrix4& dest, bool forGpuProgram)
+	void D3D11RenderSystem::convertProjectionMatrix(const Matrix4& matrix, Matrix4& dest)
 	{
 		dest = matrix;
 
@@ -997,15 +997,6 @@ namespace BansheeEngine
 		dest[2][1] = (dest[2][1] + dest[3][1]) / 2;
 		dest[2][2] = (dest[2][2] + dest[3][2]) / 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()

+ 1 - 1
BansheeD3D9RenderSystem/Include/BsD3D9RenderSystem.h

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

+ 1 - 10
BansheeD3D9RenderSystem/Source/BsD3D9RenderSystem.cpp

@@ -1511,7 +1511,7 @@ namespace BansheeEngine
 		return VET_COLOR_ARGB;
 	}
 
-	void D3D9RenderSystem::convertProjectionMatrix(const Matrix4& matrix, Matrix4& dest, bool forGpuProgram)
+	void D3D9RenderSystem::convertProjectionMatrix(const Matrix4& matrix, Matrix4& dest)
 	{
 		dest = matrix;
 
@@ -1520,15 +1520,6 @@ namespace BansheeEngine
 		dest[2][1] = (dest[2][1] + dest[3][1]) / 2;
 		dest[2][2] = (dest[2][2] + dest[3][2]) / 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 clearGizmos();
 
+		HSceneObject getSceneObject(UINT32 gizmoIdx);
+
 	private:
 		friend class GizmoManagerCore;
 
+		enum class GizmoMaterial
+		{
+			Solid, Wire, Picking
+		};
+
 		struct CommonData
 		{
+			UINT32 idx;
 			Color color;
 			Matrix4 transform;
 			HSceneObject sceneObject;
@@ -99,7 +107,7 @@ namespace BansheeEngine
 		typedef Vector<IconRenderData> IconRenderDataVec;
 		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 calculateIconColors(const Color& tint, const Camera& camera, UINT32 iconHeight, bool fixedScale,
@@ -122,6 +130,7 @@ namespace BansheeEngine
 		Matrix4 mTransform;
 		HSceneObject mActiveSO;
 		bool mPickable;
+		UINT32 mCurrentIdx;
 
 		DrawHelper* mDrawHelper;
 		DrawHelper* mPickingDrawHelper;
@@ -133,6 +142,7 @@ namespace BansheeEngine
 		Vector<LineData> mLineData;
 		Vector<FrustumData> mFrustumData;
 		Vector<IconData> mIconData;
+		Map<UINT32, HSceneObject> mIdxToSceneObjectMap;
 
 		MeshHeapPtr mIconMeshHeap;
 
@@ -203,12 +213,8 @@ namespace BansheeEngine
 		void initialize(const GizmoManager::CoreInitData& initData);
 
 		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,
 			const MeshProxyPtr& iconMeshProxy, const GizmoManager::IconRenderDataVecPtr& iconRenderData);

+ 4 - 21
BansheeEditor/Include/BsScenePicking.h

@@ -7,21 +7,6 @@
 
 namespace BansheeEngine
 {
-	class PickResult
-	{
-	public:
-		enum class Type
-		{
-			SceneObject,
-			Gizmo,
-			None
-		};
-
-		HSceneObject sceneObject;
-		UINT32 gizmoId;
-		Type type;
-	};
-
 	class ScenePicking : public Module<ScenePicking>
 	{
 		struct RenderablePickData
@@ -59,10 +44,8 @@ namespace BansheeEngine
 	public:
 		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:
 		typedef Set<RenderablePickData, std::function<bool(const RenderablePickData&, const RenderablePickData&)>> RenderableSet;
@@ -72,8 +55,8 @@ namespace BansheeEngine
 		Color encodeIndex(UINT32 index);
 		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;
 

+ 1 - 1
BansheeEditor/Source/BsBuiltinEditorResources.cpp

@@ -1420,7 +1420,6 @@ namespace BansheeEngine
 		blendDesc.renderTargetDesc[0].srcBlend = BF_SOURCE_ALPHA;
 		blendDesc.renderTargetDesc[0].dstBlend = BF_INV_SOURCE_ALPHA;
 		blendDesc.renderTargetDesc[0].blendOp = BO_ADD;
-		blendDesc.renderTargetDesc[0].renderTargetWriteMask = 0x7; // Don't write to alpha
 
 		HBlendState blendState = BlendState::create(blendDesc);
 
@@ -1491,6 +1490,7 @@ namespace BansheeEngine
 
 		mShaderGizmoAlphaPicking->addParameter("mainTexture", "mainTexture", GPOT_TEXTURE2D);
 
+		mShaderGizmoAlphaPicking->addParameter("alphaCutoff", "alphaCutoff", GPDT_FLOAT1);
 		mShaderGizmoAlphaPicking->addParameter("matViewProj", "matViewProj", GPDT_MATRIX_4X4);
 
 		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;
 
 	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>();
 		mPickingDrawHelper = bs_new<DrawHelper>();
 
@@ -102,11 +103,13 @@ namespace BansheeEngine
 
 	void GizmoManager::setColor(const Color& color)
 	{
+		mDrawHelper->setColor(color);
 		mColor = color;
 	}
 
 	void GizmoManager::setTransform(const Matrix4& transform)
 	{
+		mDrawHelper->setTransform(transform);
 		mTransform = transform;
 	}
 
@@ -115,6 +118,7 @@ namespace BansheeEngine
 		mSolidCubeData.push_back(CubeData());
 		CubeData& cubeData = mSolidCubeData.back();
 
+		cubeData.idx = mCurrentIdx++;
 		cubeData.position = position;
 		cubeData.extents = extents;
 		cubeData.color = mColor;
@@ -123,6 +127,7 @@ namespace BansheeEngine
 		cubeData.pickable = mPickable;
 
 		mDrawHelper->cube(position, extents);
+		mIdxToSceneObjectMap[cubeData.idx] = mActiveSO;
 	}
 
 	void GizmoManager::drawSphere(const Vector3& position, float radius)
@@ -130,6 +135,7 @@ namespace BansheeEngine
 		mSolidSphereData.push_back(SphereData());
 		SphereData& sphereData = mSolidSphereData.back();
 
+		sphereData.idx = mCurrentIdx++;
 		sphereData.position = position;
 		sphereData.radius = radius;
 		sphereData.color = mColor;
@@ -138,6 +144,7 @@ namespace BansheeEngine
 		sphereData.pickable = mPickable;
 
 		mDrawHelper->sphere(position, radius);
+		mIdxToSceneObjectMap[sphereData.idx] = mActiveSO;
 	}
 
 	void GizmoManager::drawWireCube(const Vector3& position, const Vector3& extents)
@@ -145,6 +152,7 @@ namespace BansheeEngine
 		mWireCubeData.push_back(CubeData());
 		CubeData& cubeData = mWireCubeData.back();
 
+		cubeData.idx = mCurrentIdx++;
 		cubeData.position = position;
 		cubeData.extents = extents;
 		cubeData.color = mColor;
@@ -153,6 +161,7 @@ namespace BansheeEngine
 		cubeData.pickable = mPickable;
 
 		mDrawHelper->wireCube(position, extents);
+		mIdxToSceneObjectMap[cubeData.idx] = mActiveSO;
 	}
 
 	void GizmoManager::drawWireSphere(const Vector3& position, float radius)
@@ -160,6 +169,7 @@ namespace BansheeEngine
 		mWireSphereData.push_back(SphereData());
 		SphereData& sphereData = mWireSphereData.back();
 
+		sphereData.idx = mCurrentIdx++;
 		sphereData.position = position;
 		sphereData.radius = radius;
 		sphereData.color = mColor;
@@ -168,6 +178,7 @@ namespace BansheeEngine
 		sphereData.pickable = mPickable;
 
 		mDrawHelper->wireSphere(position, radius);
+		mIdxToSceneObjectMap[sphereData.idx] = mActiveSO;
 	}
 
 	void GizmoManager::drawLine(const Vector3& start, const Vector3& end)
@@ -175,6 +186,7 @@ namespace BansheeEngine
 		mLineData.push_back(LineData());
 		LineData& lineData = mLineData.back();
 
+		lineData.idx = mCurrentIdx++;
 		lineData.start = start;
 		lineData.end = end;
 		lineData.color = mColor;
@@ -183,6 +195,7 @@ namespace BansheeEngine
 		lineData.pickable = mPickable;
 
 		mDrawHelper->line(start, end);
+		mIdxToSceneObjectMap[lineData.idx] = mActiveSO;
 	}
 
 	void GizmoManager::drawFrustum(const Vector3& position, float aspect, Degree FOV, float near, float far)
@@ -190,6 +203,7 @@ namespace BansheeEngine
 		mFrustumData.push_back(FrustumData());
 		FrustumData& frustumData = mFrustumData.back();
 
+		frustumData.idx = mCurrentIdx++;
 		frustumData.position = position;
 		frustumData.aspect = aspect;
 		frustumData.FOV = FOV;
@@ -201,6 +215,7 @@ namespace BansheeEngine
 		frustumData.pickable = mPickable;
 
 		mDrawHelper->frustum(position, aspect, FOV, near, far);
+		mIdxToSceneObjectMap[frustumData.idx] = mActiveSO;
 	}
 
 	void GizmoManager::drawIcon(Vector3 position, HSpriteTexture image, bool fixedScale)
@@ -208,6 +223,7 @@ namespace BansheeEngine
 		mIconData.push_back(IconData());
 		IconData& iconData = mIconData.back();
 
+		iconData.idx = mCurrentIdx++;
 		iconData.position = position;
 		iconData.texture = image;
 		iconData.fixedScale = fixedScale;
@@ -215,6 +231,8 @@ namespace BansheeEngine
 		iconData.transform = mTransform;
 		iconData.sceneObject = mActiveSO;
 		iconData.pickable = mPickable;
+
+		mIdxToSceneObjectMap[iconData.idx] = mActiveSO;
 	}
 
 	void GizmoManager::update()
@@ -257,8 +275,6 @@ namespace BansheeEngine
 			IconRenderDataVecPtr iconRenderData = bs_shared_ptr<IconRenderDataVec>();
 			gCoreAccessor().queueCommand(std::bind(&GizmoManagerCore::updateData, mCore, nullptr, nullptr, nullptr, nullptr, iconRenderData));
 		}
-
-		clearGizmos();
 	}
 
 	void GizmoManager::renderForPicking(const HCamera& camera, std::function<Color(UINT32)> idxToColorCallback)
@@ -268,13 +284,12 @@ namespace BansheeEngine
 
 		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)
 		{
 			if (!cubeDataEntry.pickable)
 				continue;
 
-			mPickingDrawHelper->setColor(idxToColorCallback(gizmoIdx++));
+			mPickingDrawHelper->setColor(idxToColorCallback(cubeDataEntry.idx));
 			mPickingDrawHelper->setTransform(cubeDataEntry.transform);
 
 			mPickingDrawHelper->cube(cubeDataEntry.position, cubeDataEntry.extents);
@@ -285,7 +300,7 @@ namespace BansheeEngine
 			if (!cubeDataEntry.pickable)
 				continue;
 
-			mPickingDrawHelper->setColor(idxToColorCallback(gizmoIdx++));
+			mPickingDrawHelper->setColor(idxToColorCallback(cubeDataEntry.idx));
 			mPickingDrawHelper->setTransform(cubeDataEntry.transform);
 
 			mPickingDrawHelper->wireCube(cubeDataEntry.position, cubeDataEntry.extents);
@@ -296,7 +311,7 @@ namespace BansheeEngine
 			if (!sphereDataEntry.pickable)
 				continue;
 
-			mPickingDrawHelper->setColor(idxToColorCallback(gizmoIdx++));
+			mPickingDrawHelper->setColor(idxToColorCallback(sphereDataEntry.idx));
 			mPickingDrawHelper->setTransform(sphereDataEntry.transform);
 
 			mPickingDrawHelper->sphere(sphereDataEntry.position, sphereDataEntry.radius);
@@ -307,7 +322,7 @@ namespace BansheeEngine
 			if (!sphereDataEntry.pickable)
 				continue;
 
-			mPickingDrawHelper->setColor(idxToColorCallback(gizmoIdx++));
+			mPickingDrawHelper->setColor(idxToColorCallback(sphereDataEntry.idx));
 			mPickingDrawHelper->setTransform(sphereDataEntry.transform);
 
 			mPickingDrawHelper->wireSphere(sphereDataEntry.position, sphereDataEntry.radius);
@@ -318,7 +333,7 @@ namespace BansheeEngine
 			if (!lineDataEntry.pickable)
 				continue;
 
-			mPickingDrawHelper->setColor(idxToColorCallback(gizmoIdx++));
+			mPickingDrawHelper->setColor(idxToColorCallback(lineDataEntry.idx));
 			mPickingDrawHelper->setTransform(lineDataEntry.transform);
 
 			mPickingDrawHelper->line(lineDataEntry.start, lineDataEntry.end);
@@ -329,7 +344,7 @@ namespace BansheeEngine
 			if (!frustumDataEntry.pickable)
 				continue;
 
-			mPickingDrawHelper->setColor(idxToColorCallback(gizmoIdx++));
+			mPickingDrawHelper->setColor(idxToColorCallback(frustumDataEntry.idx));
 			mPickingDrawHelper->setTransform(frustumDataEntry.transform);
 
 			mPickingDrawHelper->frustum(frustumDataEntry.position, frustumDataEntry.aspect, frustumDataEntry.FOV, 
@@ -342,7 +357,7 @@ namespace BansheeEngine
 				continue;
 
 			iconData.push_back(iconDataEntry);
-			iconData.back().color = idxToColorCallback(gizmoIdx++);
+			iconData.back().color = idxToColorCallback(iconDataEntry.idx);
 		}
 
 		TransientMeshPtr solidMesh = mPickingDrawHelper->buildSolidMesh();
@@ -351,19 +366,19 @@ namespace BansheeEngine
 
 		// Note: This must be rendered while Scene view is being rendered
 		Matrix4 viewMat = camera->getViewMatrix();
-		Matrix4 projMat = camera->getProjectionMatrix();
+		Matrix4 projMat = camera->getProjectionMatrixRS();
 		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();
 
-		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->releaseWireMesh(wireMesh);
@@ -379,12 +394,15 @@ namespace BansheeEngine
 		mLineData.clear();
 		mFrustumData.clear();
 		mIconData.clear();
+		mIdxToSceneObjectMap.clear();
 
 		mDrawHelper->clear();
+
+		mCurrentIdx = 0;
 	}
 
 	TransientMeshPtr GizmoManager::buildIconMesh(const HCamera& camera, const Vector<IconData>& iconData, 
-		bool pickingOnly, GizmoManager::IconRenderDataVecPtr& iconRenderData)
+		bool forPicking, GizmoManager::IconRenderDataVecPtr& iconRenderData)
 	{
 		mSortedIconData.clear();
 		
@@ -392,9 +410,9 @@ namespace BansheeEngine
 			mSortedIconData.resize(iconData.size());
 
 		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;
 			if (distance < camera->getNearClipDistance()) // Ignore behind clip plane
@@ -403,10 +421,10 @@ namespace BansheeEngine
 			if (distance > MAX_ICON_RANGE) // Ignore too far away
 				continue;
 
-			if (!iconData.texture) // Ignore missing texture
+			if (!iconEntry.texture) // Ignore missing texture
 				continue;
 
-			if (pickingOnly && !iconData.pickable)
+			if (forPicking && !iconEntry.pickable)
 				continue;
 
 			SortedIconData& sortedIconData = mSortedIconData[i];
@@ -490,7 +508,7 @@ namespace BansheeEngine
 
 			Vector3 position((float)sortedIconData.screenPosition.x, (float)sortedIconData.screenPosition.y, -sortedIconData.distance);
 			Vector3 projPosition = camera->projectPoint(position);
-			position.z = -projPosition.z;
+			position.z = projPosition.z;
 
 			float halfWidth = iconWidth * 0.5f;
 			float halfHeight = iconHeight * 0.5f;
@@ -510,6 +528,9 @@ namespace BansheeEngine
 			Color normalColor, fadedColor;
 			calculateIconColors(curIconData.color, *camera.get(), (UINT32)(halfHeight * 2.0f), curIconData.fixedScale, normalColor, fadedColor);
 
+			if (forPicking)
+				normalColor = curIconData.color;
+
 			Vector3 positions[4];
 			positions[0] = position + Vector3(-halfWidth, -halfHeight, 0.0f);
 			positions[1] = position + Vector3(halfWidth, -halfHeight, 0.0f);
@@ -584,6 +605,16 @@ namespace BansheeEngine
 		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;
 
 	GizmoManagerCore::GizmoManagerCore(const PrivatelyConstuct& dummy)
@@ -682,40 +713,41 @@ namespace BansheeEngine
 		screenArea.height = (int)(normArea.height * height);
 
 		if (mSolidMeshProxy != nullptr)
-			renderSolidGizmos(camera.viewMatrix, camera.projMatrix, mSolidMeshProxy);
+			renderGizmos(camera.viewMatrix, camera.projMatrix, mSolidMeshProxy, GizmoManager::GizmoMaterial::Solid);
 
 		if (mWireMeshProxy != nullptr)
-			renderWireGizmos(camera.viewMatrix, camera.projMatrix, mWireMeshProxy);
+			renderGizmos(camera.viewMatrix, camera.projMatrix, mWireMeshProxy, GizmoManager::GizmoMaterial::Wire);
 
 		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;
 
 		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);
 	}
 
-	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();
 		MeshBasePtr mesh;
@@ -749,89 +781,44 @@ namespace BansheeEngine
 		float near = rs.getMinimumDepthInputValue();
 		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
-			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();

+ 6 - 2
BansheeEditor/Source/BsHandleSliderManager.cpp

@@ -53,7 +53,9 @@ namespace BansheeEngine
 
 				if (mHoverSlider != overSlider)
 				{
-					mHoverSlider->setInactive();
+					if (mHoverSlider != nullptr)
+						mHoverSlider->setInactive();
+
 					mHoverSlider = overSlider;
 					overSlider->setHover();
 				}
@@ -68,7 +70,9 @@ namespace BansheeEngine
 
 				if (mActiveSlider != overSlider)
 				{
-					mActiveSlider->setInactive();
+					if (mActiveSlider != nullptr)
+						mActiveSlider->setInactive();
+
 					mActiveSlider = overSlider;
 					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 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)
 			{

+ 1 - 1
BansheeEditor/Source/BsSceneGrid.cpp

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

+ 55 - 58
BansheeEditor/Source/BsScenePicking.cpp

@@ -22,6 +22,7 @@
 #include "BsBuiltinEditorResources.h"
 #include "BsShader.h"
 #include "BsRenderer.h"
+#include "BsGizmoManager.h"
 
 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)
-			return { HSceneObject(), 0, PickResult::Type::None };
+			return HSceneObject();
 
 		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)
 		{
@@ -128,7 +104,7 @@ namespace BansheeEngine
 				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();
 		RenderableSet pickData(comparePickElement);
@@ -210,50 +186,49 @@ namespace BansheeEngine
 			}
 		}
 
+		UINT32 firstGizmoIdx = (UINT32)pickData.size();
+
 		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);
 
 		assert(op.hasCompleted());
 
 		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;
 	}
 
-	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();
 
-		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.setViewport(vp);
+		rs.setViewport(viewport);
 		rs.clearRenderTarget(FBT_COLOR | FBT_DEPTH | FBT_STENCIL, Color::White);
 		rs.setScissorRect(position.x, position.y, position.x + area.x, position.y + area.y);
 
@@ -273,7 +248,7 @@ namespace BansheeEngine
 				else
 					Renderer::setPass(*mMaterialData[(UINT32)activeMaterialCull].mMatPickingProxy, 0);
 			}
-			
+
 			Color color = encodeIndex(renderable.index);
 			MaterialData& md = mMaterialData[(UINT32)activeMaterialCull];
 
@@ -297,12 +272,34 @@ namespace BansheeEngine
 
 			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);
 		GpuResourceDataPtr outputData = outputPixelData;
 		AsyncOp unused;
 
+		RenderSystem& rs = RenderSystem::instance();
+
+		rs.endFrame();
 		rs.readSubresource(outputTexture, 0, outputData, unused);
 
 		Map<UINT32, UINT32> selectionScores;

+ 1 - 1
BansheeEditorExec/BsEditorExec.cpp

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

+ 5 - 5
BansheeEngine/Source/BsCamera.cpp

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

+ 9 - 8
BansheeEngine/Source/BsDrawHelper.cpp

@@ -156,8 +156,8 @@ namespace BansheeEngine
 		UINT32 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)
@@ -175,8 +175,8 @@ namespace BansheeEngine
 		UINT32 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)
@@ -216,8 +216,8 @@ namespace BansheeEngine
 		UINT32 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, 
@@ -251,8 +251,8 @@ namespace BansheeEngine
 		rectData.color = mColor;
 		rectData.transform = mTransform;
 
-		mTotalRequiredWireVertices += 4;
-		mTotalRequiredWireIndices += 6;
+		mTotalRequiredSolidVertices += 4;
+		mTotalRequiredSolidIndices += 6;
 	}
 
 	void DrawHelper::clear()
@@ -269,6 +269,7 @@ namespace BansheeEngine
 		mWireDiscData.clear();
 		mArcData.clear();
 		mWireArcData.clear();
+		mConeData.clear();
 
 		mTotalRequiredSolidVertices = 0;
 		mTotalRequiredSolidIndices = 0;

+ 18 - 4
BansheeEngine/Source/BsShapeMeshes3D.cpp

@@ -289,7 +289,7 @@ namespace BansheeEngine
 	void ShapeMeshes3D::getNumElementsCone(UINT32 quality, UINT32& numVertices, UINT32& numIndices)
 	{
 		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)
@@ -596,13 +596,20 @@ namespace BansheeEngine
 		}
 
 		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 + 1] = vertexOffset + i;
 			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
 		generateArcVertices(base, normal, radius, Degree(0), Degree(360),
 			numArcVertices + 1, outVertices, 0, vertexStride);
@@ -629,16 +636,23 @@ namespace BansheeEngine
 
 		outVertices += numArcVertices * vertexStride;
 		outVertices = writeVector3(outVertices, vertexStride, topVertex); // Write top vertex
-		UINT32 topIdx = numArcVertices * 2 + 2;
+		UINT32 topIdx = numArcVertices;
 
 		outIndices += numTriangles * 3;
 		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 + 1] = curVertOffset + i;
 			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)

+ 1 - 2
BansheeGLRenderSystem/Include/BsGLRenderSystem.h

@@ -161,8 +161,7 @@ namespace BansheeEngine
 		/**
 		 * @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                */

+ 1 - 1
BansheeGLRenderSystem/Source/BsGLRenderSystem.cpp

@@ -2087,7 +2087,7 @@ namespace BansheeEngine
 		return VET_COLOR_ABGR;
 	}
 
-	void GLRenderSystem::convertProjectionMatrix(const Matrix4& matrix, Matrix4& dest, bool forGpuProgram)
+	void GLRenderSystem::convertProjectionMatrix(const Matrix4& matrix, Matrix4& dest)
 	{
 		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.
 	 * 			
-	 *			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
 	{
@@ -34,7 +35,9 @@ namespace BansheeEngine
 			:mData(bs_shared_ptr<AsyncOpData, ScratchAlloc>())
 		{
 #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
 		}
 

+ 1 - 3
BansheeUtility/Include/BsMatrix4.h

@@ -401,9 +401,7 @@ namespace BansheeEngine
         /**
          * @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
         {

+ 2 - 2
MBansheeEngine/Math/Matrix3.cs

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

+ 4 - 4
SBansheeEditor/Source/BsScriptHandleSliderDisc.cpp

@@ -28,10 +28,10 @@ namespace BansheeEngine
 
 	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)

+ 3 - 3
SBansheeEditor/Source/BsScriptHandleSliderLine.cpp

@@ -28,9 +28,9 @@ namespace BansheeEngine
 
 	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)

+ 4 - 4
SBansheeEditor/Source/BsScriptHandleSliderPlane.cpp

@@ -28,10 +28,10 @@ namespace BansheeEngine
 
 	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)

+ 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.
 	- 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
-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
+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
  - HOOK UP GIZMO SELECTION and test it