Browse Source

Make sure ScreenToWorldPoint() correctly returns points on a plane with the specified distance (Z).

Lasse Öörni 10 years ago
parent
commit
eb9c04fcac
2 changed files with 5 additions and 3 deletions
  1. 3 1
      Source/Urho3D/Graphics/Camera.cpp
  2. 2 2
      Source/Urho3D/Graphics/Camera.h

+ 3 - 1
Source/Urho3D/Graphics/Camera.cpp

@@ -360,7 +360,9 @@ Vector2 Camera::WorldToScreenPoint(const Vector3& worldPos) const
 Vector3 Camera::ScreenToWorldPoint(const Vector3& screenPos) const
 {
     Ray ray = GetScreenRay(screenPos.x_, screenPos.y_);
-    return ray.origin_ + ray.direction_ * screenPos.z_;
+    Vector3 viewSpaceDir = (GetView() * Vector4(ray.direction_, 0.0f));
+    float rayDistance = (Max(screenPos.z_ - GetNearClip(), 0.0f) / viewSpaceDir.z_);
+    return ray.origin_ + ray.direction_ * rayDistance;
 }
 
 const Frustum& Camera::GetFrustum() const

+ 2 - 2
Source/Urho3D/Graphics/Camera.h

@@ -149,11 +149,11 @@ public:
     Frustum GetViewSpaceFrustum() const;
     /// Return split frustum in view space.
     Frustum GetViewSpaceSplitFrustum(float nearClip, float farClip) const;
-    /// Return ray corresponding to normalized screen coordinates (0.0 - 1.0).
+    /// Return ray corresponding to normalized screen coordinates (0.0 - 1.0), with origin on the near clip plane.
     Ray GetScreenRay(float x, float y) const;
     // Convert a world space point to normalized screen coordinates (0.0 - 1.0).
     Vector2 WorldToScreenPoint(const Vector3& worldPos) const;
-    // Convert normalized screen coordinates (0.0 - 1.0) and depth to a world space point.
+    // Convert normalized screen coordinates (0.0 - 1.0) and distance (in Z coordinate) to a world space point. The distance can not be closer than the near clip plane.
     Vector3 ScreenToWorldPoint(const Vector3& screenPos) const;
 
     /// Return projection offset.