Berechnung Block / Gesicht Kamera / Cursor hat Fokus auf 3D-Block Welt

8

Ich habe mir selbst 3D-Programmierung mit einem Minecraft-Klon-Spiel beigebracht. Ich habe eine unendliche Karte, geladen in Blöcken von 16x16x64 Blöcken.

Wenn der Spieler (die Kamera) herumläuft, zeigt die Mitte der Kamera (der Spielcursor) auf einen Block. Ich versuche herauszufinden, auf welchen Block der Benutzer zeigt.

Ich habe eine Kamera mit einer 3D-Koordinate, Gieren, Pitch, damit ich weiß, wo der Benutzer hinschaut.

Ich habe versucht, Koordinaten zu finden, die sich auf einer "Linie" befinden, die von diesem Ausgangspunkt stammt, aber nicht berücksichtigt, wenn die Kamera auf die Kanten / Ecken eines Blocks zeigt, das System weiß es nicht.

Ich habe versucht, nach Beispielen online zu suchen, aber ich finde nichts Nützliches, ein paar Beispiele, aber sie sind extrem fehlerhaft und schlecht dokumentiert.

Wie kann ich richtig konvertieren, wo die Mitte der Kamera in welchen Block / welches Gesicht schaut sie?

    
helion3 30.11.2013, 19:29
quelle

3 Antworten

3
  

"Ich habe versucht, Koordinaten zu finden, die sich auf einer" Linie "befinden, die von diesem Ursprungspunkt aus gezeichnet wird, aber nicht berücksichtigt, wenn die Kamera auf die Kanten / Ecken eines Blocks zeigt, das System weiß es nicht. " .. "Wie kann ich richtig konvertieren, wo die Mitte der Kamera in welchen Block / welches Gesicht schaut sie?"

Die beiden üblichen Wege, mit denen OpenGL-Programme die Maus auswählen, sind Farbauswahl oder Ray-Casting . Es klingt, als ob du versuchst, durch dein Blockraster zu iterieren, um die Position zu bekommen, die etwas ungewöhnlich ist, oder etwas wie Ray Casting machen willst.

Ray Casting ist fertig from the camera -> through the mouse -> onto a plane on the screen -> map screen space to world space -> collide with scene

  

"Ich habe versucht, nach Beispielen online zu suchen, aber ich finde nichts Nützliches, ein paar Beispiele, aber sie sind extrem fehlerhaft und schlecht dokumentiert."

Hier finden Sie Links zu einigen Ray-Casting-Tutorials eins mit Mathematik und Diagrammen , eine mit einigen Codebeispielen , und noch ein .

Beachten Sie, dass Sie, wenn Sie ältere OpenGL-Tutorials finden, "Auswahlmodus" oder den "Namenstapel" erwähnen, was wirklich der Fall ist alt, benutze es nicht - OpenGL Wiki .

    
Jacqui Hawkins 07.12.2013 13:22
quelle
1

Es gibt einen Clark namens "CraftMania" vom Typ "Minecraft", der Open Source bei Ссылка

ist

Möglicherweise gibt es einige dokumentierte Informationen zur 3D-Kommissionierung.

    
JustBrenkman 09.12.2013 18:49
quelle
0

Zuerst eine Anmerkung zur Kamerahöhenfrage: Achten Sie darauf, die Kameraposition beizubehalten und in der ModelView-Matrix und nicht in der Projektionsmatrix zu zeigen. Die Projektionsmatrix sollte nur verwendet werden, um Ihr menschliches Auge relativ zu Ihrem realen Bildschirm (Kegelstumpf) zu kompensieren. "Zoomen" ist ein schwierigeres Thema.

Die Links der vorherigen Antwort zeigen, wie Sie den Sichtlinienvektor von der Kamera erhalten, indem Sie in den Modellbereich (Bildschirmmitte oder Fadenkreuz) schauen.

Rufen Sie diesen Sichtlinienvektor l an. Es sollte ein Einheitsspaltenvektor sein, der im selben Koordinatenrahmen wie Ihre Blöcke ausgedrückt wird. In Bezug auf Gieren (h für Kurs) und Pitch (p), wenn + y oben ist, und 0 Gieren hat -z vorwärts und x rechts, dann sind die (x, y, z) Komponenten von l: l = (cp * sh, sp, -cp * ch), wobei cp cos (Tonhöhe) ist, sh ist sin (yaw = heading), usw.

Wir wollen den nächsten Würfel vor der Kamera, der eine oder mehrere von einem Strahl der Kamera in Richtung von l durchbohrte Gesichter hat.

Bei jedem Schritt möchten Sie Würfel ausschließen, um den Durchsatz zu sparen. OpenGL hat eine Möglichkeit zu sagen, ob ein Grundelement (z. B. Dreieck) in den Tiefenpuffer schreibt (ist sichtbar). Wenn Sie möchten, können Sie zweimal rendern und die Cubes notieren, die im zweiten Durchlauf unter einer * - oder-gleich-Regel in den Tiefenpuffer schreiben, und nur diese Cubes berücksichtigen. Wenn nicht, können Sie das überspringen und alle Würfel betrachten.

Wenn Sie nicht bereits eine begrenzte Anzahl Ihrer 16x16x64-Chunks ausgewählt haben, können Sie große Chocolate-Chunks (zB 16 ^ 3) zuerst als Ganzes ablehnen, indem Sie die grobe Methode für einzelne Blöcke verwenden Akzeptanzschwelle hochskaliert durch zB 16.

Angenommen, ein Würfel ist 2x2x2 Einheiten (Ecken in der Mitte +/- 1 in x, y, z). Das Kameraauge befindet sich in Position e. Berechnen Sie für jeden Würfel mit Mittelpunkt bei c die Verschiebung vom Auge: d = c - e. Berechnen Sie den Abstand in Richtung von l: u = d Punkt l. (d. h. u = dx * lx + dy * ly + dz * lz.) Verwerfen Sie diesen Würfel, wenn Sie u & lt; -1,5 (Würfel ist vollständig hinter der Kamera). Berechnen Sie den senkrechten Verschiebungsvektor des Würfelzentrums aus dem Strahl: p = d - u * l.

Grobprüfung: Verwerfen Sie den Würfel, wenn die Summe der absoluten Werte der Komponenten von p & gt; 3. Dies ist ein schneller Check, der alle Würfel eliminiert, die sehr nahe an der Sichtlinie liegen.
Sortieren Sie alle verbleibenden Würfel nach dem kleinsten bis größten u Der erste von ihnen, der die folgende detaillierte Prüfung besteht, gewinnt.

Detaillierte Prüfung: Sie müssen zuerst einige Vorbereitungen treffen, die auf Ihrem Vektor basieren, bevor Sie irgendwelche Würfel verarbeiten: Benennen Sie die 8 Eckpunktnummern und Positionsvektoren wie folgt für alle Würfel:

%Vor%

Als nächstes wählen Sie die 4 oder 6 Ecken, die die 2-D konvexe Hülle einer präzisen Kollision bilden, wie vom Auge gesehen, basierend auf den Vorzeichen der x, y, z Komponenten von l:

%Vor%

Entartete Fälle, wenn zwei der Komponenten x, y oder z null sind:

%Vor%

Wählen Sie einmal einen der oben genannten 14 Rümpfe, basierend auf Ihrem Sichtlinienvektor. Führen Sie dann den folgenden detaillierten Test für jeden der verbleibenden sortimentsorientierten Würfel durch. Damit sich der Strahl innerhalb dieses Rumpfes befindet, dh wenn mindestens eine Seite des Würfels durchbohrt (oder zumindest gestreift) ist, muss der Strahl links von jedem durch nachfolgende Paare der Eckpunkte des Rumpfes spezifizierten Liniensegment liegen ( 6 oder 4 Checks), wenn wir um den Rumpf gegen den Uhrzeigersinn gehen. Dies ist das gleiche wie das Erfordernis, dass das Kreuzprodukt des Rumpfsegments mit der Verschiebung von jedem Ende dieses Segments zu dem Strahl eine negative oder Nullprojektion in den Sichtlinienvektor 1 aufweist: Nehmen Sie die Rumpfscheitelpunkte in Paaren von links nach rechts, und wickeln Sie die letzten Scheitelpunkte vom letzten zum ersten um, wobei der linke Scheitel mit "a" und der rechte mit "b" bezeichnet wird. ((b - a) cross (p - a)) dot l <= 0. (dasselbe "p" wie oben, p = d - u * l. p kann von oben gespeichert oder hier neu berechnet werden.) Der erste Würfel, der in der Reihenfolge vom nächsten zum weitesten entfernt ist, um alle 4 oder 6 Liniensegmente des Rumpfes zu haben, besteht bei diesem Test den Würfel vor dem Spieler. Die vier oder sechs (b - a) Vektoren können (einmal) vorberechnet werden. Sie können auch Sätze mit 4 Scheitelpunkten für die degenerierten Fälle aufstellen, in denen nur eine der Komponenten von l Null ist, aber das ist optional, anders als in den Fällen, in denen zwei Komponenten von l Null sind und Sie nur 4 Scheitelpunkte verwenden müssen / p>

Das ist alles auf Papier, nicht codiert oder getestet.

    
PaulQ 09.12.2013 08:25
quelle

Tags und Links