Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

07.07.2015, 17:30

Minecraft ähnliche Block Auswahl

Hallo,
ich programmiere gerade mit C++ + OpenGL 4.1 + SDL2 rum und habe mir damit ein kleines Programm geschrieben, was eine Minecraft ähnliche Welt darstellt.
Soweit funktioniert auch alles ganz gut jedoch komme ich einfach nicht dahinter, wie ich den nächsten Block aus Sicht des Spielers auswählen kann.
Mit anderen Worten, ich habe ein Objekt "Camera", dass die Attribute Position(X, Y, Z),Rotation(Pitch, Yaw, Roll) hat und ein anderes Objekt "World" was einfach ein 3D Array aus booleans beinhaltet, was angibt ob da ein Block ist oder nicht.
Wie kann ich jetzt herausfinden auf welchen nächsten Block der Spieler guckt ?
Ich habe schon gesucht und einige Beiträge übers "Ray Casting" gefunden, jedoch haben die mir nicht wirklich weiter geholfen.
Ich hoffe jemand kann mir da etwas helfen.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

2

07.07.2015, 18:01

Raycasting ist schon richtig. Was genau verstehst Du daran denn nicht? Vielleicht können wir da die Details klären, die Dich behindern.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

3

07.07.2015, 18:16

Das Problem ist, dass ich den "Ray" ja mit jedem Block prüfen müsste.
Und bei 1.000.000 Blöcken wäre das wohl keine gute Lösung.
Zudem kriege ich es nicht hin zu prüfen, ob der Strahl durch einen Block oder auch durch eine Plane verläuft.
Mit den Beiträgen und Formeln dazu konnte ich jetzt nicht soviel anfangen.

Also prinzipiell würde ich das so machen wollen:
1. Finde heraus welcher Block von dem "Ray" als erstes getroffen wurde.
2. Finde heraus welche Seite des getroffenen Blockes zuerst getroffen wurde.

Sylence

Community-Fossil

Beiträge: 1 663

Beruf: Softwareentwickler

  • Private Nachricht senden

4

07.07.2015, 18:18

Das Problem ist, dass ich den "Ray" ja mit jedem Block prüfen müsste.
Und bei 1.000.000 Blöcken wäre das wohl keine gute Lösung.


Da würde sich ein Octree oder etwas vergleichbares anbieten, um diese Zahl zu reduzieren.

5

07.07.2015, 18:29

Prinzipiell schon, aber das wäre jetzt zu zeitaufwändig.
Es muss doch eigentlich relativ einfach sein, da jeder Block gleich groß ist und nicht drehbar oder skalierbar ist usw...

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

6

07.07.2015, 18:37

Im Falle von Voxeln ähnlich zu Minecraft, hast du die Blöcke doch sogar schon wunderbar 3 dimensional als Grid geordnet. Ein regelmäßiges Gitter ist ja sogar in vieler Hinsicht noch besser zur Datensuche als ein Octtree. Du muss einfach bloß alle Blöcke die den Strahl berühren untersuchen. Alle anderen brauchst du nicht anfassen.

Für das verfolgen des Strahls bietet sich eine auf die 3. Dimension erweiterte Version des bekannten Bresenham Algorithmusanbieten.

birdfreeyahoo

Alter Hase

Beiträge: 756

Wohnort: Schorndorf

Beruf: Junior Software Engineer

  • Private Nachricht senden

7

07.07.2015, 19:01

Ist dein Ray nicht eine Gerade? Kannst du nicht über die Gerade vom Spieler aus in Blockgröße iterieren und Blocks über Abstand filtern und dann einen Kollisionscheck machen?

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

8

07.07.2015, 20:15

Das Problem ist, dass ich den "Ray" ja mit jedem Block prüfen müsste.
Nö. Stell Dir vor Du nimmst ein Blatt Karopapier (Matheblock). Nun malst Du etwa 50% der Kästchen aus, die anderen lässt Du leer. Nun malst Du eine Linie quer drüber. Die Linie berührt nur eine Hand voll Kästchen. Du brauchst jetzt nur die berührten zu prüfen und schauen, welche davon ausgemalt sind und welche nicht. Übertrag das Prinzip auf 3D und Du hast Deine Lösung.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

9

07.07.2015, 22:52

Ja dann muss man aber auch wissen, welche geschnitten werden wo wir schon zum nächsten Algorithmus kommen, der dann auch noch benötigt wird.
Es gibt mir vorrangig jetzt noch nicht mal darum welches "Face" deas Blocks angesehen wird sondern einfach nur welcher.

Also Ausgangssituation ist diese:



Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// Position
    float x = camera->getX();
    float y = camera->getY();
    float z = camera->getZ();

    // Rotation
    float rx = camera->getPitch();
    float ry = camera->getYaw();
    float rz = camera->getRoll();

    // Richtung
    float dx = sinf(ry);
    float dz = cosf(ry - M_PI);
    float dy = (sinf(rx));

    float length = sqrtf(dx * dx + dy * dy + dz * dz);

    // Richtung normalisieren
    dx /= length;
    dy /= length;
    dz /= length;

    //world->getHeight()
    //world->getDepth()
    //world->getWidth()
    //world->get(x, y, z) // Wenn Rückgabewert ungleich 0(unsigned int) ein Solider Block.

    //selected = true;
    //selectedX = (int)...
    //selectedY = (int)...
    //selectedZ = (int)...

Ziel ist es nun selectedX usw. auf die Koordinaten des angesehen Blocks zu setzen.
Ich komme einfach mit dem Problem nicht weiter :dash: .
Ich kann natürlich von niemanden erwarten, dass er mir das Programmiert, wäre aber Dankbar für ein paar Code Beispiele die vielleicht ein paar Teilprobleme lösen oder mir zumindest einen Ansatz der Lösungsmöglichkeit geben.

10

08.07.2015, 07:24

Googel mal nach Ray AABB Collision.

Und teile den Strahl in kurze Strecken und teste dann die Kollision zwischen der Strecke und den Blöcken, die zwischen Anfang und Ende der Strecke liegen.

Die Berechnung der Richtung des Strahls ist falsch. Du kannst einfach die Kameramatrix (inverse View Matrix, ohne Verschiebung, also nur die 3x3 Matrix, die sich auf den 3x3 linken oberen Elementen ergibt) dafür nutzen oder basierend auf der Rotation einfach eine Rotationsmatrix generieren und diese dann nutzen, um den Vektor zu transformieren. Oder du guckst dir die Umrechnung von Kugelkoordinaten in karthesische Koordinaten an, allerdings musst du hierbei beachten, dass die Reihenfolge der Rotation anders ist.

Hier ist mein Code für die Richtung der Kamera, ich bin mir aber nicht 100% sicher, ob der bei dir funktioniert, da er für ein linkshändiges Koordinatensystem mit x nach links, y nach oben und z nach hinten gedacht ist. Rein theoretisch müsste der aber für rechts- und linkshändige Koordinatensysteme gelten. Es sei denn, bei dir zeigt z nach oben, dann bin ich mir nicht sicher. Gilt auch nur, wenn die Reihenfolge der Rotation erst um die x-Achse und dann um die y-Achse stattfindet und die Blickrichtung bei 0 Grad in positive z-Richtung ist.

C-/C++-Quelltext

1
2
3
DOUBLE3 Camera_t::GetDirection(){
    return DOUBLE3(sin(Rotation.y)*cos(Rotation.x), -sin(Rotation.x), cos(Rotation.y)*cos(Rotation.x));
}
Cube Universe
Entdecke fremde Welten auf deiner epischen Reise durchs Universum.

Dieser Beitrag wurde bereits 7 mal editiert, zuletzt von »Magogan« (08.07.2015, 07:55)


Werbeanzeige