Game Engine Math

KWEngine, Teil 22: Raytracing-Kollisionen

1) Überprüfung, ob Instanzen bestimmter Klassen von einem Teststrahl getroffen werden

Wenn Sie z.B. überprüfen möchten, ob Instanzen bestimmter Klassen im Blickfeld eines anderen Objekts liegen, können Sie wie folgt vorgehen:

public class Player : GameObject
{
    public override void Act()
    {
        Vector3 rayStart     = this.Center;
        Vector3 rayDirection = this.LookAtVector; // muss normalisiert sein!
        List<RayIntersectionExt> results = HelperIntersection.RayTraceObjectsForViewVector(
            rayStart,                        // Strahl-Startposition
            rayDirection,                    // Strahlrichtung (normalisiert)
            0,                               // Strahllänge (0 = unendlich)
            true,                            // Ergebnisliste sortieren?
            this,                            // Verweis auf das Objekt, was prüft
            typeof(Enemy), typeof(Wall), ... // Kommaseparierte Aufzählung der zu überprüfenden Klassen
        );

        if(results.Count > 0)
        {
            // Erstes Objekt der Liste angucken, weil es
            // vom Strahl als erstes getroffen wurde:
            RayIntersectionExt raycollision = results[0];

            // Objekt, das getroffen wurde:
            GameObject objectHitByRay = raycollision.Object;

            // Distanz zwischen Strahl-Startposition und dem Treffer:
            float distanceToObject = raycollision.Distance;

            // Genaue Trefferposition:
            Vector3 target = raycollision.IntersectionPoint;

            // Ebenenvektor der Oberfläche, die vom Strahl getroffen wurde:
            Vector3 normal = raycollision.SurfaceNormal;
        }
    }
}

2) Schnellere (aber ungenaue) Überprüfung, ob Instanzen bestimmter Klassen getroffen werden

Wenn Sie keine punktgenaue Analyse benötigen, können Sie sich viele unnötige Berechnungen sparen, indem Sie folgende Variante verwenden:

public class Player : GameObject
{
    public override void Act()
    {
        Vector3 rayStart     = this.Center;
        Vector3 rayDirection = this.LookAtVector; // muss normalisiert sein!
        List<RayIntersection> results = HelperIntersection.RayTraceObjectsForViewVectorFast(
            rayStart,                        // Strahl-Startposition
            rayDirection,                    // Strahlrichtung (normalisiert)
            this,                            // Verweis auf das Objekt, was prüft
            0,                               // Strahllänge (0 = unendlich)
            true,                            // Ergebnisliste sortieren?
            typeof(Enemy), typeof(Wall), ... // Kommaseparierte Aufzählung der zu überprüfenden Klassen
        );

        if(results.Count > 0)
        {
            // Erstes Objekt der Liste angucken, weil es
            // vom Strahl als erstes getroffen wurde:
            RayIntersection raycollision = results[0];

            // Objekt, das getroffen wurde:
            GameObject objectHitByRay = raycollision.Object;

            // Ungefähre Distanz zwischen Strahl-Startposition und dem Treffer:
            float distanceToObject = raycollision.Distance;
        }
    }
}

Beitrag veröffentlicht

in

von

Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.