Ejemplo n.º 1
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);
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Prüft, ob sich ein Punkt innerhalb der Hitbox einer GameObject-Instanz befindet
 /// </summary>
 /// <param name="point">Zu prüfender Punkt in der Welt</param>
 /// <param name="g">GameObject-Instanz für die die Prüfung durchgeführt werden soll</param>
 /// <returns>true, wenn sich der Punkt innerhalb der Hitbox befindet</returns>
 public static bool IsPointInsideGameObject(Vector3 point, GameObject g)
 {
     foreach (Hitbox h in g.Hitboxes)
     {
         bool isInsideCurrentHitbox = true;
         for (int boxFaceIndex = 0; boxFaceIndex < h.mMesh.Faces.Length; boxFaceIndex++)
         {
             GeoMeshFace boxFace      = h.mMesh.Faces[boxFaceIndex];
             Vector3     vertexOnFace = h.Vertices[boxFace.Vertices[0]];
             Vector3     boxNormal    = boxFace.Flip ? h.Normals[boxFace.Normal] : -h.Normals[boxFace.Normal]; // really flip this way?
             bool        tmpResult    = IsInFrontOfPlane(ref point, ref boxNormal, ref vertexOnFace);
             if (tmpResult == false)
             {
                 isInsideCurrentHitbox = false;
                 break;
             }
         }
         if (isInsideCurrentHitbox)
         {
             return(true);
         }
     }
     return(false);
 }
Ejemplo n.º 3
0
        internal static List <Vector3> ClipFaces(Hitbox caller, Hitbox collider)
        {
            List <Vector3> callerVertices          = new List <Vector3>(caller.mVertices);
            List <Vector3> collisionVolumeVertices = new List <Vector3>();

            // Clip caller against collider faces:
            for (int colliderFaceIndex = 0; colliderFaceIndex < collider.mMesh.Faces.Length; colliderFaceIndex++)
            {
                GeoMeshFace colliderClippingFace       = collider.mMesh.Faces[colliderFaceIndex];
                Vector3     colliderClippingFaceVertex = collider.mVertices[colliderClippingFace.Vertices[0]];
                Vector3     colliderClippingFaceNormal = colliderClippingFace.Flip ? collider.mNormals[colliderClippingFace.Normal] : -collider.mNormals[colliderClippingFace.Normal];
                for (int callerVertexIndex = 0; callerVertexIndex < callerVertices.Count; callerVertexIndex++)
                {
                    Vector3 callerVertex1 = callerVertices[callerVertexIndex];
                    Vector3 callerVertex2 = callerVertices[(callerVertexIndex + 1) % callerVertices.Count];
                    Vector3 lineDirection = Vector3.NormalizeFast(callerVertex2 - callerVertex1);

                    bool callerVertex1InsideRegion = HelperIntersection.IsInFrontOfPlane(ref callerVertex1, ref colliderClippingFaceNormal, ref colliderClippingFaceVertex);
                    bool callerVertex2InsideRegion = HelperIntersection.IsInFrontOfPlane(ref callerVertex2, ref colliderClippingFaceNormal, ref colliderClippingFaceVertex);

                    if (callerVertex1InsideRegion)
                    {
                        if (callerVertex2InsideRegion)
                        {
                            if (!collisionVolumeVertices.Contains(callerVertex2))
                            {
                                collisionVolumeVertices.Add(callerVertex2);
                            }
                        }
                        else
                        {
                            Vector3?clippedVertex = ClipLineToPlane(ref callerVertex2, ref lineDirection, ref colliderClippingFaceVertex, ref colliderClippingFaceNormal);
                            if (clippedVertex != null && !collisionVolumeVertices.Contains(clippedVertex.Value))
                            {
                                collisionVolumeVertices.Add(clippedVertex.Value);
                            }
                        }
                    }
                    else
                    {
                        if (callerVertex2InsideRegion)
                        {
                            Vector3?clippedVertex = ClipLineToPlane(ref callerVertex1, ref lineDirection, ref colliderClippingFaceVertex, ref colliderClippingFaceNormal);
                            if (clippedVertex != null && !collisionVolumeVertices.Contains(clippedVertex.Value))
                            {
                                collisionVolumeVertices.Add(clippedVertex.Value);
                            }
                            if (!collisionVolumeVertices.Contains(callerVertex2))
                            {
                                collisionVolumeVertices.Add(callerVertex2);
                            }
                        }
                    }
                }
                callerVertices.Clear();
                for (int i = 0; i < collisionVolumeVertices.Count; i++)
                {
                    callerVertices.Add(collisionVolumeVertices[i]);
                }
                collisionVolumeVertices.Clear();
            }
            return(callerVertices);
        }