Raypick funktioniert nur bedingt.

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Antworten
Andy90
Beiträge: 67
Registriert: 08.10.2023, 13:02

Raypick funktioniert nur bedingt.

Beitrag von Andy90 »

Hallo :) ich habe mich gestern daran gemacht, eine Funktion zu erstellen, mit der ich Entitys mi der Maus picken kann. Ich habe gesehen das es dafür mehrere Möglichkeiten gibt und dachte, dass sich ein Raycast ganz gut eignen könnte. Jedoch habe ich das Problem das das ganze nicht so richtig funktionieren mag.

Mit dieser Klasse erstelle ich den Raycast

Code: Alles auswählen

public class MouseRay
{
    public vec3 CurrentRay { get; set; }
    public mat4 ProjectionMatrix { get; set; }
    public mat4 ViewMatrix { get; set; }
    public Camera Camera { get; set; }


    public MouseRay(Camera camera)
    {
        this.Camera = camera;
    }

    private void GenerateMatrix(Camera camera)
    {
        vec3 cameraPosition = camera.Location.ToGlmVec3();
        Vec3 cameraFront = Utils.CalculateCameraFront2(camera);

        ProjectionMatrix = mat4.Perspective(Utils.ToRadians(45.0f), camera.Size.X / camera.Size.Y, camera.Near, camera.Far);
        ViewMatrix = mat4.LookAt(cameraPosition, cameraPosition + cameraFront.ToGlmVec3(), new vec3(0.0f, 1.0f, 0.0f));
    }

    public Vec3 RayCast(float mouseX, float mouseY, Viewport viewport)
    {
        this.GenerateMatrix(this.Camera);
        var ndc = GetNDC(mouseX, mouseY, viewport);
        var clip = new vec4(ndc.x, ndc.y, -1f, 1f);
        var eye = GetEyeCords(clip);
        vec3 ray_wor = GetWorldCords(eye);
        return new Vec3(ray_wor);
    }

    private vec3 GetWorldCords(vec4 eye)
    {
        vec3 rey_wor = (ViewMatrix.Inverse * eye).xyz;
        return rey_wor.Normalized;
    }

    public vec4 GetEyeCords(vec4 clip)
    {
        vec4 ray_eye = ProjectionMatrix.Inverse * clip;
        return new vec4(ray_eye.x, ray_eye.y, -1f, 0f);
    }

    public vec2 GetNDC(float x, float y, Viewport viewport) 
    {
        float ndcX = (2.0f * x) / viewport.Width - 1.0f;
        float ndcY = 1.0f - (2.0f * y) / viewport.Height;
        return new vec2(ndcX, -ndcY);
    }
}
und dann Prüfe ich hiermit ob es zu einer Intersection zwischen cast und aabb eines entitys kommt

Code: Alles auswählen

                start = this.Camera.Location;
                end = MouseRay.RayCast(e.X, e.Y, Viewport);

                foreach (var layer in this.Scene.Layer)
                {
                    foreach (var entity in layer.Elements)
                    {
                        StaticMeshBehavior staticMeshBehavior = (StaticMeshBehavior)entity.GetBehavior<StaticMeshBehavior>();
                        if (staticMeshBehavior != null)
                        {
                            Genesis.Physics.Aabb aabb = Genesis.Physics.Aabb.FromBulletRigidBody(staticMeshBehavior.RigidBody);
                            if (Genesis.Physics.Aabb.IntersectRay(start, end, aabb.Min, aabb.Max))
                            {
                                MessageBox.Show("contact");
                            }
                        }
                    }
                }
Es ist nun so, dass der cast nicht wirklich in Richtung der Maus verläuft und ich die Message box für den kontakt auch erhalte wenn ich nicht auf das Entity klicke.

Beste grüße

Andy
Mirror
Establishment
Beiträge: 269
Registriert: 25.08.2019, 05:00
Alter Benutzername: gdsWizard
Kontaktdaten:

Re: Raypick funktioniert nur bedingt.

Beitrag von Mirror »

Du schreibst gar nicht was für ein Mesh es ist. Handelt es sich denn um eine Box und ist sie auch wirklich Achsenausgerichtet ? Beides sind Gründe warum Du nicht das gewünschte Ergebnis erhältst. Wenn Du eine Box verwendest, musst Du eine Oriented-Bounding-Box verwenden und den Ray in den Modelview umrechnen.
Hat den StormWizard 1.0 und 2.0 verbrochen. http://www.mirrorcad.com
Andy90
Beiträge: 67
Registriert: 08.10.2023, 13:02

Re: Raypick funktioniert nur bedingt.

Beitrag von Andy90 »

Hallo, danek für deine Antwort. Die Aabb erhalte ich von bullet selbst. Ich debuge den Ray und da ist schon zu sehen das die linie nicht zur Maus position geht.
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4264
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: Raypick funktioniert nur bedingt.

Beitrag von Chromanoid »

Wenn Du Bullet benutzt, kannst Du doch direkt einen RayTest ausführen und musst nicht selbst alle Entities durchgehen?
Andy90
Beiträge: 67
Registriert: 08.10.2023, 13:02

Re: Raypick funktioniert nur bedingt.

Beitrag von Andy90 »

Ich nutze direkt bullet sondern ein wrapper namens Bulletsharp. Ich habe noch nicht wirklich rausgefunden wie ich einen RayTest mit bullet machen kann. Ich habe auch keine game loop, da es für ein editor ist und dieser nur rendert wenn ein neues Frame benötigt wird.

Habe eine RayTest funktion gefunden. Allerdings brauche ich dafür auch die Maus Position in world coordinaten.
Andy90
Beiträge: 67
Registriert: 08.10.2023, 13:02

Re: Raypick funktioniert nur bedingt.

Beitrag von Andy90 »

Ich glaube einfach meine Maus Koordinaten sind zu gering. Mein Model ist auf 0,0,0 und hat eine größe von 1,1,1. Meine Maus ist, mit einer TopDown view am oberen Linken Bildschirmrand an der position (0,32, -0.78, 0.533) und in der Mitte wie es sein soll auf (0, -1, 0). Demnach ist ja der Mausbereich viel zu gering oder irre ich mich da?
Benutzeravatar
Schrompf
Moderator
Beiträge: 4891
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas
Wohnort: Dresden
Kontaktdaten:

Re: Raypick funktioniert nur bedingt.

Beitrag von Schrompf »

Kommt auf den Öffnungswinkel an, ob das korrekt ist, aber die Zahlen sehen erstmal einfach danach aus, als wäre Dein Vektor normiert. Und das würde ich ja auch so erwarten.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4264
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: Raypick funktioniert nur bedingt.

Beitrag von Chromanoid »

Andy90
Beiträge: 67
Registriert: 08.10.2023, 13:02

Re: Raypick funktioniert nur bedingt.

Beitrag von Andy90 »

Ja genau, das mache ich hier mit dem Normalisieren

Code: Alles auswählen

        private vec3 GetWorldCords(vec4 eye)
        {
            vec3 rey_wor = (ViewMatrix.Inverse * eye).xyz;
            return rey_wor.Normalized;
        }
Das Beispiel habe ich gesehen. Habe das auch schon so implementiert. Allerdings ist es so, was ich festgestellt habe, dass wenn ich mein Model auf die Position die ich erhalte (von meinem Raycast) es überhaupt nicht diesen Welt Koordinaten entspricht.
Andy90
Beiträge: 67
Registriert: 08.10.2023, 13:02

Re: Raypick funktioniert nur bedingt.

Beitrag von Andy90 »

habe anhand von dem Beispiel von Chromanoid folgendes gefunden was etwas besser funktioniert aber noch nicht ganz richtig. https://github.com/AndresTraks/BulletSh ... mo.cs#L311 Ich nehme an, dass es sich bei Freelook um die Kamera handelt und bei Freelook.target um den Mittelpunkt der Kamera.
Andy90
Beiträge: 67
Registriert: 08.10.2023, 13:02

Re: Raypick funktioniert nur bedingt.

Beitrag von Andy90 »

Ich nehme an, ich habe mein fehler gefunden. Die Koordinaten des Rays sind auch im Normal Device Space. Nun ist die frage wie wandele ich diese um.
Andy90
Beiträge: 67
Registriert: 08.10.2023, 13:02

Re: Raypick funktioniert nur bedingt.

Beitrag von Andy90 »

Sorry für die vielen Nachrichten, ich denke ich hab es gelöst. Wie @Chromanoid vorgeschlagen hat mit bullet selbst. https://www.opengl-tutorial.org/miscell ... s-library/ hat mir auch sehr geholfen. Werde morgen noch den code des RayCasters posten, so dass andere was davon haben, bei selben Problemmen.

----------------------
Edit: Hier ist die klasse von dem Raycaster https://github.com/Andy16823/GFX/blob/m ... ouseRay.cs
Antworten