Kollision mit Map



  • Zur Heightmap:
    Du hast doch die Höhendaten. Wenn du das Objekt positionierst checkste einfach ob sich das Objekt im Feld der Heightmap befindet und falls ja, holst du dir die Y-Achse der Heightmap und übergibst sie an deine Transformation.

    Zum *.X-File:
    Das X-File ist zwar ASCII-Codiert, trotzdem empfehle ich dir ein binäres Format (3DS). Bei den binären Fileformaten brauchst du nicht auf whitespaces, tabs, zeilenumbruch etc. zu reagieren. Falls du trotzdem auf das X-File bestehst, such dir einen bei Google und versuche ihn zu verstehen 😉 .



  • Scorcher:
    Danke für den Hinweis, dass man meistens BSP-Maps dafür benutzt, ich werds mir mal anschaun und gucken ob ich es schaffe da was zu implementieren.
    Was "fertiges" möchte ich jedoch nicht benutzen, dafür hab ich die letzten Wochen nicht gearbeitet, ich möchte mir das alles möglichst detailliert aneignen und das geht am besten, wenn man von Anfang an möglichst alles selbst entwirft/implementiert. Is halt ne schlechte Angewohnheit von mir =).

    Kóyaánasqatsi:
    Ich erstelle meine Models/Maps mit "trueSpace", einem ziehmlich umfangreichen 3D-Modellierungsprogramm und speichere diese Models dann als *.x Dateien. Ich wüsste nicht wo ich da auf whitespaces, tabs, zeilenumbruch etc reagieren müsste, implementieren lassen sich die Grafiken auch so per LoadMeshFromX(...).

    Das Stichwort Heightmap hört sich jedoch sehr gut an^^
    Meine Fragen dazu:
    1. Hat ein *.x Model eine Heightmap oder muss ich die Selbst erstellen?
    2. Wenn es standardgemäß eine Heightmap gibt, wie greife ich darauf zu?

    Ich danke schonmal für die bisher schnellen Antworten 🙂



  • Ok, das DirectX von Haus aus einen X-Fileloader anbietet, wusste ich nicht. Ich dachte, du wolltest das File selber parsen.

    tharug schrieb:

    1. Hat ein *.x Model eine Heightmap oder muss ich die Selbst erstellen?

    Das ginge reintheoretisch zwar, doch Mesh-/Modelformate sind nicht dazu gedacht Höhendaten zu speichern. Heightmaps werden generell aus Texturen generiert. Meistens representieren die weissen bis schwarzen Farbwerte die Höhe. Google sollte dir aber auch hilfreiche Seiten ausspucken.

    tharug schrieb:

    2. Wenn es standardgemäß eine Heightmap gibt, wie greife ich darauf zu?

    Inwiefern? Ich sage jetzt einfach mal: Mit einem Filestream :p .



  • Also ich habe jetzt ca 40 Minuten nach "Meshes" "Heightmap" etc. gesucht und das einzige was ich finde sind solche Heightmaps, die du denke ich auch meinst (Bilder in denen Hell/Dunkel Höhenmaße sind).

    Ich benötige jedoch eine Methode eine X- und Z-Koordinate einzugeben um dann den dazugehörigen Y-Wert zu erhalten.

    Ich werde jetzt mal weiter nach BSP-Maps suchen und einem dazugehörigen Modellierungsprogramm. Mal schaun was sich da so ergibt.

    Inwiefern? Ich sage jetzt einfach mal: Mit einem Filestream :p .

    Ich will ja ned in dem File rumwuseln^^.
    Normal sollte dX schon selbst Klassen und methoden besitzen, um diese Files auszulesen, zu parsen etc.
    Es hätte ja sein können, dass ein *.x File auch gleichzeitig eine Heightmap erstellt,

    doch Mesh-/Modelformate sind nicht dazu gedacht Höhendaten zu speichern.

    aaaber der Gedanke wurde durch diese Aussage zerstört 🙂

    Danke 😃



  • tharug schrieb:

    Ich benötige jedoch eine Methode eine X- und Z-Koordinate einzugeben um dann den dazugehörigen Y-Wert zu erhalten.

    Du hast ja letztendlich ein Array mit den x, y und z-Koordinaten. Dieses Array kannst du dann nach den x und z-Werten durchsuchen und die y-Koordinaten zurückgeben. Sollte in etwa so gehen (Vorsicht, ungetestet!):

    float GetY(const std::vector<Vector3> &vecIndex, float &x, float &z)
    {
    	std::vector<Vector3>::iterator it(vecIndex.begin());
    
    	for(; it != vecIndex.end(); ++it)
    	{
    		if((*it->x == x) && (*it->z == z))
    			return *it->y;
    	}
    }
    

    tharug schrieb:

    Ich werde jetzt mal weiter nach BSP-Maps suchen und einem dazugehörigen Modellierungsprogramm. Mal schaun was sich da so ergibt.

    BSP (Half Life 1: IBSP, Half Life 2: VBSP) ist ein Mapformat, das von Valve für seine Spiele benutzt wird. Du kannst sie von daher mit dem "Valve Hammer Editor" erstellen. Jedoch solltest du wissen, dass die BSP-Mapformate für "richtige" Maps gedacht sind. Sprich Wände, Objekte etc. und nicht für Landschaften (Heightmaps). Außerdem wären beide Mapformate, meiner Meinung nach, für dich zu overkill.

    tharug schrieb:

    Ich will ja ned in dem File rumwuseln^^.
    Normal sollte dX schon selbst Klassen und methoden besitzen, um diese Files auszulesen, zu parsen etc.

    Naja, ich kenne mich mit DirectX nicht aus und weiß von daher nicht, ob Texturloader (für beispielsweise Bitmaps, JPEG, PNG, TARGA etc.) implementiert wurden. Falls ja, brauchst du nur ein Array mit den Farbwerten (r, g, b -> x, y, z) von der Textur um die Heightmap zu generieren. Allerdings sind das Laden der Textur und das generieren der Heightmap zwei verschiedene paar Schuhe und sollten nicht zusammengewürfelt werden.



  • Also ich hab das Gefühl, du verstehst nich so richtig, was mein Ziel ist^^

    Ich werd mal ein kleines Beispiel aufstellen, was leicht zu verstehen ist denke ich:

    Da in DirectX, sowie in [ich glaube] allen anderen 3D Programmiersprachen/Programmen alles in Dreiecken dargestellt wird setzen wir einfach mal ein Dreieck mit beliebiger Textur und Material in den Raum. Dieses Dreieck besteht aus 3 Ecken mit den Koordinaten:

    P1 = [0, 0, 0]
    P2 = [1, 0, 0]
    P3 = [1, 1, 1]

    Es hätte also eine gewisse Ebene, die aber nicht senkrecht zur Y-Achse ist (nicht gerade).

    Diese Ebene hat unendlich viele Höhen!

    Wenn ich nun zufällig auf dem Punkt P1 stehe, die X- und Z-Werte also genau 0 sind, dann funktioniert deine Methode einwandfrei, sie geht durch die Liste, die meine 3 Vektoren enthält, findet P1 und gibt mir Y = 0 zurück.
    Das gleiche mit P2 wo X=1 ist und Z = 0 Rückgabe ist Y = 0.

    Aber ich muss auch die Höhe bei X = 0.4 und Z = 0.1 wissen, dieser müsste ca Y = 0.1 betragen (überschlagen).

    Es reicht mir also nicht nur die einzelnen Höhen der Eckpunkte zu wissen, sondern ich benötige eine Methode, die mir für jeden beliebigen Punkt der Map die Höhe zurückgibt.

    Mein pers. Vorgehensweise (die ich mir mittlerweile hergeleitet habe, da ich nix passendes zu dem Thema finde °_° ) wäre nun:

    1. die einzelnen Eckpunkte in eine Liste zu schreiben (Ich glaube das geht indem ich mir den Vertexbuffer hole oder?)

    2. Eine Methode zu schreiben, in der ich herausfinde zwischen welchen drei Punkten sich eine gewisse [X, Z] Koordinate befindet.

    3. Eine weitere Methode zu schreiben, die mir sagt, wie hoch dieses Dreieck an der gewissen [x, Z] Koordinate ist (Da überlege ich gerade wie das funktioniert^^)

    Und sollte es davon eine einfachere Variante Seitens DirectX geben, dann brauch ich diese Variante^^

    Danke



  • Das geht bestimmt performanter, aber ein paar Vektoren wirst du schon jonglieren müssen...:

    float heightmap::get_height_at(float x, float z)
    {
      if (x<0 or z<0 or x>width or z>height) return 0.0; // außerhalb der map
    
      // Die Breite w in Punkten (=> +1)
      int w= width;
    
      // v1,v2,v3:
      vektor3d v1(static_cast<float>(std::floor(x)),
                  data_field[ static_cast<int>( std::floor(x)+std::floor(z)*w ) ],
                  static_cast<float>(std::floor(z)));
      vektor3d v2(static_cast<float>(std::ceil(x)),
                  data_field[ static_cast<int>( std::ceil(x)+std::ceil(z)*w ) ],
                  static_cast<float>(std::ceil(z)));
      vektor3d v3; // Noch leer, nun if-Abfrage:
    
      // gegeben: a,b,c,d:
      // gesucht: Eines der beiden Dreiecke: Das, in dem der Punkt (x|z) liegt!
      // 
      // d---c
      // |ol/|
      // |/ur|
      // a---b
      if ( std::fabs(x-std::floor(x)) < std::fabs(z-std::floor(z)) ) // oben-links
      {
        v3.x= static_cast<float>(std::floor(x));
        v3.y= data_field[ static_cast<int>( std::floor(x)+std::ceil(z)*w ) ];
        v3.z= static_cast<float>(std::ceil(z));
      }
      else                                               // unten-rechts
      {
        v3.x= static_cast<float>(std::ceil(x));
        v3.y= data_field[ static_cast<int>( std::ceil(x)+std::floor(z)*w ) ];
        v3.z= static_cast<float>(std::floor(z));
      }
    
      //Nun kann die Höhe mithilfe der drei Vektoren berechnet werden:
    
      vektor3d l1= vektor3d::normalize(vektor3d(v1.x - x, 0, v1.z - z));
    
    	vektor3d l2= vektor3d::normalize(vektor3d(v2.x - x, 0, v2.z - z));
    
    	vektor3d l3= vektor3d::normalize(vektor3d(v3.x - x, 0, v3.z - z));
    
    	float a= acosf(vektor3d::dot_product(l1, l2)),
            b= acosf(vektor3d::dot_product(l2, l3)),
            c= acosf(vektor3d::dot_product(l1, l3)),
            d;
    
    	const vektor3d norm= vektor3d::cross_product(
             vektor3d(v2.x-v1.x,v2.y-v1.y,v2.z-v1.z),
    
    		     vektor3d(v3.x-v1.x,v3.y-v1.y,v3.z-v1.z)
            );
    
    	a=norm.x;
    
    	b=norm.y;
    
    	c=norm.z;
    
    	d=-( a*v1.x + b*v1.y + c*v1.z );
    
    	return ((a*x+c*z+d) / (-b))*scale;// Die Höhe(y) an der Stelle (x| |z) z-geben
    }
    


  • @tharug: Du schiesst einfach einen senkrechten Strahl, und suchst alle Schnittpunkte mit Dreiecken, damit hast du dann die Hoehe.

    Kóyaánasqatsi schrieb:

    Ok, das DirectX von Haus aus einen X-Fileloader anbietet, wusste ich nicht. Ich dachte, du wolltest das File selber parsen.

    Wie mir scheint, weisst du auch nicht, das man x-Files in einem binaeren Modus speichern kann. f'`8k

    Autocogito

    Gruß, TGGC (Was Gamestar sagt...)



  • TGGC schrieb:

    Kóyaánasqatsi schrieb:

    Ok, das DirectX von Haus aus einen X-Fileloader anbietet, wusste ich nicht. Ich dachte, du wolltest das File selber parsen.

    Wie mir scheint, weisst du auch nicht, das man x-Files in einem binaeren Modus speichern kann. f'`8k

    Nein. Und wie mir scheint, weißt du auch nicht, das man weiß mit einem ß schreibt.



  • Kóyaánasqatsi schrieb:

    TGGC schrieb:

    Kóyaánasqatsi schrieb:

    Ok, das DirectX von Haus aus einen X-Fileloader anbietet, wusste ich nicht. Ich dachte, du wolltest das File selber parsen.

    Wie mir scheint, weisst du auch nicht, das man x-Files in einem binaeren Modus speichern kann. f'`8k

    Nein. Und wie mir scheint, weißt du auch nicht, das man weiß mit einem ß schreibt.

    was soll das jetzt werden? Schonmal auf die Idee gekommen, dass er an einer Tastatur ohne ß hocken könnte?


  • Mod

    bleibt beim thema.


Anmelden zum Antworten