Esempio n. 1
0
        internal static bool IsMouseCursorInsideHitbox(GameObject g, ref Vector3 worldRay, ref Vector3 origin, MouseIntersectionPrecision precision)
        {
            bool    result;
            Vector3 intersection;

            result = GameObject.LinePlaneIntersection(
                out intersection,
                worldRay,
                origin,
                -worldRay,
                g.GetCenterPointForAllHitboxes()
                );

            if (result)
            {
                foreach (Hitbox hb in g.Hitboxes)
                {
                    if (IsPointInsideBox(ref intersection, hb))
                    {
                        return(true);
                    }
                }
                return(false);
            }
            else
            {
                return(false);
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Prüft, ob ein Strahl die Hitbox einer GameObject-Instanz trifft und gibt die genaue Position des Schnittpunkts an
        /// </summary>
        /// <param name="g">Zu prüfende GameObject-Instanz</param>
        /// <param name="origin">Ursprung des Strahls</param>
        /// <param name="worldRay">Richtung des Strahls (muss normalisiert sein)</param>
        /// <param name="intersectionPoint">Ergebnis der Prüfung (Position des Schnittpunkts)</param>
        /// <param name="precision">Präzision der Prüfung</param>
        /// <returns>true, wenn der Strahl das Objekt trifft</returns>
        public static bool GetRayIntersectionPointOnHitbox(GameObject g, Vector3 origin, Vector3 worldRay, out Vector3 intersectionPoint, MouseIntersectionPrecision precision = MouseIntersectionPrecision.Box)
        {
            bool    result;
            Vector3 intersection;

            for (int i = 0; i < g.Hitboxes.Count; i++)
            {
                Hitbox currentHitbox = g.Hitboxes[i];
                for (int j = 0; j < currentHitbox.mMesh.Faces.Length; j++)
                {
                    GeoMeshFace currentFace       = g.Hitboxes[i].mMesh.Faces[j];
                    Vector3     currentFaceNormal = currentFace.Flip ? -currentHitbox.Normals[currentFace.Normal] : currentHitbox.Normals[currentFace.Normal];
                    Vector3     pointOnFaceNormal = currentHitbox.GetPointOnFace(j, ref currentFaceNormal, currentFace.Flip);

                    result = GameObject.LinePlaneIntersection(out intersection, worldRay, origin, currentFaceNormal, pointOnFaceNormal);
                    if (result)
                    {
                        if (precision == MouseIntersectionPrecision.Box)
                        {
                            if (IsPointInsideBox(ref intersection, currentHitbox))
                            {
                                intersectionPoint = intersection;
                                return(true);
                            }
                        }
                        else
                        {
                            IsPointInsideSphere(ref intersection, g.GetCenterPointForAllHitboxes(), g._sceneDiameter);
                        }
                    }
                }
            }
            intersectionPoint = g.GetCenterPointForAllHitboxes();
            return(false);
        }
Esempio n. 3
0
        /// <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);
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Gibt die am nächsten liegende (vom Mauszeiger überlagerte) GameObject-Instanz zurück
        /// </summary>
        /// <typeparam name="T">Beliebige Unterklasse von GameObject</typeparam>
        /// <param name="ms">Aktueller Mausstatus</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">Präzision der Messung (Standard: Box für genauere Messung)</param>
        /// <returns>Die GameObject-Instanz, die der Kamera am nächsten ist</returns>
        public static T IsMouseCursorOnAny <T>(MouseState ms, int offsetX = 0, int offsetY = 0, MouseIntersectionPrecision precision = MouseIntersectionPrecision.Box) where T : GameObject
        {
            GameObject[] list = KWEngine.CurrentWorld._gameObjects.FindAll(go => go is T).ToArray();
            if (list.Length == 0)
            {
                return(null);
            }

            Vector3 origin;
            Vector2 mc       = HelperGeneral.GetNormalizedMouseCoords(ms.X + offsetX, ms.Y + offsetY);
            Vector3 worldRay = KWEngine.CurrentWindow.Get3DMouseCoords(mc.X, mc.Y);

            if (KWEngine.CurrentWorld != null && KWEngine.CurrentWorld.IsFirstPersonMode)
            {
                if (KWEngine.Projection == ProjectionType.Perspective)
                {
                    origin    = KWEngine.CurrentWorld.GetFirstPersonObject().Position;
                    origin.Y += KWEngine.CurrentWorld.GetFirstPersonObject().FPSEyeOffset;
                }
                else
                {
                    origin = HelperGeneral.GetRayOriginForOrthographicProjection(mc);
                }
            }
            else
            {
                if (KWEngine.Projection == ProjectionType.Perspective)
                {
                    origin = KWEngine.CurrentWorld.GetCameraPosition();
                }
                else
                {
                    origin = HelperGeneral.GetRayOriginForOrthographicProjection(mc);
                }
            }
            float minDistance = float.MaxValue;
            int   minIndex    = -1;

            for (int i = 0; i < list.Length; i++)
            {
                bool rayHitGameObject = IsMouseCursorInsideHitbox(list[i], ref worldRay, ref origin, precision);
                if (rayHitGameObject)
                {
                    float currentDistance = (origin - list[i].GetCenterPointForAllHitboxes()).LengthSquared;
                    if (currentDistance < minDistance)
                    {
                        minDistance = currentDistance;
                        minIndex    = i;
                    }
                }
            }
            if (minIndex >= 0)
            {
                return(list[minIndex] as T);
            }
            return(null);
        }