} // end of GetWinRTRatio() /// <summary> /// Helper function for touch selection of standard 2d UI elements. /// </summary> /// <param name="touchPosition">Position to test against</param> /// <param name="camera">Current camera.</param> /// <param name="invWorldMatrix">Inverse of element's world matrix.</param> /// <param name="width">Width of UI element in world units.</param> /// <param name="height">Height of UI element in world units.</param> /// <param name="useRtCoords">Assumes rendering to a rendertarget rather than the backbuffer.</param> /// <returns>UV coord of mouse hit. Should be in [0, 1][0, 1] range. Outside of this implies a miss.</returns> public static Vector2 GetHitUV(Vector2 touchPosition, Camera camera, ref Matrix invWorldMatrix, float width, float height, bool useRtCoords) { Vector2 adjustedTouchPosition = touchPosition; if (useRtCoords) { adjustedTouchPosition = ScreenWarp.ScreenToRT(adjustedTouchPosition); } // Get 3D direction for mouse position. Vector3 touchDir = camera.ScreenToWorldCoords(adjustedTouchPosition); // Transform mouse ray into local space. Vector3 position = Vector3.Transform(camera.ActualFrom, invWorldMatrix); Vector3 direction = Vector3.TransformNormal(touchDir, invWorldMatrix); // Project to Z==0 plane, calc hit in local units (origin in center). float dist = -position.Z / direction.Z; Vector3 hit = position + direction * dist; Target = hit - invWorldMatrix.Translation; Vector2 hitUV = new Vector2(hit.X / width + 0.5f, -hit.Y / height + 0.5f); return(hitUV); } // end of GetHitUV
/// <summary> /// Gets the mouse position but transformed into current rendertarget coordinates. /// Note: This requires that ScreenWarp.FitRtToScreen() has been called with the /// correct RT size. /// </summary> /// <returns></returns> public static Vector2 GetMouseInRtCoords() { Vector2 mousePosition = new Vector2(MouseInput.Position.X, MouseInput.Position.Y); mousePosition = ScreenWarp.ScreenToRT(mousePosition); return(mousePosition); } // end of GetMouseInRtCoords()
/// <summary> /// Returns it in world coords of ray through touch pixel. /// </summary> /// <param name=param name="touchPosition">Position to test against</param> /// <param name="camera">UiCamera (orthographic)</param> /// <param name="invWorldMatrix">Inverse of object's world matrix.</param> /// <param name="useRtCoords">Adjust hit for rendering to a render target?</param> /// <returns></returns> public static Vector2 GetHitOrtho(Vector2 touchPosition, UiCamera camera, ref Matrix invWorldMatrix, bool useRtCoords) { Vector2 adjustedTouchPosition = touchPosition; if (useRtCoords) { adjustedTouchPosition = ScreenWarp.ScreenToRT(adjustedTouchPosition); } Vector2 hit = Vector2.Zero; // Convert from pixels to world units. hit.X = adjustedTouchPosition.X * camera.Width / camera.Resolution.X; hit.Y = adjustedTouchPosition.Y * camera.Height / camera.Resolution.Y; // Put origin at center. hit.X -= camera.Width / 2.0f; hit.Y -= camera.Height / 2.0f; // Flip vertical axis. hit.Y = -hit.Y; Vector3 actualFrom = camera.ActualFrom; Vector3 actualAt = camera.ActualAt; // Apply object and camera translation hit.X += invWorldMatrix.Translation.X + actualAt.X + camera.Offset.X; hit.Y += invWorldMatrix.Translation.Y + actualAt.Y + camera.Offset.Y; // Adjust if camera not going along Z axis. hit.X *= (float)Math.Cos(Math.Atan(camera.ViewDir.X / camera.ViewDir.Z)); hit.Y *= (float)Math.Cos(Math.Atan(camera.ViewDir.Y / camera.ViewDir.Z)); // Need to adjust if object is not at z==0. if (invWorldMatrix.Translation.Z != 0) { float fraction = invWorldMatrix.Translation.Z / (actualFrom.Z - actualAt.Z); hit.X -= (actualFrom.X - actualAt.X) * fraction; hit.Y -= (actualFrom.Y - actualAt.Y) * fraction; } return(hit); } // end of GetHitOrtho()