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

24.10.2003, 18:07

Terrain Höhe berechnen

Es ist wieder einmal das Terrain. Diesmal ist es die Höhe für die Objekte und Spieler. Vorweg, ich kann mein Terrain Skalieren, also alles z.B. mit 10 Multiplizieren. Das gibt ein hübsches großes Terrain ;D Allerdings läuft dann meine Kamera nicht mehr richtig über das Terrain. Die höhen werden zwar richtig ermittelt, aber er springt immer ein bissel in der Höhe. Das macht er aber nur dann wenn des Skalierungsvektor ungleich 1 ist.

So berechne ich die Höhendaten

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
float Terrain::GetHeightData(const float x,
                             const float y)
{
    unsigned int ix = int(x / m_fScale) + (m_uiWidth / 2);
    unsigned int iy = int(y / m_fScale) + (m_uiWidth / 2);

    if(ix >= m_uiWidth) ix = m_uiWidth - 2;
    else if(ix < 0)     ix = 0;
    if(iy >= m_uiDepth) iy = m_uiDepth - 2;
    else if(iy < 0)     iy = 0;

    gtl::vector3 v[3] = { m_pvHeightData[ix + (iy * m_uiWidth)],
                          m_pvHeightData[ix + 1 + (iy * m_uiWidth)],
                          m_pvHeightData[ix + 1 + ((iy + 1) * m_uiWidth)] };

    gtl::vector3 res;
    gtl::LineHitsPlane(gtl::vector3(x, m_uiHeight, y), gtl::vector3(x, 0.0f, y), gtl::CalculatePlane(v[0], v[1], v[2]), &res);
    return res.y;
}
m_pvHeightData ist ein zusätzliches Array wo ich die Koordinaten gespeichert hab die erzeugt werden. Die Funktion LineHitsPlane liefert mir einen Vektor in dem der Punkt gespeichert ist wo die Linie die Ebene schneidet. m_uiWidth, m_uiDepth ist die Breite und Tiefe des Terrains, und m_fScale ist der Skalierungsvektor.

So ich denke ich hab alles an wichtigen Informationen. Ach ja als Koordinaten werden die Weltkoordinaten geliefert. Daher muss ich die Koordinaten natürlich erst einmal umrechnen, da ja auch Negative Werte möglich sind und die mag ein Array ja gar nett.
Wichtig! Ich übernehme keinerlei Verantwortung für eventl. Datenverlust oder Schäden am Rechner ;D

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

2

24.10.2003, 18:26

Das Problem ist, dass Du mit einer Ebene rechnest. Diese Ebene erstellst Du anhand von 3 Punkten aus dem Terrain. Dabei vernachlässigst Du den vierten Punkt. Und es ist allgemein nicht möglich, eine Ebene durch 4 Punkte zu erstellen. Betrachtet man also ein einzelnes Viereck aus dem Terrain, so gibt es in den allermeisten Fällen keine Ebene, in der dieses Viereck liegt. Das geht nur bei Dreiecken. Du solltest lieber mit Interpolation arbeiten, wie ich das im TriBase-Terrain-Editor tue.

3

24.10.2003, 18:33

Aber ich benutze doch nur ein Dreieck für die erzeugung der Ebene.

gtl::LineHitsPlane();
Parameter 1 & 2: Anfangs- und Endpunkt der Linie
Parameter 3: Die Ebene
Parameter 4: Der Punkt an dem die Linie die Ebene schneidet.

gtl::CalculatePlane();
Parameter 1 bis 3: Bilden ein Komplettes Dreieck.
Wichtig! Ich übernehme keinerlei Verantwortung für eventl. Datenverlust oder Schäden am Rechner ;D

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

4

24.10.2003, 18:36

Ja, ein Dreieck! Es gibt aber zwei! Und beide würden unterschiedliche Ebenen liefern. Da ist der Ärger doch geradezu vorprogrammiert.
Nimm die bilineare Interpolation, und Du wirst damit keine Probleme mehr haben.

5

22.11.2003, 21:55

@David:

Zeig mal deine Interpolation, ich will mein Terrain später scalen, deswegen wäre das nich schlecht.

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

6

22.11.2003, 22:45

Ist eine einfache bilineare Interpolation... das wirst Du schon selbst schaffen!

7

22.11.2003, 23:21

aehm ja ..... so ein scheiss haben wir nicht in der Schule und ich kenne keine Seiten darüber von daher ....

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

8

23.11.2003, 09:05

"So einen Scheiss" hatten wir auch nicht in der Schule.
Du kannst doch eine normale lineare Interpolation zwischen zwei Zahlen: zwischen A und B mit dem Faktor f: A + (B - A) * f
Bei der bilinearen Interpolation:

Quellcode

1
2
3
4
(0,0) A     B (1,0)


(0,1) C     D (1,1)


Jetzt willst Du wissen, wie der Wert an der Stelle (x,y) ist.
Dann interpolierst Du zwischen A und B mit dem Faktor x, ebenso zwischen C und D. Und zwischen den beiden Ergebnissen interpolierst Du dann mit y.

Also ist der Wert an der Stelle (x,y):
(A + (B - A) * x) + ((C + (D - C) * x) - (A + (B - A) * x)) * y

Anders ausgedrückt:
x·(y·(A - B - C + D) - A + B) + y·(C - A) + A

9

23.11.2003, 14:25

oehm .. noe sowas hatten wir wirklich nie.

Ich hab vorher auch mal gegoogelt aber nix gefunden.

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

10

23.11.2003, 14:42

Wie gesagt, wir auch nicht, aber die Überlegung dahinter ist doch wirklich simpel, oder nicht?

Werbeanzeige