Browse Source

Fixing camera clip space transforms to properly flip the Y axis

Marko Pintera 11 years ago
parent
commit
d896e3e772

+ 10 - 6
BansheeEditor/Source/BsGizmoManager.cpp

@@ -557,11 +557,11 @@ namespace BansheeEngine
 			UINT32 vertOffset = i * 4;
 			UINT32 vertOffset = i * 4;
 
 
 			indices[0] = vertOffset + 0;
 			indices[0] = vertOffset + 0;
-			indices[1] = vertOffset + 3;
-			indices[2] = vertOffset + 1;
-			indices[3] = vertOffset + 1;
-			indices[4] = vertOffset + 3;
-			indices[5] = vertOffset + 2;
+			indices[1] = vertOffset + 1;
+			indices[2] = vertOffset + 2;
+			indices[3] = vertOffset + 0;
+			indices[4] = vertOffset + 2;
+			indices[5] = vertOffset + 3;
 
 
 			indices += 6;
 			indices += 6;
 		}
 		}
@@ -784,7 +784,11 @@ 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); // Minus near/far because Z is flipped for normalized device coords
+		// Top/bottom have been swapped because we're moving from window coordinates (origin top left)
+		// to normalized device coordinates (origin bottom left)
+		// Negative near/far because Z is flipped for normalized device coordinates 
+		// (positive Z goes into screen as opposed to view space here we're looking along negative Z)
+		projMat.makeProjectionOrtho(left, right, top, bottom, -near, -far);
 
 
 		if (!usePickingMaterial)
 		if (!usePickingMaterial)
 		{
 		{

+ 0 - 1
BansheeEditor/Source/BsSceneEditorWidget.cpp

@@ -153,7 +153,6 @@ namespace BansheeEngine
 		if (!HandleManager::instance().isHandleActive())
 		if (!HandleManager::instance().isHandleActive())
 		{
 		{
 			// 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)
 			HSceneObject pickedObject = ScenePicking::instance().pickClosestObject(mCamera, scenePos, Vector2I(1, 1));
 			HSceneObject pickedObject = ScenePicking::instance().pickClosestObject(mCamera, scenePos, Vector2I(1, 1));
 
 
 			if (pickedObject)
 			if (pickedObject)

+ 3 - 3
BansheeEngine/Source/BsCameraHandler.cpp

@@ -531,7 +531,7 @@ namespace BansheeEngine
 	{
 	{
 		Vector2 clipPoint;
 		Vector2 clipPoint;
 		clipPoint.x = (float)(((screenPoint.x - mViewport->getX()) / (float)mViewport->getWidth()) * 2.0f - 1.0f);
 		clipPoint.x = (float)(((screenPoint.x - mViewport->getX()) / (float)mViewport->getWidth()) * 2.0f - 1.0f);
-		clipPoint.y = (float)(((screenPoint.y - mViewport->getY()) / (float)mViewport->getHeight()) * 2.0f - 1.0f);
+		clipPoint.y = (float)((1.0f - ((screenPoint.y - mViewport->getY()) / (float)mViewport->getHeight())) * 2.0f - 1.0f);
 
 
 		return clipPoint;
 		return clipPoint;
 	}
 	}
@@ -568,8 +568,8 @@ namespace BansheeEngine
 	Vector2I CameraHandler::clipToScreenPoint(const Vector2& clipPoint) const
 	Vector2I CameraHandler::clipToScreenPoint(const Vector2& clipPoint) const
 	{
 	{
 		Vector2I screenPoint;
 		Vector2I screenPoint;
-		screenPoint.x = Math::roundToInt(mViewport->getX() + (clipPoint.x + 1.0f) * mViewport->getWidth() * 0.5f);
-		screenPoint.y = Math::roundToInt(mViewport->getY() + (clipPoint.y + 1.0f) * mViewport->getHeight() * 0.5f);
+		screenPoint.x = Math::roundToInt(mViewport->getX() + ((clipPoint.x + 1.0f) * 0.5f) * mViewport->getWidth());
+		screenPoint.y = Math::roundToInt(mViewport->getY() + (1.0f - (clipPoint.y + 1.0f) * 0.5f) * mViewport->getHeight());
 
 
 		return screenPoint;
 		return screenPoint;
 	}
 	}

+ 10 - 5
BansheeUtility/Source/BsMatrix4.cpp

@@ -246,11 +246,16 @@ namespace BansheeEngine
 		}
 		}
 	}
 	}
 
 
-	void Matrix4::makeProjectionOrtho(float left, float right, float bottom,
-		float top, float near, float far)
+	void Matrix4::makeProjectionOrtho(float left, float right, float top,
+		float bottom, float near, float far)
 	{
 	{
+		// Create a matrix that transforms coordinate to normalized device coordinate in range:
+		// Left -1 - Right 1
+		// Bottom -1 - Top 1
+		// Near -1 - Far 1
+
 		float deltaX = right - left;
 		float deltaX = right - left;
-		float deltaY = top - bottom;
+		float deltaY = bottom - top;
 		float deltaZ = far - near;
 		float deltaZ = far - near;
 
 
 		m[0][0] = 2.0F / deltaX;
 		m[0][0] = 2.0F / deltaX;
@@ -259,9 +264,9 @@ namespace BansheeEngine
 		m[0][3] = -(right + left) / deltaX;
 		m[0][3] = -(right + left) / deltaX;
 
 
 		m[1][0] = 0.0f;
 		m[1][0] = 0.0f;
-		m[1][1] = 2.0F / deltaY;
+		m[1][1] = -2.0F / deltaY;
 		m[1][2] = 0.0f;
 		m[1][2] = 0.0f;
-		m[1][3] = -(top + bottom) / deltaY;
+		m[1][3] = (top + bottom) / deltaY;
 
 
 		m[2][0] = 0.0f;
 		m[2][0] = 0.0f;
 		m[2][1] = 0.0f;
 		m[2][1] = 0.0f;

+ 0 - 1
MBansheeEditor/DbgGizmo.cs

@@ -28,7 +28,6 @@ namespace BansheeEditor
                 target.sceneObject.position + 8.5f * Vector3.xAxis);
                 target.sceneObject.position + 8.5f * Vector3.xAxis);
             Gizmos.DrawFrustum(target.sceneObject.position + 10 * Vector3.xAxis, 1920.0f / 1080.0f, 90, 1.0f, 1000.0f);
             Gizmos.DrawFrustum(target.sceneObject.position + 10 * Vector3.xAxis, 1920.0f / 1080.0f, 90, 1.0f, 1000.0f);
 
 
-            Gizmos.color = Color.red;
             Gizmos.DrawIcon(target.sceneObject.position + new Vector3(0, 10, 0), iconTexture, false);
             Gizmos.DrawIcon(target.sceneObject.position + new Vector3(0, 10, 0), iconTexture, false);
         }
         }
     }
     }

+ 0 - 1
SceneView.txt

@@ -3,7 +3,6 @@
   - Make a C# wrapper for Camera and Renderable
   - Make a C# wrapper for Camera and Renderable
 
 
 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
-Add a way to render GUI image without alpha
 Line slider collider intersection doesn't work properly
 Line slider collider intersection doesn't work properly
 Handles need to render in front of everything
 Handles need to render in front of everything
 Clicking on empty space needs to deselect everything
 Clicking on empty space needs to deselect everything