internal static Vector3 GetRayOriginForOrthographicProjection(Vector2 normalizedMouseCoords) { float aspectRatio = (float)GLWindow.CurrentWindow.Width / (float)GLWindow.CurrentWindow.Height; float xOffset = (2.0f * normalizedMouseCoords.X / (float)GLWindow.CurrentWindow.Width - 1) * (KWEngine.CurrentWorld.FOV / 2 * aspectRatio); float yOffset = (-(2.0f * normalizedMouseCoords.Y / (float)GLWindow.CurrentWindow.Height - 1)) * (KWEngine.CurrentWorld.FOV / 2); Vector3 lookAt; Vector3 position; if (KWEngine.CurrentWorld.IsFirstPersonMode && KWEngine.CurrentWorld.GetFirstPersonObject() != null) { position = KWEngine.CurrentWorld.GetFirstPersonObject().Position + KWEngine.WorldUp * KWEngine.CurrentWorld.GetFirstPersonObject().FPSEyeOffset; lookAt = HelperCamera.GetLookAtVector(); } else { position = KWEngine.CurrentWorld.GetCameraPosition(); lookAt = KWEngine.CurrentWorld.GetCameraLookAtVector(); } Vector3 cameraRight = Vector3.NormalizeFast(Vector3.Cross(lookAt, KWEngine.WorldUp)); Vector3 cameraUp = Vector3.NormalizeFast(Vector3.Cross(cameraRight, lookAt)); Vector3 rayOrigin = position + cameraRight * xOffset + cameraUp * yOffset; return(rayOrigin); }
/// <summary> /// Erfragt, ob der Mauszeiger (näherungsweise) auf dem Objekt liegt /// </summary> /// <param name="g">Zu untersuchendes GameObject</param> /// <param name="ms">Mausinformationen</param> /// <param name="offsetX">optionale Verschiebung des Cursors auf der X-Achse in Pixeln (Standard: 0)</param> /// <param name="offsetY">optionale Verschiebung des Cursors auf der X-Achse in Pixeln (Standard: 0)</param> /// <param name="precision">Genauigkeit der Prüfung (Standard: Box für eine genauere Prüfung)</param> /// <returns>true, wenn der Mauszeiger auf dem Objekt liegt</returns> public static bool IsMouseCursorInsideHitbox(GameObject g, MouseState ms, int offsetX = 0, int offsetY = 0, MouseIntersectionPrecision precision = MouseIntersectionPrecision.Box) { Vector2 mc = HelperGeneral.GetNormalizedMouseCoords(ms.X + offsetX, ms.Y + offsetY); Vector3 worldRay = KWEngine.CurrentWindow.Get3DMouseCoords(mc.X, mc.Y); Vector3 normal; bool result; Vector3 intersection; if (KWEngine.CurrentWindow.CurrentWorld != null && KWEngine.CurrentWindow.CurrentWorld.IsFirstPersonMode) { normal = HelperCamera.GetLookAtVector(); normal.Y += 0.000001f; normal.Z += 0.000001f; if (KWEngine.Projection == ProjectionType.Perspective) { Vector3 fpPos = KWEngine.CurrentWindow.CurrentWorld.GetFirstPersonObject().Position; fpPos.Y += KWEngine.CurrentWindow.CurrentWorld.GetFirstPersonObject().FPSEyeOffset; result = GameObject.LinePlaneIntersection(out intersection, worldRay, fpPos, normal, g.GetCenterPointForAllHitboxes()); } else { Vector3 fpPos = HelperGeneral.GetRayOriginForOrthographicProjection(mc); result = GameObject.LinePlaneIntersection(out intersection, worldRay, fpPos, normal, g.GetCenterPointForAllHitboxes()); } } else { normal = -KWEngine.CurrentWindow.CurrentWorld.GetCameraLookAtVector(); normal.Y += 0.000001f; normal.Z += 0.000001f; if (KWEngine.Projection == ProjectionType.Perspective) { result = GameObject.LinePlaneIntersection(out intersection, worldRay, KWEngine.CurrentWindow.CurrentWorld.GetCameraPosition(), normal, g.GetCenterPointForAllHitboxes()); } else { Vector3 rayOrigin = HelperGeneral.GetRayOriginForOrthographicProjection(mc); result = GameObject.LinePlaneIntersection(out intersection, worldRay, rayOrigin, normal, g.GetCenterPointForAllHitboxes()); } } if (result) { foreach (Hitbox hb in g.Hitboxes) { if (precision == MouseIntersectionPrecision.Box) { if (IsPointInsideBox(ref intersection, hb)) { return(true); } } else { if (IsPointInsideSphere(ref intersection, hb.GetCenter(), hb.DiameterAveraged)) { return(true); } } } return(false); } else { return(false); } }